Commit 94bc4c44 authored by kdrobnyh's avatar kdrobnyh

Some changes in erosion and dilation functions

parent 487ded8b
...@@ -1137,338 +1137,120 @@ private: ...@@ -1137,338 +1137,120 @@ private:
}; };
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) #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(); int type = src.type();
switch( src.depth() ) const Mat* _src = &src;
{ Mat temp;
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 ) if( src.data == dst.data )
{ {
ippiFree(data); src.copyTo(temp);
} _src = &temp;
return true; }
} //DEPRECATED. Allocates and initializes morphology state structure for erosion or dilation operation.
case 4: typedef IppStatus (CV_STDCALL* ippiMorphologyInitAllocFunc)(int, const void*, IppiSize, IppiPoint, IppiMorphState **);
{ ippiMorphologyInitAllocFunc ippInitAllocFunc =
IppiSize roiSize = {src.cols, src.rows}; type == CV_8UC1 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_8u_C1R :
Ipp8u *data = (Ipp8u *)src.data; type == CV_8UC3 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_8u_C3R :
int step = src.step; type == CV_8UC4 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_8u_C4R :
if( src.data == dst.data ) 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 )
{ {
Ipp8u *temp = ippiMalloc_8u_C4( src.cols, src.rows, &step ); case MORPH_DILATE:
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); ippFunc =
} type == CV_8UC1 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_8u_C1R :
return true; 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; 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); 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;
} }
return true;
} }
case 3: if( ippFunc && ippInitAllocFunc)
{ {
IppiMorphState* pState;
IppiSize roiSize = {src.cols, src.rows}; 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}; IppiSize kernelSize = {kernel.cols, kernel.rows};
IppiPoint point = {anchor.x, anchor.y}; IppiPoint point = {anchor.x, anchor.y};
ippiMorphologyInitAlloc_32f_C3R( roiSize.width, (Ipp8u *)kernel.data, kernelSize, point, &ppState ); if( ippInitAllocFunc( roiSize.width, kernel.data, kernelSize, point, &pState ) < 0 )
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 ); return false;
ippiCopy_32f_C4R( (Ipp32f *)src.data, src.step, temp, step, roiSize );
data = temp;
} }
IppiMorphState* ppState; if( ippFunc( _src->data, _src->step[0], dst.data, dst.step[0], roiSize, ippBorderRepl, pState ) < 0 )
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); ippiMorphologyFree(pState);
return false;
} }
ippiMorphologyFree(pState);
return true; return true;
} }
}
break;
}
}
return false; 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(); Mat src = _src.getMat(), kernel = _kernel.getMat();
switch( src.depth() ) if( !( src.depth() == CV_8U || src.depth() == CV_32F ) || ( iterations > 1 ) ||
{ !( borderType == cv::BORDER_REPLICATE || (borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue()) )
case CV_8U: || !( op == MORPH_DILATE || op == MORPH_ERODE) )
{
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 false;
}
return true;
} }
case 3: if( borderType == cv::BORDER_CONSTANT )
{ {
IppiSize roiSize = {src.cols, src.rows}; int x, y;
Ipp8u *data = (Ipp8u *)src.data; for( y = 0; y < kernel.rows; y++ )
int step = src.step;
if( src.data == dst.data )
{ {
Ipp8u *temp = ippiMalloc_8u_C3( src.cols, src.rows, &step ); if( kernel.at<uchar>(y, anchor.x) != 0 )
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); continue;
} }
return true; for( x = 0; x < kernel.cols; x++ )
}
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 ); if( kernel.at<uchar>(y,x) != 0 )
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 false;
}
return true;
} }
} }
break;
} }
case CV_32F: for( x = 0; y < kernel.cols; x++ )
{
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 ); if( kernel.at<uchar>(anchor.y, x) != 0 )
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); continue;
}
return true;
} }
case 3: for( y = 0; y < kernel.rows; y++ )
{ {
IppiSize roiSize = {src.cols, src.rows}; if( kernel.at<uchar>(y,x) != 0 )
Ipp32f *data = (Ipp32f *)src.data;
int step = src.step;
if( src.data == dst.data )
{ {
Ipp32f *temp = ippiMalloc_32f_C3( src.cols, src.rows, &step ); return false;
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); Size ksize = kernel.data ? kernel.size() : Size(3,3);
Point normanchor = normalizeAnchor(anchor, ksize); Point normanchor = normalizeAnchor(anchor, ksize);
...@@ -1499,18 +1281,8 @@ static bool IPPMorphOp(int op, InputArray _src, OutputArray _dst, ...@@ -1499,18 +1281,8 @@ static bool IPPMorphOp(int op, InputArray _src, OutputArray _dst,
normanchor); normanchor);
iterations = 1; iterations = 1;
} }
switch( op )
{ return IPPMorphReplicate( op, src, dst, kernel, normanchor );
case MORPH_DILATE:
{
return IPPDilateReplicate( src, dst, kernel, normanchor );
}
case MORPH_ERODE:
{
return IPPErodeReplicate( src, dst, kernel, normanchor );
}
}
return false;
} }
#endif #endif
...@@ -1521,7 +1293,7 @@ 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 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; return;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment