cv::remap
authorIlya Lavrenov <ilya.lavrenov@itseez.com>
Tue, 15 Apr 2014 19:43:14 +0000 (23:43 +0400)
committerIlya Lavrenov <ilya.lavrenov@itseez.com>
Tue, 22 Apr 2014 10:33:55 +0000 (14:33 +0400)
modules/imgproc/src/imgwarp.cpp

index 16ad555..c5213de 100644 (file)
@@ -71,7 +71,7 @@ namespace cv
     {
         Type values[channels];
         for( int i = 0; i < channels; i++ )
-            values[i] = (Type)value[i];
+            values[i] = saturate_cast<Type>(value[i]);
         return func(values, dataPointer, step, size) >= 0;
     }
 
@@ -82,11 +82,11 @@ namespace cv
             switch( depth )
             {
             case CV_8U:
-                return ippiSet_8u_C1R((Ipp8u)value[0], (Ipp8u *)dataPointer, step, size) >= 0;
+                return ippiSet_8u_C1R(saturate_cast<Ipp8u>(value[0]), (Ipp8u *)dataPointer, step, size) >= 0;
             case CV_16U:
-                return ippiSet_16u_C1R((Ipp16u)value[0], (Ipp16u *)dataPointer, step, size) >= 0;
+                return ippiSet_16u_C1R(saturate_cast<Ipp16u>(value[0]), (Ipp16u *)dataPointer, step, size) >= 0;
             case CV_32F:
-                return ippiSet_32f_C1R((Ipp32f)value[0], (Ipp32f *)dataPointer, step, size) >= 0;
+                return ippiSet_32f_C1R(saturate_cast<Ipp32f>(value[0]), (Ipp32f *)dataPointer, step, size) >= 0;
             }
         }
         else
