From 42d45e0b02b3a4270f4b205c10d51dde38b58975 Mon Sep 17 00:00:00 2001 From: Elena Gvozdeva Date: Tue, 8 Apr 2014 16:48:13 +0400 Subject: [PATCH 1/3] Added ippiSqrDistanceNorm and ippiCrossCorrNorm to cv::matchTemplate --- modules/imgproc/src/templmatch.cpp | 66 ++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/modules/imgproc/src/templmatch.cpp b/modules/imgproc/src/templmatch.cpp index ca132dd0f8..6735cec279 100644 --- a/modules/imgproc/src/templmatch.cpp +++ b/modules/imgproc/src/templmatch.cpp @@ -341,6 +341,67 @@ static bool ocl_matchTemplate( InputArray _img, InputArray _templ, OutputArray _ #endif +#if defined (HAVE_IPP) + +typedef IppStatus (CV_STDCALL * ippiGetBufferSize)(IppiSize, IppiSize, IppEnum, int*); +typedef IppStatus (CV_STDCALL * ippimatchTemplate)(const void*, int, IppiSize, const void*, int, IppiSize, Ipp32f* , int , IppEnum , Ipp8u*); + + +static bool ipp_matchTemplate(const Mat& src, const Mat& tpl, Mat& dst, int method) +{ + if (src.channels() != 1 || (method!=CV_TM_SQDIFF && method!=CV_TM_CCORR)) + return false; + + IppStatus status; + + IppiSize srcRoiSize = {src.cols,src.rows}; + IppiSize tplRoiSize = {tpl.cols,tpl.rows}; + + IppEnum funCfg; + ippimatchTemplate ippFunc; + ippiGetBufferSize ippGetBufSize; + Ipp8u *pBuffer; + int bufSize=0; + + int depth = src.depth(); + + if (method==CV_TM_SQDIFF) + { + ippFunc = + depth==CV_8U ? (ippimatchTemplate)ippiSqrDistanceNorm_8u32f_C1R: + depth==CV_32F? (ippimatchTemplate)ippiSqrDistanceNorm_32f_C1R: 0; + + ippGetBufSize = (ippiGetBufferSize)ippiSqrDistanceNormGetBufferSize; + } + else + { + ippFunc = + depth==CV_8U ? (ippimatchTemplate)ippiCrossCorrNorm_8u32f_C1R: + depth==CV_32F? (ippimatchTemplate)ippiCrossCorrNorm_32f_C1R: 0; + + ippGetBufSize = (ippiGetBufferSize)ippiCrossCorrNormGetBufferSize; + } + if (ippFunc==0) + return false; + + funCfg = (IppEnum)(ippAlgAuto | ippiNormNone | ippiROIValid); + + status = ippGetBufSize(srcRoiSize, tplRoiSize, funCfg, &bufSize); + if ( status < 0 ) + return false; + + pBuffer = ippsMalloc_8u( bufSize ); + + status = ippFunc(src.data, (int)src.step, srcRoiSize, tpl.data, (int)tpl.step, tplRoiSize, (Ipp32f*)dst.data, dst.step, funCfg, pBuffer); + if (status < 0) + return false; + + ippsFree( pBuffer ); + return true; +} + +#endif + void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, Size corrsize, int ctype, Point anchor, double delta, int borderType ) @@ -555,6 +616,11 @@ void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result, _result.create(corrSize, CV_32F); Mat result = _result.getMat(); +#if defined (HAVE_IPP) + if (ipp_matchTemplate(img, templ, result, method)) + return; +#endif + #ifdef HAVE_TEGRA_OPTIMIZATION if (tegra::matchTemplate(img, templ, result, method)) return; From 6119ae0ea9c400154600d41a516044c3f1e83e53 Mon Sep 17 00:00:00 2001 From: Elena Gvozdeva Date: Wed, 9 Apr 2014 11:08:32 +0400 Subject: [PATCH 2/3] fixed --- modules/imgproc/src/templmatch.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/modules/imgproc/src/templmatch.cpp b/modules/imgproc/src/templmatch.cpp index 6735cec279..96c2a7092c 100644 --- a/modules/imgproc/src/templmatch.cpp +++ b/modules/imgproc/src/templmatch.cpp @@ -346,7 +346,6 @@ static bool ocl_matchTemplate( InputArray _img, InputArray _templ, OutputArray _ typedef IppStatus (CV_STDCALL * ippiGetBufferSize)(IppiSize, IppiSize, IppEnum, int*); typedef IppStatus (CV_STDCALL * ippimatchTemplate)(const void*, int, IppiSize, const void*, int, IppiSize, Ipp32f* , int , IppEnum , Ipp8u*); - static bool ipp_matchTemplate(const Mat& src, const Mat& tpl, Mat& dst, int method) { if (src.channels() != 1 || (method!=CV_TM_SQDIFF && method!=CV_TM_CCORR)) @@ -392,12 +391,10 @@ static bool ipp_matchTemplate(const Mat& src, const Mat& tpl, Mat& dst, int meth pBuffer = ippsMalloc_8u( bufSize ); - status = ippFunc(src.data, (int)src.step, srcRoiSize, tpl.data, (int)tpl.step, tplRoiSize, (Ipp32f*)dst.data, dst.step, funCfg, pBuffer); - if (status < 0) - return false; + status = ippFunc(src.data, (int)src.step, srcRoiSize, tpl.data, (int)tpl.step, tplRoiSize, (Ipp32f*)dst.data, (int)dst.step, funCfg, pBuffer); ippsFree( pBuffer ); - return true; + return status >= 0; } #endif From 43c29a675167b7290dba912f252c2e2887985ac9 Mon Sep 17 00:00:00 2001 From: Elena Gvozdeva Date: Wed, 9 Apr 2014 17:36:00 +0400 Subject: [PATCH 3/3] fixed --- modules/imgproc/src/templmatch.cpp | 77 ++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/modules/imgproc/src/templmatch.cpp b/modules/imgproc/src/templmatch.cpp index 96c2a7092c..d3fb92ebb3 100644 --- a/modules/imgproc/src/templmatch.cpp +++ b/modules/imgproc/src/templmatch.cpp @@ -341,14 +341,13 @@ static bool ocl_matchTemplate( InputArray _img, InputArray _templ, OutputArray _ #endif -#if defined (HAVE_IPP) +#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) -typedef IppStatus (CV_STDCALL * ippiGetBufferSize)(IppiSize, IppiSize, IppEnum, int*); typedef IppStatus (CV_STDCALL * ippimatchTemplate)(const void*, int, IppiSize, const void*, int, IppiSize, Ipp32f* , int , IppEnum , Ipp8u*); -static bool ipp_matchTemplate(const Mat& src, const Mat& tpl, Mat& dst, int method) +static bool ipp_crossCorr(const Mat& src, const Mat& tpl, Mat& dst) { - if (src.channels() != 1 || (method!=CV_TM_SQDIFF && method!=CV_TM_CCORR)) + if (src.channels()!= 1) return false; IppStatus status; @@ -356,36 +355,57 @@ static bool ipp_matchTemplate(const Mat& src, const Mat& tpl, Mat& dst, int meth IppiSize srcRoiSize = {src.cols,src.rows}; IppiSize tplRoiSize = {tpl.cols,tpl.rows}; - IppEnum funCfg; - ippimatchTemplate ippFunc; - ippiGetBufferSize ippGetBufSize; Ipp8u *pBuffer; int bufSize=0; int depth = src.depth(); - if (method==CV_TM_SQDIFF) - { - ippFunc = - depth==CV_8U ? (ippimatchTemplate)ippiSqrDistanceNorm_8u32f_C1R: - depth==CV_32F? (ippimatchTemplate)ippiSqrDistanceNorm_32f_C1R: 0; - - ippGetBufSize = (ippiGetBufferSize)ippiSqrDistanceNormGetBufferSize; - } - else - { - ippFunc = + ippimatchTemplate ippFunc = depth==CV_8U ? (ippimatchTemplate)ippiCrossCorrNorm_8u32f_C1R: depth==CV_32F? (ippimatchTemplate)ippiCrossCorrNorm_32f_C1R: 0; - ippGetBufSize = (ippiGetBufferSize)ippiCrossCorrNormGetBufferSize; - } if (ippFunc==0) return false; - funCfg = (IppEnum)(ippAlgAuto | ippiNormNone | ippiROIValid); + IppEnum funCfg = (IppEnum)(ippAlgAuto | ippiNormNone | ippiROIValid); + + status = ippiCrossCorrNormGetBufferSize(srcRoiSize, tplRoiSize, funCfg, &bufSize); + if ( status < 0 ) + return false; + + pBuffer = ippsMalloc_8u( bufSize ); + + status = ippFunc(src.data, (int)src.step, srcRoiSize, tpl.data, (int)tpl.step, tplRoiSize, (Ipp32f*)dst.data, (int)dst.step, funCfg, pBuffer); + + ippsFree( pBuffer ); + return status >= 0; +} + +static bool ipp_sqrDistance(const Mat& src, const Mat& tpl, Mat& dst) +{ + if (src.channels()!= 1) + return false; + + IppStatus status; + + IppiSize srcRoiSize = {src.cols,src.rows}; + IppiSize tplRoiSize = {tpl.cols,tpl.rows}; + + Ipp8u *pBuffer; + int bufSize=0; + + int depth = src.depth(); + + ippimatchTemplate ippFunc = + depth==CV_8U ? (ippimatchTemplate)ippiSqrDistanceNorm_8u32f_C1R: + depth==CV_32F? (ippimatchTemplate)ippiSqrDistanceNorm_32f_C1R: 0; + + if (ippFunc==0) + return false; + + IppEnum funCfg = (IppEnum)(ippAlgAuto | ippiNormNone | ippiROIValid); - status = ippGetBufSize(srcRoiSize, tplRoiSize, funCfg, &bufSize); + status = ippiSqrDistanceNormGetBufferSize(srcRoiSize, tplRoiSize, funCfg, &bufSize); if ( status < 0 ) return false; @@ -403,6 +423,11 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, Size corrsize, int ctype, Point anchor, double delta, int borderType ) { +#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) + if (ipp_crossCorr(img, _templ, corr)) + return; +#endif + const double blockScale = 4.5; const int minBlockSize = 256; std::vector buf; @@ -613,13 +638,13 @@ void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result, _result.create(corrSize, CV_32F); Mat result = _result.getMat(); -#if defined (HAVE_IPP) - if (ipp_matchTemplate(img, templ, result, method)) +#ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::matchTemplate(img, templ, result, method)) return; #endif -#ifdef HAVE_TEGRA_OPTIMIZATION - if (tegra::matchTemplate(img, templ, result, method)) +#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) + if (method == CV_TM_SQDIFF && ipp_sqrDistance(img, templ, result)) return; #endif