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 "test_precomp.hpp"
44
45 #ifdef HAVE_CUDA
46
47 using namespace cvtest;
48
49 ////////////////////////////////////////////////////////////////////////////////
50 // MatchTemplate8U
51
52 CV_ENUM(TemplateMethod, cv::TM_SQDIFF, cv::TM_SQDIFF_NORMED, cv::TM_CCORR, cv::TM_CCORR_NORMED, cv::TM_CCOEFF, cv::TM_CCOEFF_NORMED)
53 #define ALL_TEMPLATE_METHODS testing::Values(TemplateMethod(cv::TM_SQDIFF), TemplateMethod(cv::TM_SQDIFF_NORMED), TemplateMethod(cv::TM_CCORR), TemplateMethod(cv::TM_CCORR_NORMED), TemplateMethod(cv::TM_CCOEFF), TemplateMethod(cv::TM_CCOEFF_NORMED))
54
55 namespace
56 {
57 IMPLEMENT_PARAM_CLASS(TemplateSize, cv::Size);
58 }
59
PARAM_TEST_CASE(MatchTemplate8U,cv::cuda::DeviceInfo,cv::Size,TemplateSize,Channels,TemplateMethod)60 PARAM_TEST_CASE(MatchTemplate8U, cv::cuda::DeviceInfo, cv::Size, TemplateSize, Channels, TemplateMethod)
61 {
62 cv::cuda::DeviceInfo devInfo;
63 cv::Size size;
64 cv::Size templ_size;
65 int cn;
66 int method;
67
68 virtual void SetUp()
69 {
70 devInfo = GET_PARAM(0);
71 size = GET_PARAM(1);
72 templ_size = GET_PARAM(2);
73 cn = GET_PARAM(3);
74 method = GET_PARAM(4);
75
76 cv::cuda::setDevice(devInfo.deviceID());
77 }
78 };
79
CUDA_TEST_P(MatchTemplate8U,Accuracy)80 CUDA_TEST_P(MatchTemplate8U, Accuracy)
81 {
82 cv::Mat image = randomMat(size, CV_MAKETYPE(CV_8U, cn));
83 cv::Mat templ = randomMat(templ_size, CV_MAKETYPE(CV_8U, cn));
84
85 cv::Ptr<cv::cuda::TemplateMatching> alg = cv::cuda::createTemplateMatching(image.type(), method);
86
87 cv::cuda::GpuMat dst;
88 alg->match(loadMat(image), loadMat(templ), dst);
89
90 cv::Mat dst_gold;
91 cv::matchTemplate(image, templ, dst_gold, method);
92
93 cv::Mat h_dst(dst);
94 ASSERT_EQ(dst_gold.size(), h_dst.size());
95 ASSERT_EQ(dst_gold.type(), h_dst.type());
96 for (int y = 0; y < h_dst.rows; ++y)
97 {
98 for (int x = 0; x < h_dst.cols; ++x)
99 {
100 float gold_val = dst_gold.at<float>(y, x);
101 float actual_val = dst_gold.at<float>(y, x);
102 ASSERT_FLOAT_EQ(gold_val, actual_val) << y << ", " << x;
103 }
104 }
105 }
106
107 INSTANTIATE_TEST_CASE_P(CUDA_ImgProc, MatchTemplate8U, testing::Combine(
108 ALL_DEVICES,
109 DIFFERENT_SIZES,
110 testing::Values(TemplateSize(cv::Size(5, 5)), TemplateSize(cv::Size(16, 16)), TemplateSize(cv::Size(30, 30))),
111 testing::Values(Channels(1), Channels(3), Channels(4)),
112 ALL_TEMPLATE_METHODS));
113
114 ////////////////////////////////////////////////////////////////////////////////
115 // MatchTemplate32F
116
PARAM_TEST_CASE(MatchTemplate32F,cv::cuda::DeviceInfo,cv::Size,TemplateSize,Channels,TemplateMethod)117 PARAM_TEST_CASE(MatchTemplate32F, cv::cuda::DeviceInfo, cv::Size, TemplateSize, Channels, TemplateMethod)
118 {
119 cv::cuda::DeviceInfo devInfo;
120 cv::Size size;
121 cv::Size templ_size;
122 int cn;
123 int method;
124
125 int n, m, h, w;
126
127 virtual void SetUp()
128 {
129 devInfo = GET_PARAM(0);
130 size = GET_PARAM(1);
131 templ_size = GET_PARAM(2);
132 cn = GET_PARAM(3);
133 method = GET_PARAM(4);
134
135 cv::cuda::setDevice(devInfo.deviceID());
136 }
137 };
138
CUDA_TEST_P(MatchTemplate32F,Regression)139 CUDA_TEST_P(MatchTemplate32F, Regression)
140 {
141 cv::Mat image = randomMat(size, CV_MAKETYPE(CV_32F, cn));
142 cv::Mat templ = randomMat(templ_size, CV_MAKETYPE(CV_32F, cn));
143
144 cv::Ptr<cv::cuda::TemplateMatching> alg = cv::cuda::createTemplateMatching(image.type(), method);
145
146 cv::cuda::GpuMat dst;
147 alg->match(loadMat(image), loadMat(templ), dst);
148
149 cv::Mat dst_gold;
150 cv::matchTemplate(image, templ, dst_gold, method);
151
152 cv::Mat h_dst(dst);
153 ASSERT_EQ(dst_gold.size(), h_dst.size());
154 ASSERT_EQ(dst_gold.type(), h_dst.type());
155 for (int y = 0; y < h_dst.rows; ++y)
156 {
157 for (int x = 0; x < h_dst.cols; ++x)
158 {
159 float gold_val = dst_gold.at<float>(y, x);
160 float actual_val = dst_gold.at<float>(y, x);
161 ASSERT_FLOAT_EQ(gold_val, actual_val) << y << ", " << x;
162 }
163 }
164 }
165
166 INSTANTIATE_TEST_CASE_P(CUDA_ImgProc, MatchTemplate32F, testing::Combine(
167 ALL_DEVICES,
168 DIFFERENT_SIZES,
169 testing::Values(TemplateSize(cv::Size(5, 5)), TemplateSize(cv::Size(16, 16)), TemplateSize(cv::Size(30, 30))),
170 testing::Values(Channels(1), Channels(3), Channels(4)),
171 testing::Values(TemplateMethod(cv::TM_SQDIFF), TemplateMethod(cv::TM_CCORR))));
172
173 ////////////////////////////////////////////////////////////////////////////////
174 // MatchTemplateBlackSource
175
PARAM_TEST_CASE(MatchTemplateBlackSource,cv::cuda::DeviceInfo,TemplateMethod)176 PARAM_TEST_CASE(MatchTemplateBlackSource, cv::cuda::DeviceInfo, TemplateMethod)
177 {
178 cv::cuda::DeviceInfo devInfo;
179 int method;
180
181 virtual void SetUp()
182 {
183 devInfo = GET_PARAM(0);
184 method = GET_PARAM(1);
185
186 cv::cuda::setDevice(devInfo.deviceID());
187 }
188 };
189
CUDA_TEST_P(MatchTemplateBlackSource,Accuracy)190 CUDA_TEST_P(MatchTemplateBlackSource, Accuracy)
191 {
192 cv::Mat image = readImage("matchtemplate/black.png");
193 ASSERT_FALSE(image.empty());
194
195 cv::Mat pattern = readImage("matchtemplate/cat.png");
196 ASSERT_FALSE(pattern.empty());
197
198 cv::Ptr<cv::cuda::TemplateMatching> alg = cv::cuda::createTemplateMatching(image.type(), method);
199
200 cv::cuda::GpuMat d_dst;
201 alg->match(loadMat(image), loadMat(pattern), d_dst);
202
203 cv::Mat dst(d_dst);
204
205 double maxValue;
206 cv::Point maxLoc;
207 cv::minMaxLoc(dst, NULL, &maxValue, NULL, &maxLoc);
208
209 cv::Point maxLocGold = cv::Point(284, 12);
210
211 ASSERT_EQ(maxLocGold, maxLoc);
212 }
213
214 INSTANTIATE_TEST_CASE_P(CUDA_ImgProc, MatchTemplateBlackSource, testing::Combine(
215 ALL_DEVICES,
216 testing::Values(TemplateMethod(cv::TM_CCOEFF_NORMED), TemplateMethod(cv::TM_CCORR_NORMED))));
217
218 ////////////////////////////////////////////////////////////////////////////////
219 // MatchTemplate_CCOEF_NORMED
220
PARAM_TEST_CASE(MatchTemplate_CCOEF_NORMED,cv::cuda::DeviceInfo,std::pair<std::string,std::string>)221 PARAM_TEST_CASE(MatchTemplate_CCOEF_NORMED, cv::cuda::DeviceInfo, std::pair<std::string, std::string>)
222 {
223 cv::cuda::DeviceInfo devInfo;
224 std::string imageName;
225 std::string patternName;
226
227 virtual void SetUp()
228 {
229 devInfo = GET_PARAM(0);
230 imageName = GET_PARAM(1).first;
231 patternName = GET_PARAM(1).second;
232
233 cv::cuda::setDevice(devInfo.deviceID());
234 }
235 };
236
CUDA_TEST_P(MatchTemplate_CCOEF_NORMED,Accuracy)237 CUDA_TEST_P(MatchTemplate_CCOEF_NORMED, Accuracy)
238 {
239 cv::Mat image = readImage(imageName);
240 ASSERT_FALSE(image.empty());
241
242 cv::Mat pattern = readImage(patternName);
243 ASSERT_FALSE(pattern.empty());
244
245 cv::Ptr<cv::cuda::TemplateMatching> alg = cv::cuda::createTemplateMatching(image.type(), cv::TM_CCOEFF_NORMED);
246
247 cv::cuda::GpuMat d_dst;
248 alg->match(loadMat(image), loadMat(pattern), d_dst);
249
250 cv::Mat dst(d_dst);
251
252 cv::Point minLoc, maxLoc;
253 double minVal, maxVal;
254 cv::minMaxLoc(dst, &minVal, &maxVal, &minLoc, &maxLoc);
255
256 cv::Mat dstGold;
257 cv::matchTemplate(image, pattern, dstGold, cv::TM_CCOEFF_NORMED);
258
259 double minValGold, maxValGold;
260 cv::Point minLocGold, maxLocGold;
261 cv::minMaxLoc(dstGold, &minValGold, &maxValGold, &minLocGold, &maxLocGold);
262
263 ASSERT_EQ(minLocGold, minLoc);
264 ASSERT_EQ(maxLocGold, maxLoc);
265 ASSERT_LE(maxVal, 1.0);
266 ASSERT_GE(minVal, -1.0);
267 }
268
269 INSTANTIATE_TEST_CASE_P(CUDA_ImgProc, MatchTemplate_CCOEF_NORMED, testing::Combine(
270 ALL_DEVICES,
271 testing::Values(std::make_pair(std::string("matchtemplate/source-0.png"), std::string("matchtemplate/target-0.png")))));
272
273 ////////////////////////////////////////////////////////////////////////////////
274 // MatchTemplate_CanFindBigTemplate
275
276 struct MatchTemplate_CanFindBigTemplate : testing::TestWithParam<cv::cuda::DeviceInfo>
277 {
278 cv::cuda::DeviceInfo devInfo;
279
SetUpMatchTemplate_CanFindBigTemplate280 virtual void SetUp()
281 {
282 devInfo = GetParam();
283
284 cv::cuda::setDevice(devInfo.deviceID());
285 }
286 };
287
CUDA_TEST_P(MatchTemplate_CanFindBigTemplate,SQDIFF_NORMED)288 CUDA_TEST_P(MatchTemplate_CanFindBigTemplate, SQDIFF_NORMED)
289 {
290 cv::Mat scene = readImage("matchtemplate/scene.png");
291 ASSERT_FALSE(scene.empty());
292
293 cv::Mat templ = readImage("matchtemplate/template.png");
294 ASSERT_FALSE(templ.empty());
295
296 cv::Ptr<cv::cuda::TemplateMatching> alg = cv::cuda::createTemplateMatching(scene.type(), cv::TM_SQDIFF_NORMED);
297
298 cv::cuda::GpuMat d_result;
299 alg->match(loadMat(scene), loadMat(templ), d_result);
300
301 cv::Mat result(d_result);
302
303 double minVal;
304 cv::Point minLoc;
305 cv::minMaxLoc(result, &minVal, 0, &minLoc, 0);
306
307 ASSERT_GE(minVal, 0);
308 ASSERT_LT(minVal, 1e-3);
309 ASSERT_EQ(344, minLoc.x);
310 ASSERT_EQ(0, minLoc.y);
311 }
312
CUDA_TEST_P(MatchTemplate_CanFindBigTemplate,SQDIFF)313 CUDA_TEST_P(MatchTemplate_CanFindBigTemplate, SQDIFF)
314 {
315 cv::Mat scene = readImage("matchtemplate/scene.png");
316 ASSERT_FALSE(scene.empty());
317
318 cv::Mat templ = readImage("matchtemplate/template.png");
319 ASSERT_FALSE(templ.empty());
320
321 cv::Ptr<cv::cuda::TemplateMatching> alg = cv::cuda::createTemplateMatching(scene.type(), cv::TM_SQDIFF);
322
323 cv::cuda::GpuMat d_result;
324 alg->match(loadMat(scene), loadMat(templ), d_result);
325
326 cv::Mat result(d_result);
327
328 double minVal;
329 cv::Point minLoc;
330 cv::minMaxLoc(result, &minVal, 0, &minLoc, 0);
331
332 ASSERT_GE(minVal, 0);
333 ASSERT_EQ(344, minLoc.x);
334 ASSERT_EQ(0, minLoc.y);
335 }
336
337 INSTANTIATE_TEST_CASE_P(CUDA_ImgProc, MatchTemplate_CanFindBigTemplate, ALL_DEVICES);
338
339 #endif // HAVE_CUDA
340