@@ -3657,6 +3657,54 @@ static bool ocl_remap(InputArray _src, OutputArray _dst, InputArray _map1, Input
 
 #endif
 
+#if IPP_VERSION_X100 >= 0 && !defined HAVE_IPP_ICV_ONLY && 0
+
+typedef IppStatus (CV_STDCALL * ippiRemap)(const void * pSrc, IppiSize srcSize, int srcStep, IppiRect srcRoi,
+                                           const Ipp32f* pxMap, int xMapStep, const Ipp32f* pyMap, int yMapStep,
+                                           void * pDst, int dstStep, IppiSize dstRoiSize, int interpolation);
+
+class IPPRemapInvoker :
+        public ParallelLoopBody
+{
+public:
+    IPPRemapInvoker(Mat & _src, Mat & _dst, Mat & _xmap, Mat & _ymap, ippiRemap _ippFunc,
+                    int _ippInterpolation, int _borderType, const Scalar & _borderValue, bool * _ok) :
+        ParallelLoopBody(), src(_src), dst(_dst), map1(_xmap), map2(_ymap), ippFunc(_ippFunc),
+        ippInterpolation(_ippInterpolation), borderType(_borderType), borderValue(_borderValue), ok(_ok)
+    {
+        *ok = true;
+    }
+
+    virtual void operator() (const Range & range) const
+    {
+        IppiRect srcRoiRect = { 0, 0, src.cols, src.rows };
+        Mat dstRoi = dst.rowRange(range);
+        IppiSize dstRoiSize = ippiSize(dstRoi.size());
+        int type = dst.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
+
+        if (borderType == BORDER_CONSTANT &&
+                !IPPSet(borderValue, dstRoi.data, (int)dstRoi.step, dstRoiSize, cn, depth))
+        {
+            *ok = false;
+            return;
+        }
+
+        if (ippFunc(src.data, ippiSize(src.size()), (int)src.step, srcRoiRect,
+                    (const Ipp32f *)map1.data, (int)map1.step, (const Ipp32f *)map2.data, (int)map2.step,
+                    dstRoi.data, (int)dstRoi.step, dstRoiSize, ippInterpolation) < 0)
+            *ok = false;
+    }
+
+private:
+    Mat & src, & dst, & map1, & map2;
+    ippiRemap ippFunc;
+    int ippInterpolation, borderType;
+    Scalar borderValue;
+    bool * ok;
+};
+
+#endif
+
 }
 
 void cv::remap( InputArray _src, OutputArray _dst,
@@ -3708,7 +3756,46 @@ void cv::remap( InputArray _src, OutputArray _dst,
     if( dst.data == src.data )
         src = src.clone();
 
-    int depth = src.depth();
+    if( interpolation == INTER_AREA )
+        interpolation = INTER_LINEAR;
+
+    int type = src.type(), depth = CV_MAT_DEPTH(type);
+
+#if IPP_VERSION_X100 >= 0 && !defined HAVE_IPP_ICV_ONLY && 0
+    if ((interpolation == INTER_LINEAR || interpolation == INTER_CUBIC || interpolation == INTER_NEAREST) &&
+            map1.type() == CV_32FC1 && map2.type() == CV_32FC1 &&
+            (borderType == BORDER_CONSTANT || borderType == BORDER_TRANSPARENT))
+    {
+        int ippInterpolation =
+            interpolation == INTER_NEAREST ? IPPI_INTER_NN :
+            interpolation == INTER_LINEAR ? IPPI_INTER_LINEAR : IPPI_INTER_CUBIC;
+
+        ippiRemap ippFunc =
+            type == CV_8UC1 ? (ippiRemap)ippiRemap_8u_C1R :
+            type == CV_8UC3 ? (ippiRemap)ippiRemap_8u_C3R :
+            type == CV_8UC4 ? (ippiRemap)ippiRemap_8u_C4R :
+            type == CV_16UC1 ? (ippiRemap)ippiRemap_16u_C1R :
+            type == CV_16UC3 ? (ippiRemap)ippiRemap_16u_C3R :
+            type == CV_16UC4 ? (ippiRemap)ippiRemap_16u_C4R :
+            type == CV_32FC1 ? (ippiRemap)ippiRemap_32f_C1R :
+            type == CV_32FC3 ? (ippiRemap)ippiRemap_32f_C3R :
+            type == CV_32FC4 ? (ippiRemap)ippiRemap_32f_C4R : 0;
+
+        if (ippFunc)
+        {
+            bool ok;
+            IPPRemapInvoker invoker(src, dst, map1, map2, ippFunc, ippInterpolation,
+                                    borderType, borderValue, &ok);
+            Range range(0, dst.rows);
+            parallel_for_(range, invoker, dst.total() / (double)(1 << 16));
+
+            if (ok)
+                return;
+            setIppErrorStatus();
+        }
+    }
+#endif
+
     RemapNNFunc nnfunc = 0;
     RemapFunc ifunc = 0;
     const void* ctab = 0;
@@ -3722,9 +3809,6 @@ void cv::remap( InputArray _src, OutputArray _dst,
     }
     else
     {
-        if( interpolation == INTER_AREA )
-            interpolation = INTER_LINEAR;
-
         if( interpolation == INTER_LINEAR )
             ifunc = linear_tab[depth];
         else if( interpolation == INTER_CUBIC )
@@ -4023,8 +4107,7 @@ private:
 };
 
 
-    /*
-#if defined (HAVE_IPP) && IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR >= 801
+#if defined (HAVE_IPP) && IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR >= 801 && 0
 class IPPWarpAffineInvoker :
     public ParallelLoopBody
 {
@@ -4072,7 +4155,6 @@ private:
     const IPPWarpAffineInvoker& operator= (const IPPWarpAffineInvoker&);
 };
 #endif
-    */
 
 #ifdef HAVE_OPENCL
 
@@ -4223,8 +4305,7 @@ void cv::warpAffine( InputArray _src, OutputArray _dst,
     const int AB_BITS = MAX(10, (int)INTER_BITS);
     const int AB_SCALE = 1 << AB_BITS;
 
-    /*
-#if defined (HAVE_IPP) && IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR >= 801
+#if defined (HAVE_IPP) && IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR >= 801 && 0
     int type = src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
     if( ( depth == CV_8U || depth == CV_16U || depth == CV_32F ) &&
        ( cn == 1 || cn == 3 || cn == 4 ) &&
@@ -4281,7 +4362,6 @@ void cv::warpAffine( InputArray _src, OutputArray _dst,
         setIppErrorStatus();
     }
 #endif
-     */
 
     for( x = 0; x < dst.cols; x++ )
     {
@@ -4390,8 +4470,8 @@ private:
     Scalar borderValue;
 };
 
-    /*
-#if defined (HAVE_IPP) && IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR >= 801
+
+#if defined (HAVE_IPP) && IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR >= 801 && 0
 class IPPWarpPerspectiveInvoker :
     public ParallelLoopBody
 {
@@ -4439,7 +4519,6 @@ private:
     const IPPWarpPerspectiveInvoker& operator= (const IPPWarpPerspectiveInvoker&);
 };
 #endif
-    */
 }
 
 void cv::warpPerspective( InputArray _src, OutputArray _dst, InputArray _M0,
@@ -4472,8 +4551,8 @@ void cv::warpPerspective( InputArray _src, OutputArray _dst, InputArray _M0,
         return;
 #endif
 
-    /*
-#if defined (HAVE_IPP) && IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR >= 801
+
+#if defined (HAVE_IPP) && IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR >= 801 && 0
     int type = src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
     if( (depth == CV_8U || depth == CV_16U || depth == CV_32F) &&
        (cn == 1 || cn == 3 || cn == 4) &&
@@ -4525,7 +4604,6 @@ void cv::warpPerspective( InputArray _src, OutputArray _dst, InputArray _M0,
         setIppErrorStatus();
     }
 #endif
-    */
 
     if( !(flags & WARP_INVERSE_MAP) )
         invert(matM, matM);