cvsegment.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 587 行 · 第 1/2 页
SVN-BASE
587 行
d[0] = src[0] - src[-3];
ad[0] = CV_IABS(d[0]);
d[1] = src[1] - src[-2];
ad[1] = CV_IABS(d[1]);
d[2] = src[2] - src[-1];
ad[2] = CV_IABS(d[2]);
f0 = ad[1] > ad[0];
f1 = ad[2] > ad[f0];
val = d[tab[f0*2 + f1]];
d[0] = src[0] - src[-src_step];
ad[0] = CV_IABS(d[0]);
d[1] = src[1] - src[1-src_step];
ad[1] = CV_IABS(d[1]);
d[2] = src[2] - src[2-src_step];
ad[2] = CV_IABS(d[2]);
f0 = ad[1] > ad[0];
f1 = ad[2] > ad[f0];
dst[x] = (uchar)(val + d[tab[f0*2 + f1]] > thresh ? 255 : 0);*/
dst[x] = (uchar)(val > thresh);
}
src = src0;
}
}
#endif
const CvPoint icvCodeDeltas[8] =
{ {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} };
static CvSeq*
icvGetComponent( uchar* img, int step, CvRect rect,
CvMemStorage* storage )
{
const char nbd = 4;
int deltas[16];
int x, y;
CvSeq* exterior = 0;
char* ptr;
/* initialize local state */
CV_INIT_3X3_DELTAS( deltas, step, 1 );
memcpy( deltas + 8, deltas, 8 * sizeof( deltas[0] ));
ptr = (char*)(img + step*rect.y);
rect.width += rect.x;
rect.height += rect.y;
for( y = rect.y; y < rect.height; y++, ptr += step )
{
int prev = ptr[rect.x - 1] & -2;
for( x = rect.x; x < rect.width; x++ )
{
int p = ptr[x] & -2;
//assert( exterior || ((p | prev) & -4) == 0 );
if( p != prev )
{
CvSeq *seq = 0;
int is_hole = 0;
CvSeqWriter writer;
char *i0, *i1, *i3, *i4 = 0;
int prev_s = -1, s, s_end;
CvPoint pt = { x, y };
if( !(prev == 0 && p == 2) ) /* if not external contour */
{
/* check hole */
if( p != 0 || prev < 1 )
{
prev = p;
continue;
}
is_hole = 1;
if( !exterior )
{
assert(0);
return 0;
}
}
cvStartWriteSeq( CV_SEQ_CONTOUR | (is_hole ? CV_SEQ_FLAG_HOLE : 0),
sizeof(CvContour), sizeof(CvPoint), storage, &writer );
s_end = s = is_hole ? 0 : 4;
i0 = ptr + x - is_hole;
do
{
s = (s - 1) & 7;
i1 = i0 + deltas[s];
if( (*i1 & -2) != 0 )
break;
}
while( s != s_end );
if( s == s_end ) /* single pixel domain */
{
*i0 = (char) (nbd | -128);
CV_WRITE_SEQ_ELEM( pt, writer );
}
else
{
i3 = i0;
prev_s = s ^ 4;
/* follow border */
for( ;; )
{
s_end = s;
for( ;; )
{
i4 = i3 + deltas[++s];
if( (*i4 & -2) != 0 )
break;
}
s &= 7;
/* check "right" bound */
if( (unsigned) (s - 1) < (unsigned) s_end )
{
*i3 = (char) (nbd | -128);
}
else if( *i3 > 0 )
{
*i3 = nbd;
}
if( s != prev_s )
{
CV_WRITE_SEQ_ELEM( pt, writer );
prev_s = s;
}
pt.x += icvCodeDeltas[s].x;
pt.y += icvCodeDeltas[s].y;
if( i4 == i0 && i3 == i1 )
break;
i3 = i4;
s = (s + 4) & 7;
} /* end of border following loop */
}
seq = cvEndWriteSeq( &writer );
cvContourBoundingRect( seq, 1 );
if( !is_hole )
exterior = seq;
else
{
seq->v_prev = exterior;
seq->h_next = exterior->v_next;
if( seq->h_next )
seq->h_next->h_prev = seq;
exterior->v_next = seq;
}
prev = ptr[x] & -2;
}
}
}
return exterior;
}
CV_IMPL CvSeq*
cvSegmentImage( const CvArr* srcarr, CvArr* dstarr,
double canny_threshold,
double ffill_threshold,
CvMemStorage* storage )
{
CvSeq* root = 0;
CvMat* gray = 0;
CvMat* canny = 0;
//CvMat* temp = 0;
void* stack = 0;
CV_FUNCNAME( "cvSegmentImage" );
__BEGIN__;
CvMat srcstub, *src;
CvMat dststub, *dst;
CvMat* mask;
CvSize size;
CvPoint pt;
int ffill_lw_up = cvRound( fabs(ffill_threshold) );
CvSeq* prev_seq = 0;
CV_CALL( src = cvGetMat( srcarr, &srcstub ));
CV_CALL( dst = cvGetMat( dstarr, &dststub ));
size = cvGetSize( src );
CV_CALL( gray = cvCreateMat( size.height, size.width, CV_8UC1 ));
CV_CALL( canny = cvCreateMat( size.height, size.width, CV_8UC1 ));
//CV_CALL( temp = cvCreateMat( size.height/2, size.width/2, CV_8UC3 ));
CV_CALL( stack = cvAlloc( size.width * size.height * sizeof(Seg)));
cvCvtColor( src, gray, CV_BGR2GRAY );
cvCanny( gray, canny, 0/*canny_threshold*0.4*/, canny_threshold, 3 );
cvThreshold( canny, canny, 1, 1, CV_THRESH_BINARY );
//cvZero( canny );
//color_derv( src, canny, canny_threshold );
//cvPyrDown( src, temp );
//cvPyrUp( temp, dst );
//src = dst;
mask = canny; // a new name for new role
// make a non-zero border.
cvRectangle( mask, cvPoint(0,0), cvPoint(size.width-1,size.height-1), 1, 1 );
for( pt.y = 0; pt.y < size.height; pt.y++ )
{
for( pt.x = 0; pt.x < size.width; pt.x++ )
{
if( mask->data.ptr[mask->step*pt.y + pt.x] == 0 )
{
CvConnectedComp region;
int avgVal[3] = { 0, 0, 0 };
icvSegmFloodFill_Stage1( src->data.ptr, src->step,
mask->data.ptr, mask->step,
size, pt, avgVal,
ffill_lw_up, ffill_lw_up,
®ion, stack );
/*avgVal[0] = (avgVal[0] + 15) & -32;
if( avgVal[0] > 255 )
avgVal[0] = 255;
avgVal[1] = (avgVal[1] + 15) & -32;
if( avgVal[1] > 255 )
avgVal[1] = 255;
avgVal[2] = (avgVal[2] + 15) & -32;
if( avgVal[2] > 255 )
avgVal[2] = 255;*/
if( storage )
{
CvSeq* tmpseq = icvGetComponent( mask->data.ptr, mask->step,
region.rect, storage );
if( tmpseq != 0 )
{
((CvContour*)tmpseq)->color =
CV_RGB(avgVal[2],avgVal[1],avgVal[0]);
tmpseq->h_prev = prev_seq;
if( prev_seq )
prev_seq->h_next = tmpseq;
else
root = tmpseq;
prev_seq = tmpseq;
}
}
icvSegmFloodFill_Stage2( dst->data.ptr, dst->step,
mask->data.ptr, mask->step,
size, avgVal,
region.rect );
}
}
}
__END__;
//cvReleaseMat( &temp );
cvReleaseMat( &gray );
cvReleaseMat( &canny );
cvFree( &stack );
return root;
}
/* End of file. */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?