1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
22 //
23 // * Redistribution's in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
26 //
27 // * The name of the copyright holders may not be used to endorse or promote products
28 // derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42
43 #include "perf_precomp.hpp"
44
45 using namespace std;
46 using namespace testing;
47 using namespace perf;
48
49 //////////////////////////////////////////////////////////////////////
50 // FAST
51
52 DEF_PARAM_TEST(Image_Threshold_NonMaxSuppression, string, int, bool);
53
54 PERF_TEST_P(Image_Threshold_NonMaxSuppression, FAST,
55 Combine(Values<string>("gpu/perf/aloe.png"),
56 Values(20),
57 Bool()))
58 {
59 const cv::Mat img = readImage(GET_PARAM(0), cv::IMREAD_GRAYSCALE);
60 ASSERT_FALSE(img.empty());
61
62 const int threshold = GET_PARAM(1);
63 const bool nonMaxSuppersion = GET_PARAM(2);
64
65 if (PERF_RUN_CUDA())
66 {
67 cv::Ptr<cv::cuda::FastFeatureDetector> d_fast =
68 cv::cuda::FastFeatureDetector::create(threshold, nonMaxSuppersion,
69 cv::FastFeatureDetector::TYPE_9_16,
70 0.5 * img.size().area());
71
72 const cv::cuda::GpuMat d_img(img);
73 cv::cuda::GpuMat d_keypoints;
74
75 TEST_CYCLE() d_fast->detectAsync(d_img, d_keypoints);
76
77 std::vector<cv::KeyPoint> gpu_keypoints;
78 d_fast->convert(d_keypoints, gpu_keypoints);
79
80 sortKeyPoints(gpu_keypoints);
81
82 SANITY_CHECK_KEYPOINTS(gpu_keypoints);
83 }
84 else
85 {
86 std::vector<cv::KeyPoint> cpu_keypoints;
87
88 TEST_CYCLE() cv::FAST(img, cpu_keypoints, threshold, nonMaxSuppersion);
89
90 SANITY_CHECK_KEYPOINTS(cpu_keypoints);
91 }
92 }
93
94 //////////////////////////////////////////////////////////////////////
95 // ORB
96
97 DEF_PARAM_TEST(Image_NFeatures, string, int);
98
99 PERF_TEST_P(Image_NFeatures, ORB,
100 Combine(Values<string>("gpu/perf/aloe.png"),
101 Values(4000)))
102 {
103 declare.time(300.0);
104
105 const cv::Mat img = readImage(GET_PARAM(0), cv::IMREAD_GRAYSCALE);
106 ASSERT_FALSE(img.empty());
107
108 const int nFeatures = GET_PARAM(1);
109
110 if (PERF_RUN_CUDA())
111 {
112 cv::Ptr<cv::cuda::ORB> d_orb = cv::cuda::ORB::create(nFeatures);
113
114 const cv::cuda::GpuMat d_img(img);
115 cv::cuda::GpuMat d_keypoints, d_descriptors;
116
117 TEST_CYCLE() d_orb->detectAndComputeAsync(d_img, cv::noArray(), d_keypoints, d_descriptors);
118
119 std::vector<cv::KeyPoint> gpu_keypoints;
120 d_orb->convert(d_keypoints, gpu_keypoints);
121
122 cv::Mat gpu_descriptors(d_descriptors);
123
124 gpu_keypoints.resize(10);
125 gpu_descriptors = gpu_descriptors.rowRange(0, 10);
126
127 sortKeyPoints(gpu_keypoints, gpu_descriptors);
128
129 SANITY_CHECK_KEYPOINTS(gpu_keypoints, 1e-4);
130 SANITY_CHECK(gpu_descriptors);
131 }
132 else
133 {
134 cv::Ptr<cv::ORB> orb = cv::ORB::create(nFeatures);
135
136 std::vector<cv::KeyPoint> cpu_keypoints;
137 cv::Mat cpu_descriptors;
138
139 TEST_CYCLE() orb->detectAndCompute(img, cv::noArray(), cpu_keypoints, cpu_descriptors);
140
141 SANITY_CHECK_KEYPOINTS(cpu_keypoints);
142 SANITY_CHECK(cpu_descriptors);
143 }
144 }
145
146 //////////////////////////////////////////////////////////////////////
147 // BFMatch
148
149 DEF_PARAM_TEST(DescSize_Norm, int, NormType);
150
151 PERF_TEST_P(DescSize_Norm, BFMatch,
152 Combine(Values(64, 128, 256),
153 Values(NormType(cv::NORM_L1), NormType(cv::NORM_L2), NormType(cv::NORM_HAMMING))))
154 {
155 declare.time(20.0);
156
157 const int desc_size = GET_PARAM(0);
158 const int normType = GET_PARAM(1);
159
160 const int type = normType == cv::NORM_HAMMING ? CV_8U : CV_32F;
161
162 cv::Mat query(3000, desc_size, type);
163 declare.in(query, WARMUP_RNG);
164
165 cv::Mat train(3000, desc_size, type);
166 declare.in(train, WARMUP_RNG);
167
168 if (PERF_RUN_CUDA())
169 {
170 cv::Ptr<cv::cuda::DescriptorMatcher> d_matcher = cv::cuda::DescriptorMatcher::createBFMatcher(normType);
171
172 const cv::cuda::GpuMat d_query(query);
173 const cv::cuda::GpuMat d_train(train);
174 cv::cuda::GpuMat d_matches;
175
176 TEST_CYCLE() d_matcher->matchAsync(d_query, d_train, d_matches);
177
178 std::vector<cv::DMatch> gpu_matches;
179 d_matcher->matchConvert(d_matches, gpu_matches);
180
181 SANITY_CHECK_MATCHES(gpu_matches);
182 }
183 else
184 {
185 cv::BFMatcher matcher(normType);
186
187 std::vector<cv::DMatch> cpu_matches;
188
189 TEST_CYCLE() matcher.match(query, train, cpu_matches);
190
191 SANITY_CHECK_MATCHES(cpu_matches);
192 }
193 }
194
195 //////////////////////////////////////////////////////////////////////
196 // BFKnnMatch
197
toOneRowMatches(const std::vector<std::vector<cv::DMatch>> & src,std::vector<cv::DMatch> & dst)198 static void toOneRowMatches(const std::vector< std::vector<cv::DMatch> >& src, std::vector<cv::DMatch>& dst)
199 {
200 dst.clear();
201 for (size_t i = 0; i < src.size(); ++i)
202 for (size_t j = 0; j < src[i].size(); ++j)
203 dst.push_back(src[i][j]);
204 }
205
206 DEF_PARAM_TEST(DescSize_K_Norm, int, int, NormType);
207
208 PERF_TEST_P(DescSize_K_Norm, BFKnnMatch,
209 Combine(Values(64, 128, 256),
210 Values(2, 3),
211 Values(NormType(cv::NORM_L1), NormType(cv::NORM_L2))))
212 {
213 declare.time(30.0);
214
215 const int desc_size = GET_PARAM(0);
216 const int k = GET_PARAM(1);
217 const int normType = GET_PARAM(2);
218
219 const int type = normType == cv::NORM_HAMMING ? CV_8U : CV_32F;
220
221 cv::Mat query(3000, desc_size, type);
222 declare.in(query, WARMUP_RNG);
223
224 cv::Mat train(3000, desc_size, type);
225 declare.in(train, WARMUP_RNG);
226
227 if (PERF_RUN_CUDA())
228 {
229 cv::Ptr<cv::cuda::DescriptorMatcher> d_matcher = cv::cuda::DescriptorMatcher::createBFMatcher(normType);
230
231 const cv::cuda::GpuMat d_query(query);
232 const cv::cuda::GpuMat d_train(train);
233 cv::cuda::GpuMat d_matches;
234
235 TEST_CYCLE() d_matcher->knnMatchAsync(d_query, d_train, d_matches, k);
236
237 std::vector< std::vector<cv::DMatch> > matchesTbl;
238 d_matcher->knnMatchConvert(d_matches, matchesTbl);
239
240 std::vector<cv::DMatch> gpu_matches;
241 toOneRowMatches(matchesTbl, gpu_matches);
242
243 SANITY_CHECK_MATCHES(gpu_matches);
244 }
245 else
246 {
247 cv::BFMatcher matcher(normType);
248
249 std::vector< std::vector<cv::DMatch> > matchesTbl;
250
251 TEST_CYCLE() matcher.knnMatch(query, train, matchesTbl, k);
252
253 std::vector<cv::DMatch> cpu_matches;
254 toOneRowMatches(matchesTbl, cpu_matches);
255
256 SANITY_CHECK_MATCHES(cpu_matches);
257 }
258 }
259
260 //////////////////////////////////////////////////////////////////////
261 // BFRadiusMatch
262
263 PERF_TEST_P(DescSize_Norm, BFRadiusMatch,
264 Combine(Values(64, 128, 256),
265 Values(NormType(cv::NORM_L1), NormType(cv::NORM_L2))))
266 {
267 declare.time(30.0);
268
269 const int desc_size = GET_PARAM(0);
270 const int normType = GET_PARAM(1);
271
272 const int type = normType == cv::NORM_HAMMING ? CV_8U : CV_32F;
273 const float maxDistance = 10000;
274
275 cv::Mat query(3000, desc_size, type);
276 declare.in(query, WARMUP_RNG);
277
278 cv::Mat train(3000, desc_size, type);
279 declare.in(train, WARMUP_RNG);
280
281 if (PERF_RUN_CUDA())
282 {
283 cv::Ptr<cv::cuda::DescriptorMatcher> d_matcher = cv::cuda::DescriptorMatcher::createBFMatcher(normType);
284
285 const cv::cuda::GpuMat d_query(query);
286 const cv::cuda::GpuMat d_train(train);
287 cv::cuda::GpuMat d_matches;
288
289 TEST_CYCLE() d_matcher->radiusMatchAsync(d_query, d_train, d_matches, maxDistance);
290
291 std::vector< std::vector<cv::DMatch> > matchesTbl;
292 d_matcher->radiusMatchConvert(d_matches, matchesTbl);
293
294 std::vector<cv::DMatch> gpu_matches;
295 toOneRowMatches(matchesTbl, gpu_matches);
296
297 SANITY_CHECK_MATCHES(gpu_matches);
298 }
299 else
300 {
301 cv::BFMatcher matcher(normType);
302
303 std::vector< std::vector<cv::DMatch> > matchesTbl;
304
305 TEST_CYCLE() matcher.radiusMatch(query, train, matchesTbl, maxDistance);
306
307 std::vector<cv::DMatch> cpu_matches;
308 toOneRowMatches(matchesTbl, cpu_matches);
309
310 SANITY_CHECK_MATCHES(cpu_matches);
311 }
312 }
313