📄 cvmorph.cpp
字号:
return element;
}
CV_IMPL void
cvReleaseStructuringElement( IplConvKernel ** element )
{
CV_FUNCNAME( "cvReleaseStructuringElement" );
__BEGIN__;
if( !element )
CV_ERROR( CV_StsNullPtr, "" );
cvFree( element );
__END__;
}
typedef CvStatus (CV_STDCALL * CvMorphRectGetBufSizeFunc_IPP)
( int width, CvSize el_size, int* bufsize );
typedef CvStatus (CV_STDCALL * CvMorphRectFunc_IPP)
( const void* src, int srcstep, void* dst, int dststep,
CvSize roi, CvSize el_size, CvPoint el_anchor, void* buffer );
typedef CvStatus (CV_STDCALL * CvMorphCustomInitAllocFunc_IPP)
( int width, const uchar* element, CvSize el_size,
CvPoint el_anchor, void** morphstate );
typedef CvStatus (CV_STDCALL * CvMorphCustomFunc_IPP)
( const void* src, int srcstep, void* dst, int dststep,
CvSize roi, int bordertype, void* morphstate );
static void
icvMorphOp( const void* srcarr, void* dstarr, IplConvKernel* element,
int iterations, int mop )
{
CvMorphology morphology;
void* buffer = 0;
int local_alloc = 0;
void* morphstate = 0;
CvMat* temp = 0;
CV_FUNCNAME( "icvMorphOp" );
__BEGIN__;
int i, coi1 = 0, coi2 = 0;
CvMat srcstub, *src = (CvMat*)srcarr;
CvMat dststub, *dst = (CvMat*)dstarr;
CvMat el_hdr, *el = 0;
CvSize size, el_size;
CvPoint el_anchor;
int el_shape;
int type;
bool inplace;
if( !CV_IS_MAT(src) )
CV_CALL( src = cvGetMat( src, &srcstub, &coi1 ));
if( src != &srcstub )
{
srcstub = *src;
src = &srcstub;
}
if( dstarr == srcarr )
dst = src;
else
{
CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 ));
if( !CV_ARE_TYPES_EQ( src, dst ))
CV_ERROR( CV_StsUnmatchedFormats, "" );
if( !CV_ARE_SIZES_EQ( src, dst ))
CV_ERROR( CV_StsUnmatchedSizes, "" );
}
if( dst != &dststub )
{
dststub = *dst;
dst = &dststub;
}
if( coi1 != 0 || coi2 != 0 )
CV_ERROR( CV_BadCOI, "" );
type = CV_MAT_TYPE( src->type );
size = cvGetMatSize( src );
inplace = src->data.ptr == dst->data.ptr;
if( iterations == 0 || (element && element->nCols == 1 && element->nRows == 1))
{
if( src->data.ptr != dst->data.ptr )
cvCopy( src, dst );
EXIT;
}
if( element )
{
el_size = cvSize( element->nCols, element->nRows );
el_anchor = cvPoint( element->anchorX, element->anchorY );
el_shape = (int)(element->nShiftR);
el_shape = el_shape < CV_SHAPE_CUSTOM ? el_shape : CV_SHAPE_CUSTOM;
}
else
{
el_size = cvSize(3,3);
el_anchor = cvPoint(1,1);
el_shape = CV_SHAPE_RECT;
}
if( el_shape == CV_SHAPE_RECT && iterations > 1 )
{
el_size.width += (el_size.width-1)*iterations;
el_size.height += (el_size.height-1)*iterations;
el_anchor.x *= iterations;
el_anchor.y *= iterations;
iterations = 1;
}
if( el_shape == CV_SHAPE_RECT && icvErodeRect_GetBufSize_8u_C1R_p )
{
CvMorphRectFunc_IPP rect_func = 0;
CvMorphRectGetBufSizeFunc_IPP rect_getbufsize_func = 0;
if( mop == 0 )
{
if( type == CV_8UC1 )
rect_getbufsize_func = icvErodeRect_GetBufSize_8u_C1R_p,
rect_func = icvErodeRect_8u_C1R_p;
else if( type == CV_8UC3 )
rect_getbufsize_func = icvErodeRect_GetBufSize_8u_C3R_p,
rect_func = icvErodeRect_8u_C3R_p;
else if( type == CV_8UC4 )
rect_getbufsize_func = icvErodeRect_GetBufSize_8u_C4R_p,
rect_func = icvErodeRect_8u_C4R_p;
else if( type == CV_32FC1 )
rect_getbufsize_func = icvErodeRect_GetBufSize_32f_C1R_p,
rect_func = icvErodeRect_32f_C1R_p;
else if( type == CV_32FC3 )
rect_getbufsize_func = icvErodeRect_GetBufSize_32f_C3R_p,
rect_func = icvErodeRect_32f_C3R_p;
else if( type == CV_32FC4 )
rect_getbufsize_func = icvErodeRect_GetBufSize_32f_C4R_p,
rect_func = icvErodeRect_32f_C4R_p;
}
else
{
if( type == CV_8UC1 )
rect_getbufsize_func = icvDilateRect_GetBufSize_8u_C1R_p,
rect_func = icvDilateRect_8u_C1R_p;
else if( type == CV_8UC3 )
rect_getbufsize_func = icvDilateRect_GetBufSize_8u_C3R_p,
rect_func = icvDilateRect_8u_C3R_p;
else if( type == CV_8UC4 )
rect_getbufsize_func = icvDilateRect_GetBufSize_8u_C4R_p,
rect_func = icvDilateRect_8u_C4R_p;
else if( type == CV_32FC1 )
rect_getbufsize_func = icvDilateRect_GetBufSize_32f_C1R_p,
rect_func = icvDilateRect_32f_C1R_p;
else if( type == CV_32FC3 )
rect_getbufsize_func = icvDilateRect_GetBufSize_32f_C3R_p,
rect_func = icvDilateRect_32f_C3R_p;
else if( type == CV_32FC4 )
rect_getbufsize_func = icvDilateRect_GetBufSize_32f_C4R_p,
rect_func = icvDilateRect_32f_C4R_p;
}
if( rect_getbufsize_func && rect_func )
{
int bufsize = 0;
CvStatus status = rect_getbufsize_func( size.width, el_size, &bufsize );
if( status >= 0 && bufsize > 0 )
{
if( bufsize < CV_MAX_LOCAL_SIZE )
{
buffer = cvStackAlloc( bufsize );
local_alloc = 1;
}
else
CV_CALL( buffer = cvAlloc( bufsize ));
}
if( status >= 0 )
{
int src_step, dst_step = dst->step ? dst->step : CV_STUB_STEP;
if( inplace )
{
CV_CALL( temp = cvCloneMat( dst ));
src = temp;
}
src_step = src->step ? src->step : CV_STUB_STEP;
status = rect_func( src->data.ptr, src_step, dst->data.ptr,
dst_step, size, el_size, el_anchor, buffer );
}
if( status >= 0 )
EXIT;
}
}
else if( el_shape == CV_SHAPE_CUSTOM && icvMorphInitAlloc_8u_C1R_p && icvMorphFree_p &&
src->data.ptr != dst->data.ptr )
{
CvMorphCustomFunc_IPP custom_func = 0;
CvMorphCustomInitAllocFunc_IPP custom_initalloc_func = 0;
const int bordertype = 1; // replication border
if( type == CV_8UC1 )
custom_initalloc_func = icvMorphInitAlloc_8u_C1R_p,
custom_func = mop == 0 ? icvErode_8u_C1R_p : icvDilate_8u_C1R_p;
else if( type == CV_8UC3 )
custom_initalloc_func = icvMorphInitAlloc_8u_C3R_p,
custom_func = mop == 0 ? icvErode_8u_C3R_p : icvDilate_8u_C3R_p;
else if( type == CV_8UC4 )
custom_initalloc_func = icvMorphInitAlloc_8u_C4R_p,
custom_func = mop == 0 ? icvErode_8u_C4R_p : icvDilate_8u_C4R_p;
else if( type == CV_32FC1 )
custom_initalloc_func = icvMorphInitAlloc_32f_C1R_p,
custom_func = mop == 0 ? icvErode_32f_C1R_p : icvDilate_32f_C1R_p;
else if( type == CV_32FC3 )
custom_initalloc_func = icvMorphInitAlloc_32f_C3R_p,
custom_func = mop == 0 ? icvErode_32f_C3R_p : icvDilate_32f_C3R_p;
else if( type == CV_32FC4 )
custom_initalloc_func = icvMorphInitAlloc_32f_C4R_p,
custom_func = mop == 0 ? icvErode_32f_C4R_p : icvDilate_32f_C4R_p;
if( custom_initalloc_func && custom_func )
{
uchar *src_ptr, *dst_ptr = dst->data.ptr;
int src_step, dst_step = dst->step ? dst->step : CV_STUB_STEP;
int el_len = el_size.width*el_size.height;
uchar* el_mask = (uchar*)cvStackAlloc( el_len );
CvStatus status;
for( i = 0; i < el_len; i++ )
el_mask[i] = (uchar)(element->values[i] != 0);
status = custom_initalloc_func( size.width, el_mask, el_size,
el_anchor, &morphstate );
if( status >= 0 && (inplace || iterations > 1) )
{
CV_CALL( temp = cvCloneMat( dst ));
src = temp;
}
src_ptr = src->data.ptr;
src_step = src->step ? src->step : CV_STUB_STEP;
for( i = 0; i < iterations && status >= 0 && morphstate; i++ )
{
uchar* t_ptr;
int t_step;
status = custom_func( src_ptr, src_step, dst_ptr, dst_step,
size, bordertype, morphstate );
CV_SWAP( src_ptr, dst_ptr, t_ptr );
CV_SWAP( src_step, dst_step, t_step );
if( i == 0 && temp )
{
dst_ptr = temp->data.ptr;
dst_step = temp->step ? temp->step : CV_STUB_STEP;
}
}
if( status >= 0 )
{
if( iterations % 2 == 0 )
cvCopy( temp, dst );
EXIT;
}
}
}
if( el_shape != CV_SHAPE_RECT )
{
el_hdr = cvMat( element->nRows, element->nCols, CV_32SC1, element->values );
el = &el_hdr;
el_shape = CV_SHAPE_CUSTOM;
}
CV_CALL( morphology.init( mop, src->cols, src->type,
el_shape, el, el_size, el_anchor ));
for( i = 0; i < iterations; i++ )
{
CV_CALL( morphology.process( src, dst ));
src = dst;
}
__END__;
if( !local_alloc )
cvFree( &buffer );
if( morphstate )
icvMorphFree_p( morphstate );
cvReleaseMat( &temp );
}
CV_IMPL void
cvErode( const void* src, void* dst, IplConvKernel* element, int iterations )
{
icvMorphOp( src, dst, element, iterations, 0 );
}
CV_IMPL void
cvDilate( const void* src, void* dst, IplConvKernel* element, int iterations )
{
icvMorphOp( src, dst, element, iterations, 1 );
}
CV_IMPL void
cvMorphologyEx( const void* src, void* dst,
void* temp, IplConvKernel* element, int op, int iterations )
{
CV_FUNCNAME( "cvMorhologyEx" );
__BEGIN__;
if( (op == CV_MOP_GRADIENT ||
(op == CV_MOP_TOPHAT || op == CV_MOP_BLACKHAT) && src == dst) && temp == 0 )
CV_ERROR( CV_HeaderIsNull, "temp image required" );
if( temp == src || temp == dst )
CV_ERROR( CV_HeaderIsNull, "temp image is equal to src or dst" );
switch (op)
{
case CV_MOP_OPEN:
CV_CALL( cvErode( src, dst, element, iterations ));
CV_CALL( cvDilate( dst, dst, element, iterations ));
break;
case CV_MOP_CLOSE:
CV_CALL( cvDilate( src, dst, element, iterations ));
CV_CALL( cvErode( dst, dst, element, iterations ));
break;
case CV_MOP_GRADIENT:
CV_CALL( cvErode( src, temp, element, iterations ));
CV_CALL( cvDilate( src, dst, element, iterations ));
CV_CALL( cvSub( dst, temp, dst ));
break;
case CV_MOP_TOPHAT:
if( src != dst )
temp = dst;
CV_CALL( cvErode( src, temp, element, iterations ));
CV_CALL( cvDilate( temp, temp, element, iterations ));
CV_CALL( cvSub( src, temp, dst ));
break;
case CV_MOP_BLACKHAT:
if( src != dst )
temp = dst;
CV_CALL( cvDilate( src, temp, element, iterations ));
CV_CALL( cvErode( temp, temp, element, iterations ));
CV_CALL( cvSub( temp, src, dst ));
break;
default:
CV_ERROR( CV_StsBadArg, "unknown morphological operation" );
}
__END__;
}
/* End of file. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -