Blender V4.3
detect_test.cc
Go to the documentation of this file.
1// Copyright (c) 2014 libmv authors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to
5// deal in the Software without restriction, including without limitation the
6// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7// sell copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19// IN THE SOFTWARE.
20
22
24#include "testing/testing.h"
25
26namespace libmv {
27
28namespace {
29
30void PreformSinglePointTest(const DetectOptions& options) {
31 // Prepare the image.
32 FloatImage image(15, 15);
33 image.fill(1.0);
34 image(7, 7) = 0.0;
35
36 // Run the detector.
37 vector<Feature> detected_features;
38 Detect(image, options, &detected_features);
39
40 // Check detected features matches our expectations.
41 EXPECT_EQ(1, detected_features.size());
42 if (detected_features.size() == 1) {
43 Feature& feature = detected_features[0];
44 EXPECT_EQ(7, feature.x);
45 EXPECT_EQ(7, feature.y);
46 }
47}
48
49#if 0
50void PreformCheckerBoardTest(const DetectOptions &options) {
51 // Prepare the image.
52 FloatImage image(30, 30);
53 for (int y = 0; y < image.Height(); ++y) {
54 for (int x = 0; x < image.Width(); ++x) {
55 image(y, x) = (x / 10 + y / 10) % 2 ? 1.0 : 0.0;
56 }
57 }
58
59 // Run the detector.
60 vector<Feature> detected_features;
61 Detect(image, options, &detected_features);
62
63 // Check detected features matches our expectations.
64
65 // We expect here only corners of a center square to be
66 // considered a feature points.
67 EXPECT_EQ(4, detected_features.size());
68
69 // We don't know which side of the corner detector will choose,
70 // so what we're checking here is that detected feature is from
71 // any side of the corner.
72 //
73 // This doesn't check whether there're multiple features which
74 // are placed on different sides of the same corner. The way we
75 // deal with this is requiring min_distance to be greater than 2px.
76 for (int i = 0; i < detected_features.size(); ++i) {
77 Feature &feature = detected_features[i];
78 int rounded_x = ((feature.x + 1) / 10) * 10,
79 rounded_y = ((feature.y + 1) / 10) * 10;
80 EXPECT_LE(1, std::abs(feature.x - rounded_x));
81 EXPECT_LE(1, std::abs(feature.y - rounded_y));
82 }
83}
84#endif
85
86void CheckExpectedFeatures(const vector<Feature>& detected_features,
87 const vector<Feature>& expected_features) {
88 EXPECT_EQ(expected_features.size(), detected_features.size());
89
90 // That's unsafe to iterate over vectors when their lengths
91 // doesn't match. And it doesn't make any sense actually since
92 // the test will already be considered failed here.
93 if (expected_features.size() != detected_features.size()) {
94 return;
95 }
96
97 for (int i = 0; i < expected_features.size(); ++i) {
98 const Feature& extected_feature = expected_features[i];
99 bool found = false;
100 for (int j = 0; j < detected_features.size(); ++j) {
101 const Feature& detected_feature = detected_features[j];
102 if (extected_feature.x == detected_feature.x &&
103 extected_feature.y == detected_feature.y) {
104 found = true;
105 break;
106 }
107 }
108 EXPECT_TRUE(found);
109 }
110}
111
112void PreformSingleTriangleTest(const DetectOptions& options) {
113 // Prepare the image.
114 FloatImage image(15, 21);
115 image.fill(1.0);
116
117 int vertex_x = 10, vertex_y = 5;
118 for (int i = 0; i < 6; ++i) {
119 int current_x = vertex_x - i, current_y = vertex_y + i;
120 for (int j = 0; j < i * 2 + 1; ++j, ++current_x) {
121 image(current_y, current_x) = 0.0;
122 }
123 }
124
125 // Run the detector.
126 vector<Feature> detected_features;
127 Detect(image, options, &detected_features);
128
129 // Check detected features matches our expectations.
130 vector<Feature> expected_features;
131 expected_features.push_back(Feature(6, 10));
132 expected_features.push_back(Feature(14, 10));
133 expected_features.push_back(Feature(10, 6));
134
135 CheckExpectedFeatures(detected_features, expected_features);
136}
137
138} // namespace
139
140#ifndef LIBMV_NO_FAST_DETECTOR
141TEST(Detect, FASTSinglePointTest) {
144 options.min_distance = 0;
145 options.fast_min_trackness = 1;
146
147 PreformSinglePointTest(options);
148}
149#endif // LIBMV_NO_FAST_DETECTOR
150
151#if 0
152// TODO(sergey): FAST doesn't detect checker board corners, but should it?
153TEST(Detect, FASTCheckerBoardTest) {
154 DetectOptions options;
156 options.min_distance = 0;
157 options.fast_min_trackness = 1;
158
159 PreformCheckerBoardTest(options);
160}
161#endif
162
163#if 0
164// TODO(sergey): FAST doesn't detect triangle corners!
165TEST(Detect, FASTSingleTriangleTest) {
166 DetectOptions options;
168 options.margin = 3;
169 options.min_distance = 0;
170 options.fast_min_trackness = 2;
171
172 PreformSingleTriangleTest(options);
173}
174#endif
175
176#if 0
177// TODO(sergey): This doesn't actually detect single point,
178// but should it or it's expected that Moravec wouldn't consider
179// single point as feature?
180//
181// Uncomment this or remove as soon as we know answer for the
182// question.
183TEST(Detect, MoravecSinglePointTest) {
184 DetectOptions options;
186 options.min_distance = 0;
187 options.moravec_max_count = 10;
188
189 PreformSinglePointTest(options);
190}
191
192// TODO(sergey): Moravec doesn't detect checker board corners, but should it?
193TEST(Detect, MoravecCheckerBoardTest) {
194 DetectOptions options;
196 options.min_distance = 0;
197 options.moravec_max_count = 10;
198
199 PreformCheckerBoardTest(options);
200}
201#endif
202
203TEST(Detect, HarrisSinglePointTest) {
206
207 // Set this to non-zero so image corners are not considered
208 // a feature points and avoid center point neighbors to be
209 // considered a features as well.
210 options.margin = 3;
211 options.min_distance = 3;
212
213 PreformSinglePointTest(options);
214}
215
216TEST(Detect, HarrisSingleTriangleTest) {
219
220 options.margin = 3;
221 options.min_distance = 2;
222 options.harris_threshold = 1e-3;
223
224 PreformSingleTriangleTest(options);
225}
226
227// TODO(sergey): Add tests for margin option.
228
229// TODO(sergey): Add tests for min_distance option.
230
231} // namespace libmv
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
CCL_NAMESPACE_BEGIN struct Options options
void Detect(const FloatImage &image, const DetectOptions &options, vector< Feature > *detected_features)
Definition detect.cc:347
TEST(PolynomialCameraIntrinsics2, ApplyOnFocalCenter)
Array3Df FloatImage