From 487ded8b27d6cf2f9e59d08580846aed2ea5d87c Mon Sep 17 00:00:00 2001 From: kdrobnyh Date: Tue, 16 Jul 2013 22:35:16 +0400 Subject: [PATCH 1/3] Add IPP erosion and dilation --- modules/imgproc/src/morph.cpp | 386 ++++++++++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) diff --git a/modules/imgproc/src/morph.cpp b/modules/imgproc/src/morph.cpp index 53d2347ec..0567c4884 100644 --- a/modules/imgproc/src/morph.cpp +++ b/modules/imgproc/src/morph.cpp @@ -1136,11 +1136,397 @@ private: Scalar borderValue; }; +#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) +static bool IPPDilateReplicate(const Mat &src, Mat &dst, const Mat &kernel, const Point &anchor) +{ + int cnn = src.channels(); + switch( src.depth() ) + { + case CV_8U: + { + switch( cnn ) + { + case 1: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp8u *data = (Ipp8u *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp8u *temp = ippiMalloc_8u_C1( src.cols, src.rows, &step ); + ippiCopy_8u_C1R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_8u_C1R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiDilateBorderReplicate_8u_C1R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + case 3: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp8u *data = (Ipp8u *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp8u *temp = ippiMalloc_8u_C3( src.cols, src.rows, &step ); + ippiCopy_8u_C3R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_8u_C3R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiDilateBorderReplicate_8u_C3R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + case 4: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp8u *data = (Ipp8u *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp8u *temp = ippiMalloc_8u_C4( src.cols, src.rows, &step ); + ippiCopy_8u_C4R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_8u_C4R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiDilateBorderReplicate_8u_C4R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + } + break; + } + case CV_32F: + { + switch( cnn ) + { + case 1: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp32f *data = (Ipp32f *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp32f *temp = ippiMalloc_32f_C1( src.cols, src.rows, &step ); + ippiCopy_32f_C1R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_32f_C1R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiDilateBorderReplicate_32f_C1R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + case 3: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp32f *data = (Ipp32f *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp32f *temp = ippiMalloc_32f_C3( src.cols, src.rows, &step ); + ippiCopy_32f_C3R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_32f_C3R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiDilateBorderReplicate_32f_C3R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + case 4: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp32f *data = (Ipp32f *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp32f *temp = ippiMalloc_32f_C4( src.cols, src.rows, &step ); + ippiCopy_32f_C4R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_32f_C4R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiDilateBorderReplicate_32f_C4R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + } + break; + } + } + return false; +} + +static bool IPPErodeReplicate(const Mat &src, Mat &dst, const Mat &kernel, const Point &anchor) +{ + int cnn = src.channels(); + switch( src.depth() ) + { + case CV_8U: + { + switch( cnn ) + { + case 1: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp8u *data = (Ipp8u *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp8u *temp = ippiMalloc_8u_C1( src.cols, src.rows, &step ); + ippiCopy_8u_C1R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_8u_C1R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiErodeBorderReplicate_8u_C1R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + case 3: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp8u *data = (Ipp8u *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp8u *temp = ippiMalloc_8u_C3( src.cols, src.rows, &step ); + ippiCopy_8u_C3R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_8u_C3R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiErodeBorderReplicate_8u_C3R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + case 4: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp8u *data = (Ipp8u *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp8u *temp = ippiMalloc_8u_C4( src.cols, src.rows, &step ); + ippiCopy_8u_C4R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_8u_C4R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiErodeBorderReplicate_8u_C4R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + } + break; + } + case CV_32F: + { + switch( cnn ) + { + case 1: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp32f *data = (Ipp32f *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp32f *temp = ippiMalloc_32f_C1( src.cols, src.rows, &step ); + ippiCopy_32f_C1R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_32f_C1R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiErodeBorderReplicate_32f_C1R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + case 3: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp32f *data = (Ipp32f *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp32f *temp = ippiMalloc_32f_C3( src.cols, src.rows, &step ); + ippiCopy_32f_C3R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_32f_C3R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiErodeBorderReplicate_32f_C3R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + case 4: + { + IppiSize roiSize = {src.cols, src.rows}; + Ipp32f *data = (Ipp32f *)src.data; + int step = src.step; + if( src.data == dst.data ) + { + Ipp32f *temp = ippiMalloc_32f_C4( src.cols, src.rows, &step ); + ippiCopy_32f_C4R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); + data = temp; + } + IppiMorphState* ppState; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + ippiMorphologyInitAlloc_32f_C4R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); + ippiErodeBorderReplicate_32f_C4R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); + ippiMorphologyFree(ppState); + if( src.data == dst.data ) + { + ippiFree(data); + } + return true; + } + } + break; + } + } + return false; +} + +static bool IPPMorphOp(int op, InputArray _src, OutputArray _dst, + InputArray _kernel, + Point anchor, int iterations, + int borderType) +{ + Mat src = _src.getMat(), kernel = _kernel.getMat(); + if( !(src.depth() == CV_8U || src.depth() == CV_32F) || (iterations > 1) || + (borderType != cv::BORDER_REPLICATE) || !( op == MORPH_DILATE || op == MORPH_ERODE) ) + { + return false; + } + Size ksize = kernel.data ? kernel.size() : Size(3,3); + Point normanchor = normalizeAnchor(anchor, ksize); + + CV_Assert( normanchor.inside(Rect(0, 0, ksize.width, ksize.height)) ); + + _dst.create( src.size(), src.type() ); + Mat dst = _dst.getMat(); + + if( iterations == 0 || kernel.rows*kernel.cols == 1 ) + { + src.copyTo(dst); + return true; + } + + if( !kernel.data ) + { + kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2)); + normanchor = Point(iterations, iterations); + iterations = 1; + } + else if( iterations > 1 && countNonZero(kernel) == kernel.rows*kernel.cols ) + { + normanchor = Point(normanchor.x*iterations, normanchor.y*iterations); + kernel = getStructuringElement(MORPH_RECT, + Size(ksize.width + (iterations-1)*(ksize.width-1), + ksize.height + (iterations-1)*(ksize.height-1)), + normanchor); + iterations = 1; + } + switch( op ) + { + case MORPH_DILATE: + { + return IPPDilateReplicate( src, dst, kernel, normanchor ); + } + case MORPH_ERODE: + { + return IPPErodeReplicate( src, dst, kernel, normanchor ); + } + } + return false; +} +#endif + static void morphOp( int op, InputArray _src, OutputArray _dst, InputArray _kernel, Point anchor, int iterations, int borderType, const Scalar& borderValue ) { + +#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) + if (IPPMorphOp(op, _src, _dst, _kernel, anchor, iterations, borderType)) + { + return; + } +#endif + Mat src = _src.getMat(), kernel = _kernel.getMat(); Size ksize = kernel.data ? kernel.size() : Size(3,3); anchor = normalizeAnchor(anchor, ksize); From 94bc4c4429c6d0cc6d132520f2101c705047812a Mon Sep 17 00:00:00 2001 From: kdrobnyh Date: Tue, 30 Jul 2013 15:13:04 +0400 Subject: [PATCH 2/3] Some changes in erosion and dilation functions --- modules/imgproc/src/morph.cpp | 496 +++++++++------------------------- 1 file changed, 134 insertions(+), 362 deletions(-) diff --git a/modules/imgproc/src/morph.cpp b/modules/imgproc/src/morph.cpp index 0567c4884..df3f04b0e 100644 --- a/modules/imgproc/src/morph.cpp +++ b/modules/imgproc/src/morph.cpp @@ -1137,381 +1137,153 @@ private: }; #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) -static bool IPPDilateReplicate(const Mat &src, Mat &dst, const Mat &kernel, const Point &anchor) +static bool IPPMorphReplicate(int &op, const Mat &src, Mat &dst, const Mat &kernel, const Point &anchor) { - int cnn = src.channels(); - switch( src.depth() ) + int type = src.type(); + const Mat* _src = &src; + Mat temp; + if( src.data == dst.data ) { - case CV_8U: - { - switch( cnn ) - { - case 1: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp8u *data = (Ipp8u *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp8u *temp = ippiMalloc_8u_C1( src.cols, src.rows, &step ); - ippiCopy_8u_C1R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_8u_C1R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiDilateBorderReplicate_8u_C1R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - case 3: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp8u *data = (Ipp8u *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp8u *temp = ippiMalloc_8u_C3( src.cols, src.rows, &step ); - ippiCopy_8u_C3R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_8u_C3R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiDilateBorderReplicate_8u_C3R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - case 4: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp8u *data = (Ipp8u *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp8u *temp = ippiMalloc_8u_C4( src.cols, src.rows, &step ); - ippiCopy_8u_C4R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_8u_C4R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiDilateBorderReplicate_8u_C4R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - } - break; - } - case CV_32F: - { - switch( cnn ) - { - case 1: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp32f *data = (Ipp32f *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp32f *temp = ippiMalloc_32f_C1( src.cols, src.rows, &step ); - ippiCopy_32f_C1R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_32f_C1R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiDilateBorderReplicate_32f_C1R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - case 3: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp32f *data = (Ipp32f *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp32f *temp = ippiMalloc_32f_C3( src.cols, src.rows, &step ); - ippiCopy_32f_C3R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_32f_C3R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiDilateBorderReplicate_32f_C3R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - case 4: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp32f *data = (Ipp32f *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp32f *temp = ippiMalloc_32f_C4( src.cols, src.rows, &step ); - ippiCopy_32f_C4R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_32f_C4R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiDilateBorderReplicate_32f_C4R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - } - break; - } + src.copyTo(temp); + _src = &temp; } - return false; -} - -static bool IPPErodeReplicate(const Mat &src, Mat &dst, const Mat &kernel, const Point &anchor) -{ - int cnn = src.channels(); - switch( src.depth() ) - { - case CV_8U: - { - switch( cnn ) - { - case 1: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp8u *data = (Ipp8u *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp8u *temp = ippiMalloc_8u_C1( src.cols, src.rows, &step ); - ippiCopy_8u_C1R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_8u_C1R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiErodeBorderReplicate_8u_C1R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - case 3: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp8u *data = (Ipp8u *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp8u *temp = ippiMalloc_8u_C3( src.cols, src.rows, &step ); - ippiCopy_8u_C3R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_8u_C3R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiErodeBorderReplicate_8u_C3R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - case 4: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp8u *data = (Ipp8u *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp8u *temp = ippiMalloc_8u_C4( src.cols, src.rows, &step ); - ippiCopy_8u_C4R( (Ipp8u *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_8u_C4R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiErodeBorderReplicate_8u_C4R( data, step, (Ipp8u *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - } - break; - } - case CV_32F: - { - switch( cnn ) - { - case 1: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp32f *data = (Ipp32f *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp32f *temp = ippiMalloc_32f_C1( src.cols, src.rows, &step ); - ippiCopy_32f_C1R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_32f_C1R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiErodeBorderReplicate_32f_C1R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - case 3: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp32f *data = (Ipp32f *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp32f *temp = ippiMalloc_32f_C3( src.cols, src.rows, &step ); - ippiCopy_32f_C3R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_32f_C3R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiErodeBorderReplicate_32f_C3R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - case 4: - { - IppiSize roiSize = {src.cols, src.rows}; - Ipp32f *data = (Ipp32f *)src.data; - int step = src.step; - if( src.data == dst.data ) - { - Ipp32f *temp = ippiMalloc_32f_C4( src.cols, src.rows, &step ); - ippiCopy_32f_C4R( (Ipp32f *)src.data, src.step, temp, step, roiSize ); - data = temp; - } - IppiMorphState* ppState; - IppiSize kernelSize = {kernel.cols, kernel.rows}; - IppiPoint point = {anchor.x, anchor.y}; - ippiMorphologyInitAlloc_32f_C4R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); - ippiErodeBorderReplicate_32f_C4R( data, step, (Ipp32f *)dst.data, dst.step, roiSize, ippBorderRepl, ppState ); - ippiMorphologyFree(ppState); - if( src.data == dst.data ) - { - ippiFree(data); - } - return true; - } - } - break; - } - } - return false; -} - -static bool IPPMorphOp(int op, InputArray _src, OutputArray _dst, - InputArray _kernel, - Point anchor, int iterations, - int borderType) -{ - Mat src = _src.getMat(), kernel = _kernel.getMat(); - if( !(src.depth() == CV_8U || src.depth() == CV_32F) || (iterations > 1) || - (borderType != cv::BORDER_REPLICATE) || !( op == MORPH_DILATE || op == MORPH_ERODE) ) - { - return false; - } - Size ksize = kernel.data ? kernel.size() : Size(3,3); - Point normanchor = normalizeAnchor(anchor, ksize); - - CV_Assert( normanchor.inside(Rect(0, 0, ksize.width, ksize.height)) ); - - _dst.create( src.size(), src.type() ); - Mat dst = _dst.getMat(); - - if( iterations == 0 || kernel.rows*kernel.cols == 1 ) - { - src.copyTo(dst); - return true; - } - - if( !kernel.data ) - { - kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2)); - normanchor = Point(iterations, iterations); - iterations = 1; - } - else if( iterations > 1 && countNonZero(kernel) == kernel.rows*kernel.cols ) - { - normanchor = Point(normanchor.x*iterations, normanchor.y*iterations); - kernel = getStructuringElement(MORPH_RECT, - Size(ksize.width + (iterations-1)*(ksize.width-1), - ksize.height + (iterations-1)*(ksize.height-1)), - normanchor); - iterations = 1; - } + //DEPRECATED. Allocates and initializes morphology state structure for erosion or dilation operation. + typedef IppStatus (CV_STDCALL* ippiMorphologyInitAllocFunc)(int, const void*, IppiSize, IppiPoint, IppiMorphState **); + ippiMorphologyInitAllocFunc ippInitAllocFunc = + type == CV_8UC1 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_8u_C1R : + type == CV_8UC3 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_8u_C3R : + type == CV_8UC4 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_8u_C4R : + type == CV_32FC1 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_32f_C1R : + type == CV_32FC3 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_32f_C3R : + type == CV_32FC4 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_32f_C4R : + 0; + typedef IppStatus (CV_STDCALL* ippiMorphologyBorderReplicateFunc)(const void*, int, void *, int, IppiSize, IppiBorderType, IppiMorphState *); + ippiMorphologyBorderReplicateFunc ippFunc = 0; switch( op ) { case MORPH_DILATE: { - return IPPDilateReplicate( src, dst, kernel, normanchor ); + ippFunc = + type == CV_8UC1 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_8u_C1R : + type == CV_8UC3 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_8u_C3R : + type == CV_8UC4 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_8u_C4R : + type == CV_32FC1 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_32f_C1R : + type == CV_32FC3 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_32f_C3R : + type == CV_32FC4 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_32f_C4R : + 0; + break; } case MORPH_ERODE: { - return IPPErodeReplicate( src, dst, kernel, normanchor ); + ippFunc = + type == CV_8UC1 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_8u_C1R : + type == CV_8UC3 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_8u_C3R : + type == CV_8UC4 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_8u_C4R : + type == CV_32FC1 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_32f_C1R : + type == CV_32FC3 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_32f_C3R : + type == CV_32FC4 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_32f_C4R : + 0; + break; } } + if( ippFunc && ippInitAllocFunc) + { + IppiMorphState* pState; + IppiSize roiSize = {src.cols, src.rows}; + IppiSize kernelSize = {kernel.cols, kernel.rows}; + IppiPoint point = {anchor.x, anchor.y}; + if( ippInitAllocFunc( roiSize.width, kernel.data, kernelSize, point, &pState ) < 0 ) + { + return false; + } + if( ippFunc( _src->data, _src->step[0], dst.data, dst.step[0], roiSize, ippBorderRepl, pState ) < 0 ) + { + ippiMorphologyFree(pState); + return false; + } + ippiMorphologyFree(pState); + return true; + } return false; } + +static bool IPPMorphOp(int &op, InputArray &_src, OutputArray &_dst, + InputArray &_kernel, + const Point &anchor, int &iterations, + int &borderType, const Scalar &borderValue) +{ + Mat src = _src.getMat(), kernel = _kernel.getMat(); + if( !( src.depth() == CV_8U || src.depth() == CV_32F ) || ( iterations > 1 ) || + !( borderType == cv::BORDER_REPLICATE || (borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue()) ) + || !( op == MORPH_DILATE || op == MORPH_ERODE) ) + { + return false; + } + if( borderType == cv::BORDER_CONSTANT ) + { + int x, y; + for( y = 0; y < kernel.rows; y++ ) + { + if( kernel.at(y, anchor.x) != 0 ) + { + continue; + } + for( x = 0; x < kernel.cols; x++ ) + { + if( kernel.at(y,x) != 0 ) + { + return false; + } + } + } + for( x = 0; y < kernel.cols; x++ ) + { + if( kernel.at(anchor.y, x) != 0 ) + { + continue; + } + for( y = 0; y < kernel.rows; y++ ) + { + if( kernel.at(y,x) != 0 ) + { + return false; + } + } + } + + } + Size ksize = kernel.data ? kernel.size() : Size(3,3); + Point normanchor = normalizeAnchor(anchor, ksize); + + CV_Assert( normanchor.inside(Rect(0, 0, ksize.width, ksize.height)) ); + + _dst.create( src.size(), src.type() ); + Mat dst = _dst.getMat(); + + if( iterations == 0 || kernel.rows*kernel.cols == 1 ) + { + src.copyTo(dst); + return true; + } + + if( !kernel.data ) + { + kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2)); + normanchor = Point(iterations, iterations); + iterations = 1; + } + else if( iterations > 1 && countNonZero(kernel) == kernel.rows*kernel.cols ) + { + normanchor = Point(normanchor.x*iterations, normanchor.y*iterations); + kernel = getStructuringElement(MORPH_RECT, + Size(ksize.width + (iterations-1)*(ksize.width-1), + ksize.height + (iterations-1)*(ksize.height-1)), + normanchor); + iterations = 1; + } + + return IPPMorphReplicate( op, src, dst, kernel, normanchor ); +} #endif static void morphOp( int op, InputArray _src, OutputArray _dst, @@ -1521,7 +1293,7 @@ static void morphOp( int op, InputArray _src, OutputArray _dst, { #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - if (IPPMorphOp(op, _src, _dst, _kernel, anchor, iterations, borderType)) + if( IPPMorphOp(op, _src, _dst, _kernel, anchor, iterations, borderType, borderValue) ) { return; } From 7da5fa01d43bf1ab5c18ed70a84af0ce38124471 Mon Sep 17 00:00:00 2001 From: kdrobnyh Date: Thu, 8 Aug 2013 12:30:28 +0400 Subject: [PATCH 3/3] Removed extra {} in erosion and dilation functions --- modules/imgproc/src/morph.cpp | 36 +++++++++-------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/modules/imgproc/src/morph.cpp b/modules/imgproc/src/morph.cpp index df3f04b0e..fb901b726 100644 --- a/modules/imgproc/src/morph.cpp +++ b/modules/imgproc/src/morph.cpp @@ -1137,7 +1137,7 @@ private: }; #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) -static bool IPPMorphReplicate(int &op, const Mat &src, Mat &dst, const Mat &kernel, const Point &anchor) +static bool IPPMorphReplicate(int op, const Mat &src, Mat &dst, const Mat &kernel, const Point &anchor) { int type = src.type(); const Mat* _src = &src; @@ -1171,7 +1171,7 @@ static bool IPPMorphReplicate(int &op, const Mat &src, Mat &dst, const Mat &kern type == CV_32FC3 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_32f_C3R : type == CV_32FC4 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_32f_C4R : 0; - break; + break; } case MORPH_ERODE: { @@ -1183,7 +1183,7 @@ static bool IPPMorphReplicate(int &op, const Mat &src, Mat &dst, const Mat &kern type == CV_32FC3 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_32f_C3R : type == CV_32FC4 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_32f_C4R : 0; - break; + break; } } if( ippFunc && ippInitAllocFunc) @@ -1193,61 +1193,45 @@ static bool IPPMorphReplicate(int &op, const Mat &src, Mat &dst, const Mat &kern IppiSize kernelSize = {kernel.cols, kernel.rows}; IppiPoint point = {anchor.x, anchor.y}; if( ippInitAllocFunc( roiSize.width, kernel.data, kernelSize, point, &pState ) < 0 ) - { return false; - } - if( ippFunc( _src->data, _src->step[0], dst.data, dst.step[0], roiSize, ippBorderRepl, pState ) < 0 ) - { - ippiMorphologyFree(pState); - return false; - } + bool is_ok = ippFunc( _src->data, _src->step[0], dst.data, dst.step[0], roiSize, ippBorderRepl, pState ) >= 0; ippiMorphologyFree(pState); - return true; + return is_ok; } return false; } -static bool IPPMorphOp(int &op, InputArray &_src, OutputArray &_dst, - InputArray &_kernel, - const Point &anchor, int &iterations, - int &borderType, const Scalar &borderValue) +static bool IPPMorphOp(int op, InputArray _src, OutputArray _dst, + InputArray _kernel, + const Point &anchor, int iterations, + int borderType, const Scalar &borderValue) { Mat src = _src.getMat(), kernel = _kernel.getMat(); if( !( src.depth() == CV_8U || src.depth() == CV_32F ) || ( iterations > 1 ) || !( borderType == cv::BORDER_REPLICATE || (borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue()) ) || !( op == MORPH_DILATE || op == MORPH_ERODE) ) - { return false; - } if( borderType == cv::BORDER_CONSTANT ) { int x, y; for( y = 0; y < kernel.rows; y++ ) { if( kernel.at(y, anchor.x) != 0 ) - { continue; - } for( x = 0; x < kernel.cols; x++ ) { if( kernel.at(y,x) != 0 ) - { return false; - } } } for( x = 0; y < kernel.cols; x++ ) { if( kernel.at(anchor.y, x) != 0 ) - { continue; - } for( y = 0; y < kernel.rows; y++ ) { if( kernel.at(y,x) != 0 ) - { return false; - } } } @@ -1294,9 +1278,7 @@ static void morphOp( int op, InputArray _src, OutputArray _dst, #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) if( IPPMorphOp(op, _src, _dst, _kernel, anchor, iterations, borderType, borderValue) ) - { return; - } #endif Mat src = _src.getMat(), kernel = _kernel.getMat();