};
#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:
+ src.copyTo(temp);
+ _src = &temp;
+ }
+ //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:
{
- 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;
+ 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 CV_32F:
+ case MORPH_ERODE:
{
- 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;
+ 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 IPPErodeReplicate(const Mat &src, Mat &dst, const Mat &kernel, const Point &anchor)
+static bool IPPMorphOp(int &op, InputArray &_src, OutputArray &_dst,
+ InputArray &_kernel,
+ const Point &anchor, int &iterations,
+ int &borderType, const Scalar &borderValue)
{
- int cnn = src.channels();
- switch( src.depth() )
+ 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) )
{
- case CV_8U:
+ return false;
+ }
+ if( borderType == cv::BORDER_CONSTANT )
+ {
+ int x, y;
+ for( y = 0; y < kernel.rows; y++ )
{
- switch( cnn )
+ if( kernel.at<uchar>(y, anchor.x) != 0 )
{
- 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:
+ continue;
+ }
+ for( x = 0; x < kernel.cols; x++ )
+ {
+ if( kernel.at<uchar>(y,x) != 0 )
{
- 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;
+ return false;
}
}
- break;
}
- case CV_32F:
+ for( x = 0; y < kernel.cols; x++ )
{
- switch( cnn )
+ if( kernel.at<uchar>(anchor.y, x) != 0 )
{
- 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:
+ continue;
+ }
+ for( y = 0; y < kernel.rows; y++ )
+ {
+ if( kernel.at<uchar>(y,x) != 0 )
{
- 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;
+ return false;
}
}
- 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);
+ Point normanchor = normalizeAnchor(anchor, ksize);
- CV_Assert( normanchor.inside(Rect(0, 0, ksize.width, ksize.height)) );
+ CV_Assert( normanchor.inside(Rect(0, 0, ksize.width, ksize.height)) );
- _dst.create( src.size(), src.type() );
- Mat dst = _dst.getMat();
+ _dst.create( src.size(), src.type() );
+ Mat dst = _dst.getMat();
- if( iterations == 0 || kernel.rows*kernel.cols == 1 )
- {
- src.copyTo(dst);
- return true;
- }
+ 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 )
+ if( !kernel.data )
{
- case MORPH_DILATE:
- {
- return IPPDilateReplicate( src, dst, kernel, normanchor );
- }
- case MORPH_ERODE:
- {
- return IPPErodeReplicate( src, dst, kernel, normanchor );
- }
+ kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2));
+ normanchor = Point(iterations, iterations);
+ iterations = 1;
}
- return false;
+ 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
{
#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;
}