diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index e6186b587..b37dcb804 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -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(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(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(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(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);