fixed
authorElena Gvozdeva <elena.gvozdeva@itseez.com>
Wed, 9 Apr 2014 13:36:00 +0000 (17:36 +0400)
committerElena Gvozdeva <elena.gvozdeva@itseez.com>
Thu, 10 Apr 2014 13:26:38 +0000 (17:26 +0400)
modules/imgproc/src/templmatch.cpp

index 96c2a70..d3fb92e 100644 (file)
@@ -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<uchar> 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