test_match_template.cpp 11 KB

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