|
5 | 5 | #include "test_precomp.hpp"
|
6 | 6 | #include "test_invariance_utils.hpp"
|
7 | 7 |
|
8 |
| -namespace opencv_test { namespace { |
| 8 | +#include "test_descriptors_invariance.impl.hpp" |
9 | 9 |
|
10 |
| -#define SHOW_DEBUG_LOG 1 |
| 10 | +namespace opencv_test { namespace { |
11 | 11 |
|
12 |
| -typedef tuple<std::string, Ptr<FeatureDetector>, Ptr<DescriptorExtractor>, float> |
13 |
| - String_FeatureDetector_DescriptorExtractor_Float_t; |
14 | 12 | const static std::string IMAGE_TSUKUBA = "features2d/tsukuba.png";
|
15 | 13 | const static std::string IMAGE_BIKES = "detectors_descriptors_evaluation/images_datasets/bikes/img1.png";
|
16 |
| -#define Value(...) Values(String_FeatureDetector_DescriptorExtractor_Float_t(__VA_ARGS__)) |
17 |
| - |
18 |
| -static |
19 |
| -void rotateKeyPoints(const vector<KeyPoint>& src, const Mat& H, float angle, vector<KeyPoint>& dst) |
20 |
| -{ |
21 |
| - // suppose that H is rotation given from rotateImage() and angle has value passed to rotateImage() |
22 |
| - vector<Point2f> srcCenters, dstCenters; |
23 |
| - KeyPoint::convert(src, srcCenters); |
24 |
| - |
25 |
| - perspectiveTransform(srcCenters, dstCenters, H); |
26 |
| - |
27 |
| - dst = src; |
28 |
| - for(size_t i = 0; i < dst.size(); i++) |
29 |
| - { |
30 |
| - dst[i].pt = dstCenters[i]; |
31 |
| - float dstAngle = src[i].angle + angle; |
32 |
| - if(dstAngle >= 360.f) |
33 |
| - dstAngle -= 360.f; |
34 |
| - dst[i].angle = dstAngle; |
35 |
| - } |
36 |
| -} |
37 |
| - |
38 |
| -class DescriptorInvariance : public TestWithParam<String_FeatureDetector_DescriptorExtractor_Float_t> |
39 |
| -{ |
40 |
| -protected: |
41 |
| - virtual void SetUp() { |
42 |
| - // Read test data |
43 |
| - const std::string filename = cvtest::TS::ptr()->get_data_path() + get<0>(GetParam()); |
44 |
| - image0 = imread(filename); |
45 |
| - ASSERT_FALSE(image0.empty()) << "couldn't read input image"; |
46 |
| - |
47 |
| - featureDetector = get<1>(GetParam()); |
48 |
| - descriptorExtractor = get<2>(GetParam()); |
49 |
| - minInliersRatio = get<3>(GetParam()); |
50 |
| - } |
51 |
| - |
52 |
| - Ptr<FeatureDetector> featureDetector; |
53 |
| - Ptr<DescriptorExtractor> descriptorExtractor; |
54 |
| - float minInliersRatio; |
55 |
| - Mat image0; |
56 |
| -}; |
57 |
| - |
58 |
| -typedef DescriptorInvariance DescriptorScaleInvariance; |
59 |
| -typedef DescriptorInvariance DescriptorRotationInvariance; |
60 |
| - |
61 |
| -TEST_P(DescriptorRotationInvariance, rotation) |
62 |
| -{ |
63 |
| - Mat image1, mask1; |
64 |
| - const int borderSize = 16; |
65 |
| - Mat mask0(image0.size(), CV_8UC1, Scalar(0)); |
66 |
| - mask0(Rect(borderSize, borderSize, mask0.cols - 2*borderSize, mask0.rows - 2*borderSize)).setTo(Scalar(255)); |
67 |
| - |
68 |
| - vector<KeyPoint> keypoints0; |
69 |
| - Mat descriptors0; |
70 |
| - featureDetector->detect(image0, keypoints0, mask0); |
71 |
| - std::cout << "Keypoints: " << keypoints0.size() << std::endl; |
72 |
| - EXPECT_GE(keypoints0.size(), 15u); |
73 |
| - descriptorExtractor->compute(image0, keypoints0, descriptors0); |
74 |
| - |
75 |
| - BFMatcher bfmatcher(descriptorExtractor->defaultNorm()); |
76 |
| - |
77 |
| - const float minIntersectRatio = 0.5f; |
78 |
| - const int maxAngle = 360, angleStep = 15; |
79 |
| - for(int angle = 0; angle < maxAngle; angle += angleStep) |
80 |
| - { |
81 |
| - Mat H = rotateImage(image0, mask0, static_cast<float>(angle), image1, mask1); |
82 |
| - |
83 |
| - vector<KeyPoint> keypoints1; |
84 |
| - rotateKeyPoints(keypoints0, H, static_cast<float>(angle), keypoints1); |
85 |
| - Mat descriptors1; |
86 |
| - descriptorExtractor->compute(image1, keypoints1, descriptors1); |
87 |
| - |
88 |
| - vector<DMatch> descMatches; |
89 |
| - bfmatcher.match(descriptors0, descriptors1, descMatches); |
90 |
| - |
91 |
| - int descInliersCount = 0; |
92 |
| - for(size_t m = 0; m < descMatches.size(); m++) |
93 |
| - { |
94 |
| - const KeyPoint& transformed_p0 = keypoints1[descMatches[m].queryIdx]; |
95 |
| - const KeyPoint& p1 = keypoints1[descMatches[m].trainIdx]; |
96 |
| - if(calcIntersectRatio(transformed_p0.pt, 0.5f * transformed_p0.size, |
97 |
| - p1.pt, 0.5f * p1.size) >= minIntersectRatio) |
98 |
| - { |
99 |
| - descInliersCount++; |
100 |
| - } |
101 |
| - } |
102 |
| - |
103 |
| - float descInliersRatio = static_cast<float>(descInliersCount) / keypoints0.size(); |
104 |
| - EXPECT_GE(descInliersRatio, minInliersRatio); |
105 |
| -#if SHOW_DEBUG_LOG |
106 |
| - std::cout |
107 |
| - << "angle = " << angle |
108 |
| - << ", inliers = " << descInliersCount |
109 |
| - << ", descInliersRatio = " << static_cast<float>(descInliersCount) / keypoints0.size() |
110 |
| - << std::endl; |
111 |
| -#endif |
112 |
| - } |
113 |
| -} |
114 |
| - |
115 |
| - |
116 |
| -TEST_P(DescriptorScaleInvariance, scale) |
117 |
| -{ |
118 |
| - vector<KeyPoint> keypoints0; |
119 |
| - featureDetector->detect(image0, keypoints0); |
120 |
| - std::cout << "Keypoints: " << keypoints0.size() << std::endl; |
121 |
| - EXPECT_GE(keypoints0.size(), 15u); |
122 |
| - Mat descriptors0; |
123 |
| - descriptorExtractor->compute(image0, keypoints0, descriptors0); |
124 |
| - |
125 |
| - BFMatcher bfmatcher(descriptorExtractor->defaultNorm()); |
126 |
| - for(int scaleIdx = 1; scaleIdx <= 3; scaleIdx++) |
127 |
| - { |
128 |
| - float scale = 1.f + scaleIdx * 0.5f; |
129 |
| - |
130 |
| - Mat image1; |
131 |
| - resize(image0, image1, Size(), 1./scale, 1./scale, INTER_LINEAR_EXACT); |
132 |
| - |
133 |
| - vector<KeyPoint> keypoints1; |
134 |
| - scaleKeyPoints(keypoints0, keypoints1, 1.0f/scale); |
135 |
| - Mat descriptors1; |
136 |
| - descriptorExtractor->compute(image1, keypoints1, descriptors1); |
137 |
| - |
138 |
| - vector<DMatch> descMatches; |
139 |
| - bfmatcher.match(descriptors0, descriptors1, descMatches); |
140 |
| - |
141 |
| - const float minIntersectRatio = 0.5f; |
142 |
| - int descInliersCount = 0; |
143 |
| - for(size_t m = 0; m < descMatches.size(); m++) |
144 |
| - { |
145 |
| - const KeyPoint& transformed_p0 = keypoints0[descMatches[m].queryIdx]; |
146 |
| - const KeyPoint& p1 = keypoints0[descMatches[m].trainIdx]; |
147 |
| - if(calcIntersectRatio(transformed_p0.pt, 0.5f * transformed_p0.size, |
148 |
| - p1.pt, 0.5f * p1.size) >= minIntersectRatio) |
149 |
| - { |
150 |
| - descInliersCount++; |
151 |
| - } |
152 |
| - } |
153 |
| - |
154 |
| - float descInliersRatio = static_cast<float>(descInliersCount) / keypoints0.size(); |
155 |
| - EXPECT_GE(descInliersRatio, minInliersRatio); |
156 |
| -#if SHOW_DEBUG_LOG |
157 |
| - std::cout |
158 |
| - << "scale = " << scale |
159 |
| - << ", inliers = " << descInliersCount |
160 |
| - << ", descInliersRatio = " << static_cast<float>(descInliersCount) / keypoints0.size() |
161 |
| - << std::endl; |
162 |
| -#endif |
163 |
| - } |
164 |
| -} |
| 14 | +#define Value(...) Values(make_tuple(__VA_ARGS__)) |
165 | 15 |
|
166 | 16 | /*
|
167 | 17 | * Descriptors's rotation invariance check
|
|
0 commit comments