cvdrawing.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 2,174 行 · 第 1/5 页
SVN-BASE
2,174 行
static void
icvFillEdgeCollection( CvMat* img, CvContour* edges, const void* color )
{
CvPolyEdge tmp;
int i, y, total = edges->total;
CvSeqReader reader;
CvSize size = icvGetMatSize(img);
CvPolyEdge* e;
int y_max = INT_MIN;
int pix_size = icvPixSize[CV_MAT_TYPE(img->type)];
__BEGIN__;
memset( &tmp, 0, sizeof(tmp));
/* check parameters */
if( edges->total < 2 || edges->rect.height < 0 || edges->rect.y >= size.height ||
edges->rect.width < 0 || edges->rect.x >= size.width )
EXIT;
icvSortPolyEdges( (CvSeq*)edges, 0 );
cvStartReadSeq( (CvSeq*)edges, &reader );
#ifdef _DEBUG
e = &tmp;
tmp.y0 = INT_MIN;
#endif
for( i = 0; i < total; i++ )
{
CvPolyEdge* e1 = (CvPolyEdge*)(reader.ptr);
#ifdef _DEBUG
assert( ICV_CMP_EDGES( *e, *e1 ) != 0 );
e = e1;
#endif
y_max = CV_MAX( y_max, e1->y1 );
CV_NEXT_SEQ_ELEM( sizeof(CvPolyEdge), reader );
}
if( y_max >= size.height )
y_max = size.height - 1;
/* start drawing */
tmp.y0 = INT_MAX;
cvSeqPush( (CvSeq*)edges, &tmp );
i = 0;
tmp.next = 0;
cvStartReadSeq( (CvSeq*)edges, &reader );
e = (CvPolyEdge*)(reader.ptr);
y = e->y0;
do
{
CvPolyEdge *last, *prelast, *keep_prelast;
int sort_flag = 0;
int draw = 0;
int clipline = y < 0;
prelast = &tmp;
last = tmp.next;
while( last || e->y0 == y )
{
if( last && last->y1 == y )
{
/* exlude edge if y reachs its lower point */
prelast->next = last->next;
last = last->next;
continue;
}
keep_prelast = prelast;
if( last && (e->y0 > y || last->x < e->x) )
{
/* go to the next edge in active list */
prelast = last;
last = last->next;
}
else if( i < total )
{
/* insert new edge into active list if y reachs its upper point */
prelast->next = e;
e->next = last;
prelast = e;
CV_NEXT_SEQ_ELEM( edges->elem_size, reader );
e = (CvPolyEdge*)(reader.ptr);
i++;
}
else
break;
if( draw )
{
if( !clipline )
{
/* convert x's from fixed-point to image coordinates */
uchar *timg = (uchar*)(img->data.ptr) + y * img->step;
int x1 = keep_prelast->x;
int x2 = prelast->x;
if( x1 > x2 )
{
int t = x1;
x1 = x2;
x2 = t;
}
x1 = (x1 + (1 << 15)) >> 16;
x2 = (x2 + (1 << 15)) >> 16;
/* clip and draw the line */
if( x1 < size.width && x2 >= 0 )
{
if( x1 < 0 )
x1 = 0;
if( x2 >= size.width )
x2 = size.width - 1;
ICV_HLINE( timg, x1, x2, color, pix_size );
}
}
keep_prelast->x += keep_prelast->dx;
prelast->x += prelast->dx;
}
draw ^= 1;
}
/* sort edges (bubble sort on list) */
keep_prelast = 0;
do
{
prelast = &tmp;
last = tmp.next;
while( last != keep_prelast && last->next != 0 )
{
CvPolyEdge *te = last->next;
/* swap edges */
if( last->x > te->x )
{
prelast->next = te;
last->next = te->next;
te->next = last;
prelast = te;
sort_flag = 1;
}
else
{
prelast = last;
last = te;
}
}
keep_prelast = prelast;
}
while( sort_flag && keep_prelast != tmp.next && keep_prelast != &tmp );
}
while( (++y) < y_max );
__END__;
}
/* draws simple circle */
static void
icvCircle( CvMat* img, CvPoint center, int radius, const void* color )
{
CvSize size = icvGetMatSize( img );
int step = img->step;
int pix_size = icvPixSize[CV_MAT_TYPE(img->type)];
uchar* ptr = (uchar*)(img->data.ptr);
int err = 0, dx = radius, dy = 0, plus = 1, minus = (radius << 1) - 1;
int inside = center.x >= radius && center.x < size.width - radius &&
center.y >= radius && center.y < size.height - radius;
#define ICV_PUT_POINT( ptr, x ) \
memcpy( (ptr) + (x)*pix_size, color, pix_size )
while( dx >= dy )
{
int mask;
int y11 = center.y - dy, y12 = center.y + dy, y21 = center.y - dx, y22 = center.y + dx;
int x11 = center.x - dx, x12 = center.x + dx, x21 = center.x - dy, x22 = center.x + dy;
if( inside )
{
uchar *tptr0 = ptr + y11 * step;
uchar *tptr1 = ptr + y12 * step;
ICV_PUT_POINT( tptr0, x11 );
ICV_PUT_POINT( tptr1, x11 );
ICV_PUT_POINT( tptr0, x12 );
ICV_PUT_POINT( tptr1, x12 );
tptr0 = ptr + y21 * step;
tptr1 = ptr + y22 * step;
ICV_PUT_POINT( tptr0, x21 );
ICV_PUT_POINT( tptr1, x21 );
ICV_PUT_POINT( tptr0, x22 );
ICV_PUT_POINT( tptr1, x22 );
}
else if( x11 < size.width && x12 >= 0 && y21 < size.height && y22 >= 0 )
{
if( (unsigned) y11 < (unsigned) size.height )
{
uchar *tptr = ptr + y11 * step;
if( x11 >= 0 )
ICV_PUT_POINT( tptr, x11 );
if( x12 < size.width )
ICV_PUT_POINT( tptr, x12 );
}
if( (unsigned) y12 < (unsigned) size.height )
{
uchar *tptr = ptr + y12 * step;
if( x11 >= 0 )
ICV_PUT_POINT( tptr, x11 );
if( x12 < size.width )
ICV_PUT_POINT( tptr, x12 );
}
if( x21 < size.width && x22 >= 0 )
{
if( (unsigned) y21 < (unsigned) size.height )
{
uchar *tptr = ptr + y21 * step;
if( x21 >= 0 )
ICV_PUT_POINT( tptr, x21 );
if( x22 < size.width )
ICV_PUT_POINT( tptr, x22 );
}
if( (unsigned) y22 < (unsigned) size.height )
{
uchar *tptr = ptr + y22 * step;
if( x21 >= 0 )
ICV_PUT_POINT( tptr, x21 );
if( x22 < size.width )
ICV_PUT_POINT( tptr, x22 );
}
}
}
dy++;
err += plus;
plus += 2;
mask = (err <= 0) - 1;
err -= minus & mask;
dx += mask;
minus -= mask & 2;
}
#undef ICV_PUT_POINT
}
/****************************************************************************************\
* Cicle drawing using direct Bresenham algorithm *
\****************************************************************************************/
/* draws filled circle */
static void
icvFillCircle( CvMat* img, CvPoint center, int radius, const void* color )
{
CvSize size = icvGetMatSize( img );
int step = img->step;
int pix_size = icvPixSize[CV_MAT_TYPE(img->type)];
uchar* ptr = (uchar*)(img->data.ptr);
int err = 0, dx = radius, dy = 0, plus = 1, minus = (radius << 1) - 1;
int inside = center.x >= radius && center.x < size.width - radius &&
center.y >= radius && center.y < size.height - radius;
while( dx >= dy )
{
int mask;
int y11 = center.y - dy, y12 = center.y + dy, y21 = center.y - dx, y22 = center.y + dx;
int x11 = center.x - dx, x12 = center.x + dx, x21 = center.x - dy, x22 = center.x + dy;
if( inside )
{
uchar *tptr0 = ptr + y11 * step;
uchar *tptr1 = ptr + y12 * step;
ICV_HLINE( tptr0, x11, x12, color, pix_size );
ICV_HLINE( tptr1, x11, x12, color, pix_size );
tptr0 = ptr + y21 * step;
tptr1 = ptr + y22 * step;
ICV_HLINE( tptr0, x21, x22, color, pix_size );
ICV_HLINE( tptr1, x21, x22, color, pix_size );
}
else if( x11 < size.width && x12 >= 0 && y21 < size.height && y22 >= 0 )
{
x11 = CV_MAX( x11, 0 );
x12 = CV_MIN( x12, size.width - 1 );
if( (unsigned) y11 < (unsigned) size.height )
{
uchar *tptr = ptr + y11 * step;
ICV_HLINE( tptr, x11, x12, color, pix_size );
}
if( (unsigned) y12 < (unsigned) size.height )
{
uchar *tptr = ptr + y12 * step;
ICV_HLINE( tptr, x11, x12, color, pix_size );
}
if( x21 < size.width && x22 >= 0 )
{
x21 = CV_MAX( x21, 0 );
x22 = CV_MIN( x22, size.width - 1 );
if( (unsigned) y21 < (unsigned) size.height )
{
uchar *tptr = ptr + y21 * step;
ICV_HLINE( tptr, x21, x22, color, pix_size );
}
if( (unsigned) y22 < (unsigned) size.height )
{
uchar *tptr = ptr + y22 * step;
ICV_HLINE( tptr, x21, x22, color, pix_size );
}
}
}
dy++;
err += plus;
plus += 2;
mask = (err <= 0) - 1;
err -= minus & mask;
dx += mask;
minus -= mask & 2;
}
}
/* helper function for thick lines */
static CvPoint
icvCalcWPT( CvPoint p1, CvPoint p2, int lr )
{
int dx = p1.x - p2.x, dy = p2.y - p1.y;
double r = dx * dx + dy * dy;
CvPoint dp = { 0, 0 };
if( r )
{
r = lr * cvInvSqrt( (float) r );
dp.x = cvRound( dy * r );
dp.y = cvRound( dx * r );
}
return dp;
}
static void
icvThickLine( CvMat* img, CvPoint pt1, CvPoint pt2,
int thickness, const void* color,
int connectivity = 8 )
{
thickness >>= 1;
if( connectivity == 0 )
connectivity = 8;
if( thickness <= 0 )
{
icvLine( img, pt1, pt2, color, connectivity );
}
else
{
CvPoint pt[4];
CvPoint dp = icvCalcWPT( pt1, pt2, thickness );
pt[0].x = pt1.x + dp.x;
pt[0].y = pt1.y + dp.y;
pt[1].x = pt1.x - dp.x;
pt[1].y = pt1.y - dp.y;
pt[2].x = pt2.x - dp.x;
pt[2].y = pt2.y - dp.y;
pt[3].x = pt2.x + dp.x;
pt[3].y = pt2.y + dp.y;
icvFillConvexPoly( img, pt, 4, color );
icvFillCircle( img, pt1, thickness, color );
icvFillCircle( img, pt2, thickness, color );
}
}
static void
icvPolyLine( CvMat* img, CvPoint *v, int count, int closed,
int thickness, const void* color, int connectivity )
{
CV_FUNCNAME("icvPolyLine");
__BEGIN__;
int i0 = closed ? count - 1 : 0, i;
assert( img && thickness >= 0 );
assert( v && count >= 0 );
if( !v )
CV_ERROR( CV_StsNullPtr, "" );
if( count > 0 )
{
for( i = !closed; i < count; i0 = i, i++ )
{
icvThickLine( img, v[i0], v[i], thickness, color, connectivity );
}
}
__END__;
}
static void
icvPolyLineAA( CvMat* img, CvPoint *v, int count, int closed,
int scale, const void* color )
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?