📄 cvpyrsegmentation.cpp
字号:
_CvPyramid temp_cmp;
_CvPyramidBase *first_level_start = (_CvPyramidBase *) first_level_end -
first_level_size.width * first_level_size.height;
int c, i, count = cmp_seq->total;
cvStartReadSeq( cmp_seq, &reader, 0 );
cvStartAppendToSeq( res_seq, &writer );
if( threshold < eps )
{
/* if threshold is too small then simply copy all
the components to the output sequence */
for( i = 0; i < count; i++ )
{
CvConnectedComp comp;
_CvPyramid *cmp = (_CvPyramid *) (((_CvListNode *) reader.ptr)->data);
Cv32suf _c;
if( cmp < first_level_end )
{
icvExpandBaseLevelC1( cmp, &temp_cmp, first_level_start,
first_level_size.width );
cmp = &temp_cmp;
}
_c.i = cvRound( cmp->c );
cmp->c = _c.f;
comp.value = cvRealScalar(_c.i);
comp.area = cmp->a;
comp.rect.x = cmp->rect.x1;
comp.rect.y = cmp->rect.y1;
comp.rect.width = cmp->rect.x2 - cmp->rect.x1;
comp.rect.height = cmp->rect.y2 - cmp->rect.y1;
comp.contour = 0;
CV_WRITE_SEQ_ELEM( comp, writer );
CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
}
}
else
{
_CvListNode stub_node;
_CvListNode *prev = &stub_node;
stub_node.next = 0;
for( i = 0; i < count; i++ )
{
_CvListNode *node = (_CvListNode *) reader.ptr;
prev->next = node;
prev = node;
CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
}
prev->next = 0;
prev = stub_node.next;
while( prev )
{
_CvListNode *node = prev->next;
_CvListNode *acc = prev;
_CvPyramid *cmp = (_CvPyramid *) (acc->data);
CvConnectedComp comp;
float c0 = cmp->c;
if( cmp < first_level_end )
{
icvExpandBaseLevelC1( cmp, &temp_cmp, first_level_start,
first_level_size.width );
}
else
{
temp_cmp = *cmp;
temp_cmp.c *= temp_cmp.a;
}
acc->next = 0;
stub_node.next = 0;
prev = &stub_node;
while( node )
{
cmp = (_CvPyramid *) (node->data);
if( fabs( c0 - cmp->c ) < threshold )
{
_CvPyramid temp;
/* exclude from global list and add to list of joint component */
prev->next = node->next;
node->next = acc;
acc = node;
if( cmp < first_level_end )
{
icvExpandBaseLevelC1( cmp, &temp, first_level_start,
first_level_size.width );
cmp = &temp;
}
temp_cmp.a += cmp->a;
temp_cmp.c += cmp->c * cmp->a;
icvMaxRoi( &(temp_cmp.rect), &(cmp->rect) );
}
else
{
if( prev == &stub_node )
{
stub_node.next = node;
}
prev = node;
}
node = prev->next;
}
if( temp_cmp.a != 0 )
{
c = cvRound( temp_cmp.c / temp_cmp.a );
}
else
{
c = cvRound( c0 );
}
node = acc;
while( node )
{
Cv32suf _c;
cmp = (_CvPyramid *) (node->data);
_c.i = c; cmp->c = _c.f;
node = node->next;
}
comp.value = cvRealScalar(c);
comp.area = temp_cmp.a;
comp.rect.x = temp_cmp.rect.x1;
comp.rect.y = temp_cmp.rect.y1;
comp.rect.width = temp_cmp.rect.x2 - temp_cmp.rect.x1;
comp.rect.height = temp_cmp.rect.y2 - temp_cmp.rect.y1;
comp.contour = 0;
CV_WRITE_SEQ_ELEM( comp, writer );
prev = stub_node.next;
}
}
cvEndWriteSeq( &writer );
return CV_OK;
}
/****************************************************************************************\
clusterization segmented components
\****************************************************************************************/
static void
icvExpandBaseLevelC3( _CvPyramidC3 * base_p, _CvPyramidC3 * p,
_CvPyramidBaseC3 * start, int width )
{
int x = (int)((_CvPyramidBaseC3 *) base_p - start);
int y = x / width;
x -= y * width;
p->a = 1;
p->rect.x1 = (ushort) x;
p->rect.y1 = (ushort) y;
p->rect.x2 = (ushort) (x + 1);
p->rect.y2 = (ushort) (y + 1);
p->c = base_p->c;
}
CvStatus
icvSegmentClusterC3( CvSeq * cmp_seq, CvSeq * res_seq,
double threshold,
_CvPyramidC3 * first_level_end, CvSize first_level_size )
{
const double eps = 1.;
CvSeqWriter writer;
CvSeqReader reader;
_CvPyramidC3 temp_cmp;
_CvPyramidBaseC3 *first_level_start = (_CvPyramidBaseC3 *) first_level_end -
first_level_size.width * first_level_size.height;
int i, count = cmp_seq->total;
int c_blue, c_green, c_red;
cvStartReadSeq( cmp_seq, &reader, 0 );
cvStartAppendToSeq( res_seq, &writer );
if( threshold < eps )
{
/* if threshold is too small then simply copy all
the components to the output sequence */
for( i = 0; i < count; i++ )
{
CvConnectedComp comp;
_CvPyramidC3 *cmp = (_CvPyramidC3 *) (((_CvListNode *) reader.ptr)->data);
Cv32suf _c;
if( cmp < first_level_end )
{
icvExpandBaseLevelC3( cmp, &temp_cmp, first_level_start,
first_level_size.width );
cmp = &temp_cmp;
}
c_blue = cvRound( cmp->c.blue );
c_green = cvRound( cmp->c.green );
c_red = cvRound( cmp->c.red );
_c.i = c_blue; cmp->c.blue = _c.f;
_c.i = c_green; cmp->c.green = _c.f;
_c.i = c_red; cmp->c.red = _c.f;
comp.value = cvScalar( c_blue, c_green, c_red );
comp.area = cmp->a;
comp.rect.x = cmp->rect.x1;
comp.rect.y = cmp->rect.y1;
comp.rect.width = cmp->rect.x2 - cmp->rect.x1;
comp.rect.height = cmp->rect.y2 - cmp->rect.y1;
comp.contour = 0;
CV_WRITE_SEQ_ELEM( comp, writer );
CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
}
}
else
{
_CvListNode stub_node;
_CvListNode *prev = &stub_node;
stub_node.next = 0;
for( i = 0; i < count; i++ )
{
_CvListNode *node = (_CvListNode *) reader.ptr;
prev->next = node;
prev = node;
CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
}
prev->next = 0;
prev = stub_node.next;
while( prev )
{
_CvListNode *node = prev->next;
_CvListNode *acc = prev;
_CvPyramidC3 *cmp = (_CvPyramidC3 *) (acc->data);
CvConnectedComp comp;
_CvRGBf c0 = cmp->c;
if( cmp < first_level_end )
{
icvExpandBaseLevelC3( cmp, &temp_cmp, first_level_start,
first_level_size.width );
}
else
{
temp_cmp = *cmp;
temp_cmp.c.blue *= temp_cmp.a;
temp_cmp.c.green *= temp_cmp.a;
temp_cmp.c.red *= temp_cmp.a;
}
acc->next = 0;
stub_node.next = 0;
prev = &stub_node;
while( node )
{
cmp = (_CvPyramidC3 *) (node->data);
if( _CV_RGB_DIST( c0, cmp->c ) < threshold )
{
_CvPyramidC3 temp;
/* exclude from global list and add to list of joint component */
prev->next = node->next;
node->next = acc;
acc = node;
if( cmp < first_level_end )
{
icvExpandBaseLevelC3( cmp, &temp, first_level_start,
first_level_size.width );
cmp = &temp;
}
temp_cmp.a += cmp->a;
temp_cmp.c.blue += cmp->c.blue * cmp->a;
temp_cmp.c.green += cmp->c.green * cmp->a;
temp_cmp.c.red += cmp->c.red * cmp->a;
icvMaxRoi( &(temp_cmp.rect), &(cmp->rect) );
}
else
{
if( prev == &stub_node )
{
stub_node.next = node;
}
prev = node;
}
node = prev->next;
}
if( temp_cmp.a != 0 )
{
c_blue = cvRound( temp_cmp.c.blue / temp_cmp.a );
c_green = cvRound( temp_cmp.c.green / temp_cmp.a );
c_red = cvRound( temp_cmp.c.red / temp_cmp.a );
}
else
{
c_blue = cvRound( c0.blue );
c_green = cvRound( c0.green );
c_red = cvRound( c0.red );
}
node = acc;
while( node )
{
Cv32suf _c;
cmp = (_CvPyramidC3 *) (node->data);
_c.i = c_blue; cmp->c.blue = _c.f;
_c.i = c_green; cmp->c.green = _c.f;
_c.i = c_red; cmp->c.red = _c.f;
node = node->next;
}
comp.value = cvScalar( c_blue, c_green, c_red );
comp.area = temp_cmp.a;
comp.rect.x = temp_cmp.rect.x1;
comp.rect.y = temp_cmp.rect.y1;
comp.rect.width = temp_cmp.rect.x2 - temp_cmp.rect.x1;
comp.rect.height = temp_cmp.rect.y2 - temp_cmp.rect.y1;
comp.contour = 0;
CV_WRITE_SEQ_ELEM( comp, writer );
prev = stub_node.next;
}
}
cvEndWriteSeq( &writer );
return CV_OK;
}
/****************************************************************************************\
definition of the maximum roi size
\****************************************************************************************/
void
icvMaxRoi( _CvRect16u * max_rect, _CvRect16u * cur_rect )
{
if( max_rect->x2 == 0 )
*max_rect = *cur_rect;
else
{
if( max_rect->x1 > cur_rect->x1 )
max_rect->x1 = cur_rect->x1;
if( max_rect->y1 > cur_rect->y1 )
max_rect->y1 = cur_rect->y1;
if( max_rect->x2 < cur_rect->x2 )
max_rect->x2 = cur_rect->x2;
if( max_rect->y2 < cur_rect->y2 )
max_rect->y2 = cur_rect->y2;
}
}
void
icvMaxRoi1( _CvRect16u * max_rect, int x, int y )
{
if( max_rect->x2 == 0 )
{
max_rect->x1 = (ushort) x;
max_rect->y1 = (ushort) y;
++x;
++y;
max_rect->x2 = (ushort) x;
max_rect->y2 = (ushort) y;
}
else
{
if( max_rect->x1 > x )
max_rect->x1 = (ushort) x;
if( max_rect->y1 > y )
max_rect->y1 = (ushort) y;
++x;
++y;
if( max_rect->x2 < x )
max_rect->x2 = (ushort) x;
if( max_rect->y2 < y )
max_rect->y2 = (ushort) y;
}
}
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvPyrSegmentation
// Purpose:
// segments an image using pyramid-linking technique
// Context:
// Parameters:
// src - source image
// dst - destination image
// comp - pointer to returned connected component sequence
// storage - where the sequence is stored
// level - maximal pyramid level
// threshold1 - first threshold, affecting on detalization level when pyramid
// is built.
// threshold2 - second threshold - affects on final components merging.
// Returns:
// Notes:
// Source and destination image must be equal types and channels
//F*/
CV_IMPL void
cvPyrSegmentation( IplImage * src,
IplImage * dst,
CvMemStorage * storage,
CvSeq ** comp, int level, double threshold1, double threshold2 )
{
CvSize src_size, dst_size;
uchar *src_data = 0;
uchar *dst_data = 0;
int src_step = 0, dst_step = 0;
int thresh1 = cvRound( threshold1 );
int thresh2 = cvRound( threshold2 );
CV_FUNCNAME( "cvPyrSegmentation" );
__BEGIN__;
if( src->depth != IPL_DEPTH_8U )
CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
if( src->depth != dst->depth || src->nChannels != dst->nChannels )
CV_ERROR( CV_StsBadArg, "src and dst have different formats" );
cvGetRawData( src, &src_data, &src_step, &src_size );
cvGetRawData( dst, &dst_data, &dst_step, &dst_size );
if( src_size.width != dst_size.width ||
src_size.height != dst_size.height )
CV_ERROR( CV_StsBadArg, "src and dst have different ROIs" );
switch (src->nChannels)
{
case 1:
IPPI_CALL( icvPyrSegmentation8uC1R( src_data, src_step,
dst_data, dst_step,
src_size,
CV_GAUSSIAN_5x5,
comp, storage, level, thresh1, thresh2 ));
break;
case 3:
IPPI_CALL( icvPyrSegmentation8uC3R( src_data, src_step,
dst_data, dst_step,
src_size,
CV_GAUSSIAN_5x5,
comp, storage, level, thresh1, thresh2 ));
break;
default:
CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
}
__END__;
}
/* End of file. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -