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