|
|
|
@ -1137,380 +1137,152 @@ 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: |
|
|
|
|
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 |
|
|
|
|
|
|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
|