📄 cvmorph.cpp
字号:
if( anchor.y == -1 )
anchor.y = element->rows/2;
if( (unsigned)anchor.x >= (unsigned)element->cols ||
(unsigned)anchor.y >= (unsigned)element->rows )
CV_ERROR( CV_StsOutOfRange, "anchor is outside of element" );
if( element_shape != RECT && element_shape != CROSS && element_shape != ELLIPSE )
CV_ERROR( CV_StsBadArg, "Unknown/unsupported element shape" );
rows = element->rows;
cols = element->cols;
if( rows == 1 || cols == 1 )
element_shape = RECT;
if( element_shape == ELLIPSE )
{
r = rows/2;
c = cols/2;
inv_r2 = r ? 1./((double)r*r) : 0;
}
for( i = 0; i < rows; i++ )
{
uchar* ptr = element->data.ptr + i*element->step;
int j1 = 0, j2 = 0, jx, t = 0;
if( element_shape == RECT || element_shape == CROSS && i == anchor.y )
j2 = cols;
else if( element_shape == CROSS )
j1 = anchor.x, j2 = j1 + 1;
else
{
int dy = i - r;
if( abs(dy) <= r )
{
int dx = cvRound(c*sqrt(((double)r*r - dy*dy)*inv_r2));
j1 = MAX( c - dx, 0 );
j2 = MIN( c + dx + 1, cols );
}
}
for( j = 0, jx = j1; j < cols; )
{
for( ; j < jx; j++ )
{
if( type == CV_8UC1 )
ptr[j] = (uchar)t;
else
((int*)ptr)[j] = t;
}
if( jx == j2 )
jx = cols, t = 0;
else
jx = j2, t = 1;
}
}
__END__;
}
#define ICV_MORPH_RECT_ROW( name, flavor, arrtype, \
worktype, update_extr_macro ) \
static void \
icv##name##RectRow_##flavor( const arrtype* src, \
arrtype* dst, void* params ) \
{ \
const CvMorphology* state = (const CvMorphology*)params;\
int ksize = state->get_kernel_size().width; \
int width = state->get_width(); \
int cn = CV_MAT_CN(state->get_src_type()); \
int i, j, k; \
\
width *= cn; ksize *= cn; \
\
if( ksize == cn ) \
{ \
for( i = 0; i < width; i++ ) \
dst[i] = src[i]; \
return; \
} \
\
for( k = 0; k < cn; k++, src++, dst++ ) \
{ \
for( i = 0; i <= width - cn*2; i += cn*2 ) \
{ \
const arrtype* s = src + i; \
worktype m = s[cn], t; \
for( j = cn*2; j < ksize; j += cn ) \
{ \
t = s[j]; update_extr_macro(m,t); \
} \
t = s[0]; update_extr_macro(t,m); \
dst[i] = (arrtype)t; \
t = s[j]; update_extr_macro(t,m); \
dst[i+cn] = (arrtype)t; \
} \
\
for( ; i < width; i += cn ) \
{ \
const arrtype* s = src + i; \
worktype m = s[0], t; \
for( j = cn; j < ksize; j += cn ) \
{ \
t = s[j]; update_extr_macro(m,t); \
} \
dst[i] = (arrtype)m; \
} \
} \
}
ICV_MORPH_RECT_ROW( Erode, 8u, uchar, int, CV_CALC_MIN_8U )
ICV_MORPH_RECT_ROW( Dilate, 8u, uchar, int, CV_CALC_MAX_8U )
ICV_MORPH_RECT_ROW( Erode, 32f, int, int, CV_CALC_MIN )
ICV_MORPH_RECT_ROW( Dilate, 32f, int, int, CV_CALC_MAX )
#define ICV_MORPH_RECT_COL( name, flavor, arrtype, \
worktype, update_extr_macro, toggle_macro ) \
static void \
icv##name##RectCol_##flavor( const arrtype** src, \
arrtype* dst, int dst_step, int count, void* params ) \
{ \
const CvMorphology* state = (const CvMorphology*)params;\
int ksize = state->get_kernel_size().height; \
int width = state->get_width(); \
int cn = CV_MAT_CN(state->get_src_type()); \
int i, k; \
\
width *= cn; \
dst_step /= sizeof(dst[0]); \
\
for( ; ksize > 1 && count > 1; count -= 2, \
dst += dst_step*2, src += 2 ) \
{ \
for( i = 0; i <= width - 4; i += 4 ) \
{ \
const arrtype* sptr = src[1] + i; \
worktype s0 = sptr[0], s1 = sptr[1], \
s2 = sptr[2], s3 = sptr[3], t0, t1; \
\
for( k = 2; k < ksize; k++ ) \
{ \
sptr = src[k] + i; \
t0 = sptr[0]; t1 = sptr[1]; \
update_extr_macro(s0,t0); \
update_extr_macro(s1,t1); \
t0 = sptr[2]; t1 = sptr[3]; \
update_extr_macro(s2,t0); \
update_extr_macro(s3,t1); \
} \
\
sptr = src[0] + i; \
t0 = sptr[0]; t1 = sptr[1]; \
update_extr_macro(t0,s0); \
update_extr_macro(t1,s1); \
dst[i] = (arrtype)toggle_macro(t0); \
dst[i+1] = (arrtype)toggle_macro(t1); \
t0 = sptr[2]; t1 = sptr[3]; \
update_extr_macro(t0,s2); \
update_extr_macro(t1,s3); \
dst[i+2] = (arrtype)toggle_macro(t0); \
dst[i+3] = (arrtype)toggle_macro(t1); \
\
sptr = src[k] + i; \
t0 = sptr[0]; t1 = sptr[1]; \
update_extr_macro(t0,s0); \
update_extr_macro(t1,s1); \
dst[i+dst_step] = (arrtype)toggle_macro(t0); \
dst[i+dst_step+1] = (arrtype)toggle_macro(t1); \
t0 = sptr[2]; t1 = sptr[3]; \
update_extr_macro(t0,s2); \
update_extr_macro(t1,s3); \
dst[i+dst_step+2] = (arrtype)toggle_macro(t0); \
dst[i+dst_step+3] = (arrtype)toggle_macro(t1); \
} \
\
for( ; i < width; i++ ) \
{ \
const arrtype* sptr = src[1] + i; \
worktype s0 = sptr[0], t0; \
\
for( k = 2; k < ksize; k++ ) \
{ \
sptr = src[k] + i; t0 = sptr[0]; \
update_extr_macro(s0,t0); \
} \
\
sptr = src[0] + i; t0 = sptr[0]; \
update_extr_macro(t0,s0); \
dst[i] = (arrtype)toggle_macro(t0); \
\
sptr = src[k] + i; t0 = sptr[0]; \
update_extr_macro(t0,s0); \
dst[i+dst_step] = (arrtype)toggle_macro(t0); \
} \
} \
\
for( ; count > 0; count--, dst += dst_step, src++ ) \
{ \
for( i = 0; i <= width - 4; i += 4 ) \
{ \
const arrtype* sptr = src[0] + i; \
worktype s0 = sptr[0], s1 = sptr[1], \
s2 = sptr[2], s3 = sptr[3], t0, t1; \
\
for( k = 1; k < ksize; k++ ) \
{ \
sptr = src[k] + i; \
t0 = sptr[0]; t1 = sptr[1]; \
update_extr_macro(s0,t0); \
update_extr_macro(s1,t1); \
t0 = sptr[2]; t1 = sptr[3]; \
update_extr_macro(s2,t0); \
update_extr_macro(s3,t1); \
} \
dst[i] = (arrtype)toggle_macro(s0); \
dst[i+1] = (arrtype)toggle_macro(s1); \
dst[i+2] = (arrtype)toggle_macro(s2); \
dst[i+3] = (arrtype)toggle_macro(s3); \
} \
\
for( ; i < width; i++ ) \
{ \
const arrtype* sptr = src[0] + i; \
worktype s0 = sptr[0], t0; \
\
for( k = 1; k < ksize; k++ ) \
{ \
sptr = src[k] + i; t0 = sptr[0]; \
update_extr_macro(s0,t0); \
} \
dst[i] = (arrtype)toggle_macro(s0); \
} \
} \
}
ICV_MORPH_RECT_COL( Erode, 8u, uchar, int, CV_CALC_MIN_8U, CV_NOP )
ICV_MORPH_RECT_COL( Dilate, 8u, uchar, int, CV_CALC_MAX_8U, CV_NOP )
ICV_MORPH_RECT_COL( Erode, 32f, int, int, CV_CALC_MIN, CV_TOGGLE_FLT )
ICV_MORPH_RECT_COL( Dilate, 32f, int, int, CV_CALC_MAX, CV_TOGGLE_FLT )
#define ICV_MORPH_ANY( name, flavor, arrtype, worktype, \
update_extr_macro, toggle_macro ) \
static void \
icv##name##Any_##flavor( const arrtype** src, arrtype* dst, \
int dst_step, int count, void* params ) \
{ \
CvMorphology* state = (CvMorphology*)params; \
int width = state->get_width(); \
int cn = CV_MAT_CN(state->get_src_type()); \
int i, k; \
CvPoint* el_sparse = (CvPoint*)state->get_element_sparse_buf();\
int el_count = state->get_element_sparse_count(); \
const arrtype** el_ptr = (const arrtype**)(el_sparse + el_count);\
const arrtype** el_end = el_ptr + el_count; \
\
width *= cn; \
dst_step /= sizeof(dst[0]); \
\
for( ; count > 0; count--, dst += dst_step, src++ ) \
{ \
for( k = 0; k < el_count; k++ ) \
el_ptr[k] = src[el_sparse[k].y]+el_sparse[k].x; \
\
for( i = 0; i <= width - 4; i += 4 ) \
{ \
const arrtype** psptr = el_ptr; \
const arrtype* sptr = *psptr++; \
worktype s0 = sptr[i], s1 = sptr[i+1], \
s2 = sptr[i+2], s3 = sptr[i+3], t; \
\
while( psptr != el_end ) \
{ \
sptr = *psptr++; \
t = sptr[i]; \
update_extr_macro(s0,t); \
t = sptr[i+1]; \
update_extr_macro(s1,t); \
t = sptr[i+2]; \
update_extr_macro(s2,t); \
t = sptr[i+3]; \
update_extr_macro(s3,t); \
} \
\
dst[i] = (arrtype)toggle_macro(s0); \
dst[i+1] = (arrtype)toggle_macro(s1); \
dst[i+2] = (arrtype)toggle_macro(s2); \
dst[i+3] = (arrtype)toggle_macro(s3); \
} \
\
for( ; i < width; i++ ) \
{ \
const arrtype* sptr = el_ptr[0] + i; \
worktype s0 = sptr[0], t0; \
\
for( k = 1; k < el_count; k++ ) \
{ \
sptr = el_ptr[k] + i; \
t0 = sptr[0]; \
update_extr_macro(s0,t0); \
} \
\
dst[i] = (arrtype)toggle_macro(s0); \
} \
} \
}
ICV_MORPH_ANY( Erode, 8u, uchar, int, CV_CALC_MIN, CV_NOP )
ICV_MORPH_ANY( Dilate, 8u, uchar, int, CV_CALC_MAX, CV_NOP )
ICV_MORPH_ANY( Erode, 32f, int, int, CV_CALC_MIN, CV_TOGGLE_FLT )
ICV_MORPH_ANY( Dilate, 32f, int, int, CV_CALC_MAX, CV_TOGGLE_FLT )
/////////////////////////////////// External Interface /////////////////////////////////////
CV_IMPL IplConvKernel *
cvCreateStructuringElementEx( int cols, int rows,
int anchorX, int anchorY,
int shape, int *values )
{
IplConvKernel *element = 0;
int i, size = rows * cols;
int element_size = sizeof(*element) + size*sizeof(element->values[0]);
CV_FUNCNAME( "cvCreateStructuringElementEx" );
__BEGIN__;
if( !values && shape == CV_SHAPE_CUSTOM )
CV_ERROR_FROM_STATUS( CV_NULLPTR_ERR );
if( cols <= 0 || rows <= 0 ||
(unsigned) anchorX >= (unsigned) cols ||
(unsigned) anchorY >= (unsigned) rows )
CV_ERROR_FROM_STATUS( CV_BADSIZE_ERR );
CV_CALL( element = (IplConvKernel *)cvAlloc(element_size + 32));
if( !element )
CV_ERROR_FROM_STATUS( CV_OUTOFMEM_ERR );
element->nCols = cols;
element->nRows = rows;
element->anchorX = anchorX;
element->anchorY = anchorY;
element->nShiftR = shape < CV_SHAPE_ELLIPSE ? shape : CV_SHAPE_CUSTOM;
element->values = (int*)(element + 1);
if( shape == CV_SHAPE_CUSTOM )
{
if( !values )
CV_ERROR( CV_StsNullPtr, "Null pointer to the custom element mask" );
for( i = 0; i < size; i++ )
element->values[i] = values[i];
}
else
{
CvMat el_hdr = cvMat( rows, cols, CV_32SC1, element->values );
CV_CALL( CvMorphology::init_binary_element(&el_hdr,
shape, cvPoint(anchorX,anchorY)));
}
__END__;
if( cvGetErrStatus() < 0 )
cvReleaseStructuringElement( &element );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -