diff --git a/modules/imgproc/src/templmatch.cpp b/modules/imgproc/src/templmatch.cpp index 1abb8fb2f..ae10cd929 100644 --- a/modules/imgproc/src/templmatch.cpp +++ b/modules/imgproc/src/templmatch.cpp @@ -45,17 +45,17 @@ //////////////////////////////////////////////////matchTemplate////////////////////////////////////////////////////////// namespace cv { - static bool matchTemplate_CCORR(const UMat &image, const UMat &templ, UMat &result); - static bool matchTemplate_CCORR_NORMED(const UMat &image, const UMat &templ, UMat &result); + static bool matchTemplate_CCORR(InputArray _image, InputArray _templ, OutputArray _result); + static bool matchTemplate_CCORR_NORMED(InputArray _image, InputArray _templ, OutputArray _result); - static bool matchTemplate_SQDIFF(const UMat &image, const UMat &templ, UMat &result); - static bool matchTemplate_SQDIFF_NORMED (const UMat &image, const UMat &templ, UMat &result); + static bool matchTemplate_SQDIFF(InputArray _image, InputArray _templ, OutputArray _result); + static bool matchTemplate_SQDIFF_NORMED (InputArray _image, InputArray _templ, OutputArray _result); - static bool matchTemplate_CCOEFF(const UMat &image, const UMat &templ, UMat &result); - static bool matchTemplate_CCOEFF_NORMED(const UMat &image, const UMat &templ, UMat &result); + static bool matchTemplate_CCOEFF(InputArray _image, InputArray _templ, OutputArray _result); + static bool matchTemplate_CCOEFF_NORMED(InputArray _image, InputArray _templ, OutputArray _result); - static bool matchTemplateNaive_CCORR (const UMat &image, const UMat &templ, UMat &result, int cn); - static bool matchTemplateNaive_SQDIFF(const UMat &image, const UMat &templ, UMat &result, int cn); + static bool matchTemplateNaive_CCORR (InputArray _image, InputArray _templ, OutputArray _result, int cn); + static bool matchTemplateNaive_SQDIFF(InputArray _image, InputArray _templ, OutputArray _result, int cn); static bool useNaive(int method, int depth, Size size) { @@ -76,39 +76,41 @@ namespace cv ///////////////////////////////////////////////////CCORR////////////////////////////////////////////////////////////// - static bool matchTemplate_CCORR(const UMat &image, const UMat &templ, UMat &result) + static bool matchTemplate_CCORR(InputArray _image, InputArray _templ, OutputArray _result) { - if (useNaive(TM_CCORR, image.depth(), templ.size()) ) - return matchTemplateNaive_CCORR(image, templ, result, image.channels()); + if (useNaive(TM_CCORR, _image.depth(), _templ.size()) ) + return matchTemplateNaive_CCORR(_image, _templ, _result, _image.channels()); else return false; } - static bool matchTemplateNaive_CCORR (const UMat &image, const UMat &templ, UMat &result, int cn) + static bool matchTemplateNaive_CCORR (InputArray _image, InputArray _templ, OutputArray _result, int cn) { - int type = image.type(); + int type = _image.type(); int depth = CV_MAT_DEPTH(type); - CV_Assert(result.channels() == 1); - const char * kernelName = "matchTemplate_Naive_CCORR"; ocl::Kernel k (kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn)); if (k.empty()) return false; + UMat image = _image.getUMat(); + UMat templ = _templ.getUMat(), result; + _result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F); + result = _result.getUMat(); + size_t globalsize[2] = {result.cols, result.rows}; size_t localsize[2] = {16, 16}; - return k.args(ocl::KernelArg::ReadOnlyNoSize(image), ocl::KernelArg::ReadOnly(templ), ocl::KernelArg::WriteOnly(result)).run(2,globalsize,localsize,true); + return k.args(ocl::KernelArg::ReadOnlyNoSize(image), ocl::KernelArg::ReadOnly(templ), ocl::KernelArg::WriteOnly(result)).run(2,globalsize,localsize,false); } - static bool matchTemplate_CCORR_NORMED(const UMat &image, const UMat &templ, UMat &result) + static bool matchTemplate_CCORR_NORMED(InputArray _image, InputArray _templ, OutputArray _result) { - if (!matchTemplate_CCORR(image, templ, result)) - return false; + matchTemplate(_image, _templ, _result, CV_TM_CCORR); - int type = image.type(); + int type = _image.type(); int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); const char * kernelName = "matchTemplate_CCORR_NORMED"; @@ -117,6 +119,11 @@ namespace cv if (k.empty()) return false; + UMat image = _image.getUMat(); + UMat templ = _templ.getUMat(), result; + _result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F); + result = _result.getUMat(); + UMat temp, image_sums, image_sqsums; integral(image.reshape(1), image_sums, temp); @@ -134,46 +141,48 @@ namespace cv size_t globalsize[2] = {result.cols, result.rows}; size_t localsize[2] = {16, 16}; - return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sqsums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sqsum).run(2,globalsize,localsize,true); + return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sqsums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sqsum).run(2,globalsize,localsize,false); } //////////////////////////////////////SQDIFF////////////////////////////////////////////////////////////// - static bool matchTemplate_SQDIFF(const UMat &image, const UMat &templ, UMat &result) + static bool matchTemplate_SQDIFF(InputArray _image, InputArray _templ, OutputArray _result) { - if (useNaive(TM_SQDIFF, image.depth(), templ.size())) + if (useNaive(TM_SQDIFF, _image.depth(), _templ.size())) { - return matchTemplateNaive_SQDIFF(image, templ, result, image.channels());; + return matchTemplateNaive_SQDIFF(_image, _templ, _result, _image.channels());; } else return false; } - static bool matchTemplateNaive_SQDIFF(const UMat &image, const UMat &templ, UMat &result, int cn) + static bool matchTemplateNaive_SQDIFF(InputArray _image, InputArray _templ, OutputArray _result, int cn) { - int type = image.type(); + int type = _image.type(); int depth = CV_MAT_DEPTH(type); - CV_Assert(result.channels() == 1); - const char * kernelName = "matchTemplate_Naive_SQDIFF"; ocl::Kernel k (kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn)); if (k.empty()) return false; + UMat image = _image.getUMat(); + UMat templ = _templ.getUMat(), result; + _result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F); + result = _result.getUMat(); + size_t globalsize[2] = {result.cols, result.rows}; size_t localsize[2] = {16, 16}; - return k.args(ocl::KernelArg::ReadOnlyNoSize(image), ocl::KernelArg::ReadOnly(templ), ocl::KernelArg::WriteOnly(result)).run(2,globalsize,localsize,true); + return k.args(ocl::KernelArg::ReadOnlyNoSize(image), ocl::KernelArg::ReadOnly(templ), ocl::KernelArg::WriteOnly(result)).run(2,globalsize,localsize,false); } - static bool matchTemplate_SQDIFF_NORMED (const UMat &image, const UMat &templ, UMat &result) + static bool matchTemplate_SQDIFF_NORMED (InputArray _image, InputArray _templ, OutputArray _result) { - if (!matchTemplate_CCORR(image, templ, result)) - return false; + matchTemplate(_image, _templ, _result, CV_TM_CCORR); - int type = image.type(); + int type = _image.type(); int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); const char * kernelName = "matchTemplate_SQDIFF_NORMED"; @@ -182,6 +191,11 @@ namespace cv if (k.empty()) return false; + UMat image = _image.getUMat(); + UMat templ = _templ.getUMat(), result; + _result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F); + result = _result.getUMat(); + UMat temp, image_sums, image_sqsums; integral(image.reshape(1), image_sums, temp); @@ -199,18 +213,17 @@ namespace cv size_t globalsize[2] = {result.cols, result.rows}; size_t localsize[2] = {16, 16}; - return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sqsums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sqsum).run(2,globalsize,localsize,true); + return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sqsums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sqsum).run(2,globalsize,localsize,false); } /////////////////////////////////////CCOEFF///////////////////////////////////////////////////////////////// - static bool matchTemplate_CCOEFF(const UMat &image, const UMat &templ, UMat &result) + static bool matchTemplate_CCOEFF(InputArray _image, InputArray _templ, OutputArray _result) { - if (!matchTemplate_CCORR(image, templ, result)) - return false; + matchTemplate(_image, _templ, _result, CV_TM_CCORR); UMat image_sums; - integral(image, image_sums); + integral(_image, image_sums); int type = image_sums.type(); int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); @@ -228,13 +241,18 @@ namespace cv if (k.empty()) return false; + UMat templ = _templ.getUMat(), result; + int image_rows = _image.size().height, image_cols = _image.size().width; + _result.create(image_rows - templ.rows + 1, image_cols - templ.cols + 1, CV_32F); + result = _result.getUMat(); + size_t globalsize[2] = {result.cols, result.rows}; size_t localsize[2] = {16, 16}; if (cn==1) { - float templ_sum = (float)sum(templ)[0]/ templ.size().area(); - return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sum).run(2,globalsize,localsize,true); + float templ_sum = (float)sum(_templ)[0]/ _templ.size().area(); + return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sum).run(2,globalsize,localsize,false); } else { @@ -242,26 +260,26 @@ namespace cv templ_sum = sum(templ)/ templ.size().area(); if (cn==2) return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, - templ_sum[0],templ_sum[1]).run(2,globalsize,localsize,true); + templ_sum[0],templ_sum[1]).run(2,globalsize,localsize,false); return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, - templ_sum[0],templ_sum[1],templ_sum[2],templ_sum[3]).run(2,globalsize,localsize,true); + templ_sum[0],templ_sum[1],templ_sum[2],templ_sum[3]).run(2,globalsize,localsize,false); } } - static bool matchTemplate_CCOEFF_NORMED(const UMat &image, const UMat &templ, UMat &result) + static bool matchTemplate_CCOEFF_NORMED(InputArray _image, InputArray _templ, OutputArray _result) { UMat imagef, templf; - image.convertTo(imagef, CV_32F); - templ.convertTo(templf, CV_32F); - if(!matchTemplate_CCORR(imagef, templf, result)) - return false; + _image.getUMat().convertTo(imagef, CV_32F); + _templ.getUMat().convertTo(templf, CV_32F); + + matchTemplate(imagef, templf, _result, CV_TM_CCORR); const char * kernelName; UMat temp, image_sums, image_sqsums; - integral(image,image_sums, temp); + integral(_image,image_sums, temp); int type = image_sums.type(); int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); @@ -278,6 +296,12 @@ namespace cv if (k.empty()) return false; + UMat image = _image.getUMat(); + UMat templ = _templ.getUMat(), result; + int image_rows = _image.size().height, image_cols = _image.size().width; + _result.create(image_rows - templ.rows + 1, image_cols - templ.cols + 1, CV_32F); + result = _result.getUMat(); + if(temp.depth() == CV_64F) temp.convertTo(image_sqsums, CV_32F); else @@ -306,7 +330,7 @@ namespace cv return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums),ocl::KernelArg::ReadOnlyNoSize(image_sqsums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, scale, templ_sum, templ_sqsum) - .run(2,globalsize,localsize,true); + .run(2,globalsize,localsize,false); } else { @@ -336,12 +360,12 @@ namespace cv return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::ReadOnlyNoSize(image_sqsums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, scale, templ_sum[0],templ_sum[1], templ_sqsum_sum) - .run(2,globalsize,localsize,true); + .run(2,globalsize,localsize,false); return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::ReadOnlyNoSize(image_sqsums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, scale, templ_sum[0],templ_sum[1],templ_sum[2],templ_sum[3], templ_sqsum_sum) - .run(2,globalsize,localsize,true); + .run(2,globalsize,localsize,false); } } @@ -355,7 +379,7 @@ namespace cv CV_Assert( cn == _templ.channels() && cn!=3 && cn<=4); - typedef bool (*Caller)(const UMat &, const UMat &, UMat &); + typedef bool (*Caller)(InputArray _img, InputArray _templ, OutputArray _result); const Caller callers[] = { @@ -365,11 +389,7 @@ namespace cv Caller caller = callers[method]; - UMat image = _img.getUMat(); - UMat templ = _templ.getUMat(), result; - _result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F); - result = _result.getUMat(); - return caller(image, templ, result); + return caller(_img, _templ, _result); } } diff --git a/modules/imgproc/test/ocl/test_match_template.cpp b/modules/imgproc/test/ocl/test_match_template.cpp index 48a8027b2..2a0402342 100644 --- a/modules/imgproc/test/ocl/test_match_template.cpp +++ b/modules/imgproc/test/ocl/test_match_template.cpp @@ -74,7 +74,7 @@ PARAM_TEST_CASE(MatchTemplate, MatDepth, Channels, int, bool) virtual void generateTestData() { - Size image_roiSize = randomSize(2, 20); + Size image_roiSize = randomSize(2, 100); Size templ_roiSize = Size(randomInt(1,image_roiSize.width), randomInt(1,image_roiSize.height)); Size result_roiSize = Size(image_roiSize.width - templ_roiSize.width + 1, image_roiSize.height - templ_roiSize.height + 1);