From baa6ab19671d93eea003ad0efa48b1512d9a81b2 Mon Sep 17 00:00:00 2001 From: vbystricky Date: Mon, 14 Apr 2014 15:47:50 +0400 Subject: [PATCH] Change Scharr filter to new ipp functions --- modules/imgproc/src/deriv.cpp | 354 ++++++++++++++++++++++++++++-------------- 1 file changed, 236 insertions(+), 118 deletions(-) diff --git a/modules/imgproc/src/deriv.cpp b/modules/imgproc/src/deriv.cpp index c6885d4..854ca73 100644 --- a/modules/imgproc/src/deriv.cpp +++ b/modules/imgproc/src/deriv.cpp @@ -187,9 +187,128 @@ cv::Ptr cv::createDerivFilter(int srcType, int dstType, namespace cv { +#if (IPP_VERSION_X100 >= 801) +typedef IppStatus (CV_STDCALL* ippiFilterScharrMaskBorder)(const void* pSrc, int srcStep, void* pDst, int dstStep, IppiSize dstRoiSize, IppiMaskSize mask, IppiBorderType borderType, Ipp8u borderValue, Ipp8u* pBuffer); +static bool IPPDerivScharr(InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, double scale, double delta, int borderType) +{ + if ((0 > dx) || (0 > dy) || (1 != dx + dy)) + return false; + if (fabs(delta) > 0.0001) + return false; + + IppiBorderType ippiBorderType; + switch (borderType & (~BORDER_ISOLATED)) + { + case BORDER_REPLICATE: + ippiBorderType = (IppiBorderType)ippBorderRepl; + break; + case BORDER_REFLECT: + ippiBorderType = (IppiBorderType)ippBorderMirrorR; + break; + case BORDER_WRAP: + ippiBorderType = (IppiBorderType)ippBorderWrap; + break; + case BORDER_REFLECT_101: + ippiBorderType = (IppiBorderType)ippBorderMirror; + break; + default: + return false; + }; + + int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype); + if (ddepth < 0) + ddepth = sdepth; + int dtype = CV_MAKETYPE(ddepth, cn); + + Mat src = _src.getMat(); + if (0 == (BORDER_ISOLATED & borderType)) + { + Size size; Point offset; + src.locateROI(size, offset); + if (0 < offset.x) + ippiBorderType = (IppiBorderType)(ippiBorderType | ippBorderInMemLeft); + if (0 < offset.y) + ippiBorderType = (IppiBorderType)(ippiBorderType | ippBorderInMemTop); + if (offset.x + src.cols < size.width) + ippiBorderType = (IppiBorderType)(ippiBorderType | ippBorderInMemRight); + if (offset.y + src.rows < size.height) + ippiBorderType = (IppiBorderType)(ippiBorderType | ippBorderInMemBottom); + } + + bool horz = (0 == dx) && (1 == dy); + IppiSize roiSize = {src.cols, src.rows}; + + IppStatus sts = ippStsErr; + int bufferSize = 0; + ippiFilterScharrMaskBorder func = NULL; + if ((CV_8U == stype) && (CV_16S == dtype)) + { + if (horz) + { + sts = ippiFilterScharrHorizMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp8u, ipp16s, 1, &bufferSize); + func = (ippiFilterScharrMaskBorder)ippiFilterScharrHorizMaskBorder_8u16s_C1R; + } + else + { + sts = ippiFilterScharrVertMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp8u, ipp16s, 1, &bufferSize); + func = (ippiFilterScharrMaskBorder)ippiFilterScharrVertMaskBorder_8u16s_C1R; + } + } + else if ((CV_16S == stype) && (CV_16S == dtype)) + { + if (horz) + { + sts = ippiFilterScharrHorizMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp16s, ipp16s, 1, &bufferSize); + func = (ippiFilterScharrMaskBorder)ippiFilterScharrHorizMaskBorder_16s_C1R; + } + else + { + sts = ippiFilterScharrVertMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp16s, ipp16s, 1, &bufferSize); + func = (ippiFilterScharrMaskBorder)ippiFilterScharrVertMaskBorder_16s_C1R; + } + } + else if ((CV_32F == stype) && (CV_32F == dtype)) + { + if (horz) + { + sts = ippiFilterScharrHorizMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp32f, ipp32f, 1, &bufferSize); + func = (ippiFilterScharrMaskBorder)ippiFilterScharrHorizMaskBorder_32f_C1R; + } + else + { + sts = ippiFilterScharrVertMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp32f, ipp32f, 1, &bufferSize); + func = (ippiFilterScharrMaskBorder)ippiFilterScharrVertMaskBorder_32f_C1R; + } + } + if ((sts < 0) || (NULL == func)) + return false; -static bool IPPDerivScharr(const Mat& src, Mat& dst, int ddepth, int dx, int dy, double scale) + Ipp8u *pBuffer = ippsMalloc_8u(bufferSize); + if (NULL == pBuffer) + return false; + + _dst.create( _src.size(), dtype); + Mat dst = _dst.getMat(); + sts = func(src.data, (int)src.step, dst.data, (int)dst.step, roiSize, ippMskSize3x3, ippiBorderType, 0, pBuffer); + ippsFree(pBuffer); + if (0 > sts) + return false; + if ((CV_32F == dtype) && (0.0001 < fabs(scale - 1.0))) + ippiMulC_32f_C1R((Ipp32f *)dst.data, (int)dst.step, (Ipp32f)scale, (Ipp32f *)dst.data, (int)dst.step, roiSize); + return true; +} +#elif (IPP_VERSION_MAJOR >= 7) +static bool IPPDerivScharr(InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, double scale, double delta, int borderType) { + if (BORDER_REPLICATE != IppiBorderType) + return false; + if ((0 > dx) || (0 > dy) || (1 != dx + dy)) + return false; + if (fabs(delta) > 0.0001) + return false; + + Mat src = _src.getMat(), dst = _dst.getMat(); + int bufSize = 0; cv::AutoBuffer buffer; IppiSize roi = ippiSize(src.cols, src.rows); @@ -285,142 +404,143 @@ static bool IPPDerivScharr(const Mat& src, Mat& dst, int ddepth, int dx, int dy, return false; } } +#endif - -static bool IPPDeriv(const Mat& src, Mat& dst, int ddepth, int dx, int dy, int ksize, double scale) +static bool IPPDeriv(InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, int ksize, double scale, double delta) { - int stype = src.type(), dtype = dst.type(), bufSize = 0; + if (ksize != 3 || ksize != 5) + return false; + if (fabs(delta) > 0.0001) + return false; + + int bufSize = 0; cv::AutoBuffer buffer; - if (ksize == 3 || ksize == 5) + Mat src = _src.getMat(), dst = _dst.getMat(); + if ( ddepth < 0 ) + ddepth = src.depth(); + + if (src.type() == CV_8U && dst.type() == CV_16S && scale == 1) { - if (stype == CV_8UC1 && dtype == CV_16SC1 && scale == 1) + if ((dx == 1) && (dy == 0)) { - if (dx == 1 && dy == 0) - { - if (0 > ippiFilterSobelNegVertGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) - return false; - buffer.allocate(bufSize); + if (0 > ippiFilterSobelNegVertGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) + return false; + buffer.allocate(bufSize); - return 0 <= ippiFilterSobelNegVertBorder_8u16s_C1R((const Ipp8u*)src.data, (int)src.step, - (Ipp16s*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), - ippBorderRepl, 0, (Ipp8u*)(char*)buffer); - } + return (0 <= ippiFilterSobelNegVertBorder_8u16s_C1R((const Ipp8u*)src.data, (int)src.step, + (Ipp16s*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer)); + } - if (dx == 0 && dy == 1) - { - if (0 > ippiFilterSobelHorizGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) - return false; - buffer.allocate(bufSize); + if ((dx == 0) && (dy == 1)) + { + if (0 > ippiFilterSobelHorizGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) + return false; + buffer.allocate(bufSize); - return 0 <= ippiFilterSobelHorizBorder_8u16s_C1R((const Ipp8u*)src.data, (int)src.step, - (Ipp16s*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), - ippBorderRepl, 0, (Ipp8u*)(char*)buffer); - } + return (0 <= ippiFilterSobelHorizBorder_8u16s_C1R((const Ipp8u*)src.data, (int)src.step, + (Ipp16s*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer)); + } - if (dx == 2 && dy == 0) - { - if (0 > ippiFilterSobelVertSecondGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) - return false; - buffer.allocate(bufSize); + if ((dx == 2) && (dy == 0)) + { + if (0 > ippiFilterSobelVertSecondGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) + return false; + buffer.allocate(bufSize); - return 0 <= ippiFilterSobelVertSecondBorder_8u16s_C1R((const Ipp8u*)src.data, (int)src.step, - (Ipp16s*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), - ippBorderRepl, 0, (Ipp8u*)(char*)buffer); - } + return (0 <= ippiFilterSobelVertSecondBorder_8u16s_C1R((const Ipp8u*)src.data, (int)src.step, + (Ipp16s*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer)); + } - if (dx == 0 && dy == 2) - { - if (0 > ippiFilterSobelHorizSecondGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) - return false; - buffer.allocate(bufSize); + if ((dx == 0) && (dy == 2)) + { + if (0 > ippiFilterSobelHorizSecondGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) + return false; + buffer.allocate(bufSize); - return 0 <= ippiFilterSobelHorizSecondBorder_8u16s_C1R((const Ipp8u*)src.data, (int)src.step, - (Ipp16s*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), - ippBorderRepl, 0, (Ipp8u*)(char*)buffer); - } + return (0 <= ippiFilterSobelHorizSecondBorder_8u16s_C1R((const Ipp8u*)src.data, (int)src.step, + (Ipp16s*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer)); } + } - if (stype == CV_32FC1 && dtype == CV_32FC1) - { + if (src.type() == CV_32F && dst.type() == CV_32F) + { #if defined(HAVE_IPP_ICV_ONLY) // N/A: ippiMulC_32f_C1R - return false; + return false; #else #if 0 - if (dx == 1 && dy == 0) - { - if (0 > ippiFilterSobelNegVertGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), &bufSize)) - return false; - buffer.allocate(bufSize); + if ((dx == 1) && (dy == 0)) + { + if (0 > ippiFilterSobelNegVertGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), &bufSize)) + return false; + buffer.allocate(bufSize); - if (0 > ippiFilterSobelNegVertBorder_32f_C1R((const Ipp32f*)src.data, (int)src.step, - (Ipp32f*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), - ippBorderRepl, 0, (Ipp8u*)(char*)buffer)) - { - return false; - } - if(scale != 1) - ippiMulC_32f_C1R((Ipp32f *)dst.data, (int)dst.step, (Ipp32f)scale, (Ipp32f *)dst.data, (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows)); - return true; + if (0 > ippiFilterSobelNegVertBorder_32f_C1R((const Ipp32f*)src.data, (int)src.step, + (Ipp32f*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer)) + { + return false; } + if(scale != 1) + ippiMulC_32f_C1R((Ipp32f *)dst.data, (int)dst.step, (Ipp32f)scale, (Ipp32f *)dst.data, (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows)); + return true; + } - if (dx == 0 && dy == 1) + if ((dx == 0) && (dy == 1)) + { + if (0 > ippiFilterSobelHorizGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) + return false; + buffer.allocate(bufSize); + if (0 > ippiFilterSobelHorizBorder_32f_C1R((const Ipp32f*)src.data, (int)src.step, + (Ipp32f*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer)) { - if (0 > ippiFilterSobelHorizGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) - return false; - buffer.allocate(bufSize); - - if (0 > ippiFilterSobelHorizBorder_32f_C1R((const Ipp32f*)src.data, (int)src.step, - (Ipp32f*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), - ippBorderRepl, 0, (Ipp8u*)(char*)buffer)) - { - return false; - } - if(scale != 1) - ippiMulC_32f_C1R((Ipp32f *)dst.data, (int)dst.step, (Ipp32f)scale, (Ipp32f *)dst.data, (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows)); - return true; + return false; } + if(scale != 1) + ippiMulC_32f_C1R((Ipp32f *)dst.data, (int)dst.step, (Ipp32f)scale, (Ipp32f *)dst.data, (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows)); + return true; + } #endif + if((dx == 2) && (dy == 0)) + { + if (0 > ippiFilterSobelVertSecondGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) + return false; + buffer.allocate(bufSize); - if(dx == 2 && dy == 0) + if (0 > ippiFilterSobelVertSecondBorder_32f_C1R((const Ipp32f*)src.data, (int)src.step, + (Ipp32f*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer)) { - if (0 > ippiFilterSobelVertSecondGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) - return false; - buffer.allocate(bufSize); - - if (0 > ippiFilterSobelVertSecondBorder_32f_C1R((const Ipp32f*)src.data, (int)src.step, - (Ipp32f*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), - ippBorderRepl, 0, (Ipp8u*)(char*)buffer)) - { - return false; - } - if(scale != 1) - ippiMulC_32f_C1R((Ipp32f *)dst.data, (int)dst.step, (Ipp32f)scale, (Ipp32f *)dst.data, (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows)); - return true; + return false; } + if(scale != 1) + ippiMulC_32f_C1R((Ipp32f *)dst.data, (int)dst.step, (Ipp32f)scale, (Ipp32f *)dst.data, (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows)); + return true; + } - if(dx == 0 && dy == 2) - { - if (0 > ippiFilterSobelHorizSecondGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) - return false; - buffer.allocate(bufSize); - - if (0 > ippiFilterSobelHorizSecondBorder_32f_C1R((const Ipp32f*)src.data, (int)src.step, - (Ipp32f*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), - ippBorderRepl, 0, (Ipp8u*)(char*)buffer)) - { - return false; - } + if((dx == 0) && (dy == 2)) + { + if (0 > ippiFilterSobelHorizSecondGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize)) + return false; + buffer.allocate(bufSize); - if(scale != 1) - ippiMulC_32f_C1R((Ipp32f *)dst.data, (int)dst.step, (Ipp32f)scale, (Ipp32f *)dst.data, (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows)); - return true; + if (0 > ippiFilterSobelHorizSecondBorder_32f_C1R((const Ipp32f*)src.data, (int)src.step, + (Ipp32f*)dst.data, (int)dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize), + ippBorderRepl, 0, (Ipp8u*)(char*)buffer)) + { + return false; } -#endif + + if(scale != 1) + ippiMulC_32f_C1R((Ipp32f *)dst.data, (int)dst.step, (Ipp32f)scale, (Ipp32f *)dst.data, (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows)); + return true; } +#endif } - - if (ksize <= 0) - return IPPDerivScharr(src, dst, ddepth, dx, dy, scale); return false; } @@ -449,11 +569,14 @@ void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, #endif #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - if (dx < 3 && dy < 3 && cn == 1 && borderType == BORDER_REPLICATE && - ((stype == CV_8UC1 && dtype == CV_16SC1) || (stype == CV_32FC1 && dtype == CV_32FC1))) + if (ksize < 0) { - Mat src = _src.getMat(), dst = _dst.getMat(); - if (IPPDeriv(src, dst, ddepth, dx, dy, ksize,scale)) + if (IPPDerivScharr(_src, _dst, ddepth, dx, dy, scale, delta, borderType)) + return; + } + else if (0 < ksize && cn == 1 && borderType == BORDER_REPLICATE) + { + if (IPPDeriv(_src, _dst, ddepth, dx, dy, ksize, scale, delta)) return; } #endif @@ -493,14 +616,9 @@ void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, #endif #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - if(dx < 2 && dy < 2 && borderType == BORDER_REPLICATE && - ((stype == CV_8UC1 && dtype == CV_16SC1) || (stype == CV_32FC1 && dtype == CV_32FC1))) - { - Mat src = _src.getMat(), dst = _dst.getMat(); - if(IPPDerivScharr(src, dst, ddepth, dx, dy, scale)) - return; - setIppErrorStatus(); - } + if (IPPDerivScharr(_src, _dst, ddepth, dx, dy, scale, delta, borderType)) + return; + setIppErrorStatus(); #endif int ktype = std::max(CV_32F, std::max(ddepth, sdepth)); -- 2.7.4