mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 14:13:15 +08:00
Add IPP erosion and dilation
This commit is contained in:
parent
1a2458885b
commit
487ded8b27
@ -1136,11 +1136,397 @@ private:
|
|||||||
Scalar borderValue;
|
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,
|
static void morphOp( int op, InputArray _src, OutputArray _dst,
|
||||||
InputArray _kernel,
|
InputArray _kernel,
|
||||||
Point anchor, int iterations,
|
Point anchor, int iterations,
|
||||||
int borderType, const Scalar& borderValue )
|
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();
|
Mat src = _src.getMat(), kernel = _kernel.getMat();
|
||||||
Size ksize = kernel.data ? kernel.size() : Size(3,3);
|
Size ksize = kernel.data ? kernel.size() : Size(3,3);
|
||||||
anchor = normalizeAnchor(anchor, ksize);
|
anchor = normalizeAnchor(anchor, ksize);
|
||||||
|
Loading…
Reference in New Issue
Block a user