cvdrawing.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 2,174 行 · 第 1/5 页
SVN-BASE
2,174 行
1.0000000f, 0.9998477f, 0.9993908f, 0.9986295f, 0.9975641f, 0.9961947f,
0.9945219f, 0.9925462f, 0.9902681f, 0.9876883f, 0.9848078f, 0.9816272f,
0.9781476f, 0.9743701f, 0.9702957f, 0.9659258f, 0.9612617f, 0.9563048f,
0.9510565f, 0.9455186f, 0.9396926f, 0.9335804f, 0.9271839f, 0.9205049f,
0.9135455f, 0.9063078f, 0.8987940f, 0.8910065f, 0.8829476f, 0.8746197f,
0.8660254f, 0.8571673f, 0.8480481f, 0.8386706f, 0.8290376f, 0.8191520f,
0.8090170f, 0.7986355f, 0.7880108f, 0.7771460f, 0.7660444f, 0.7547096f,
0.7431448f, 0.7313537f, 0.7193398f, 0.7071068f, 0.6946584f, 0.6819984f,
0.6691306f, 0.6560590f, 0.6427876f, 0.6293204f, 0.6156615f, 0.6018150f,
0.5877853f, 0.5735764f, 0.5591929f, 0.5446390f, 0.5299193f, 0.5150381f,
0.5000000f, 0.4848096f, 0.4694716f, 0.4539905f, 0.4383711f, 0.4226183f,
0.4067366f, 0.3907311f, 0.3746066f, 0.3583679f, 0.3420201f, 0.3255682f,
0.3090170f, 0.2923717f, 0.2756374f, 0.2588190f, 0.2419219f, 0.2249511f,
0.2079117f, 0.1908090f, 0.1736482f, 0.1564345f, 0.1391731f, 0.1218693f,
0.1045285f, 0.0871557f, 0.0697565f, 0.0523360f, 0.0348995f, 0.0174524f,
0.0000000f, -0.0174524f, -0.0348995f, -0.0523360f, -0.0697565f, -0.0871557f,
-0.1045285f, -0.1218693f, -0.1391731f, -0.1564345f, -0.1736482f, -0.1908090f,
-0.2079117f, -0.2249511f, -0.2419219f, -0.2588190f, -0.2756374f, -0.2923717f,
-0.3090170f, -0.3255682f, -0.3420201f, -0.3583679f, -0.3746066f, -0.3907311f,
-0.4067366f, -0.4226183f, -0.4383711f, -0.4539905f, -0.4694716f, -0.4848096f,
-0.5000000f, -0.5150381f, -0.5299193f, -0.5446390f, -0.5591929f, -0.5735764f,
-0.5877853f, -0.6018150f, -0.6156615f, -0.6293204f, -0.6427876f, -0.6560590f,
-0.6691306f, -0.6819984f, -0.6946584f, -0.7071068f, -0.7193398f, -0.7313537f,
-0.7431448f, -0.7547096f, -0.7660444f, -0.7771460f, -0.7880108f, -0.7986355f,
-0.8090170f, -0.8191520f, -0.8290376f, -0.8386706f, -0.8480481f, -0.8571673f,
-0.8660254f, -0.8746197f, -0.8829476f, -0.8910065f, -0.8987940f, -0.9063078f,
-0.9135455f, -0.9205049f, -0.9271839f, -0.9335804f, -0.9396926f, -0.9455186f,
-0.9510565f, -0.9563048f, -0.9612617f, -0.9659258f, -0.9702957f, -0.9743701f,
-0.9781476f, -0.9816272f, -0.9848078f, -0.9876883f, -0.9902681f, -0.9925462f,
-0.9945219f, -0.9961947f, -0.9975641f, -0.9986295f, -0.9993908f, -0.9998477f,
-1.0000000f, -0.9998477f, -0.9993908f, -0.9986295f, -0.9975641f, -0.9961947f,
-0.9945219f, -0.9925462f, -0.9902681f, -0.9876883f, -0.9848078f, -0.9816272f,
-0.9781476f, -0.9743701f, -0.9702957f, -0.9659258f, -0.9612617f, -0.9563048f,
-0.9510565f, -0.9455186f, -0.9396926f, -0.9335804f, -0.9271839f, -0.9205049f,
-0.9135455f, -0.9063078f, -0.8987940f, -0.8910065f, -0.8829476f, -0.8746197f,
-0.8660254f, -0.8571673f, -0.8480481f, -0.8386706f, -0.8290376f, -0.8191520f,
-0.8090170f, -0.7986355f, -0.7880108f, -0.7771460f, -0.7660444f, -0.7547096f,
-0.7431448f, -0.7313537f, -0.7193398f, -0.7071068f, -0.6946584f, -0.6819984f,
-0.6691306f, -0.6560590f, -0.6427876f, -0.6293204f, -0.6156615f, -0.6018150f,
-0.5877853f, -0.5735764f, -0.5591929f, -0.5446390f, -0.5299193f, -0.5150381f,
-0.5000000f, -0.4848096f, -0.4694716f, -0.4539905f, -0.4383711f, -0.4226183f,
-0.4067366f, -0.3907311f, -0.3746066f, -0.3583679f, -0.3420201f, -0.3255682f,
-0.3090170f, -0.2923717f, -0.2756374f, -0.2588190f, -0.2419219f, -0.2249511f,
-0.2079117f, -0.1908090f, -0.1736482f, -0.1564345f, -0.1391731f, -0.1218693f,
-0.1045285f, -0.0871557f, -0.0697565f, -0.0523360f, -0.0348995f, -0.0174524f,
-0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f,
0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f,
0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f,
0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f,
0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f,
0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f,
0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f,
0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f,
0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f,
0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f,
0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f,
0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f,
0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f,
0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f,
0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f,
1.0000000f
};
void
icvSinCos( int angle, float *cosval, float *sinval )
{
angle += (angle < 0 ? 360 : 0);
*sinval = icvSinTable[angle];
*cosval = icvSinTable[450 - angle];
}
/*
constructs polygon that represents elliptic arc.
*/
static int
icvEllipse2Poly( CvPoint center, CvSize axes,
int angle, int arc_start, int arc_end, CvPoint * pts, int delta )
{
float alpha, beta;
float size_a = (float) axes.width, size_b = (float) axes.height;
float arc_al, arc_be;
float da, db;
float cx, cy;
CvPoint *pts_origin = pts;
int i;
cx = (float) center.x;
cy = (float) center.y;
while( angle < 0 )
angle += 360;
while( angle > 360 )
angle -= 360;
if( arc_start > arc_end )
{
i = arc_start;
arc_start = arc_end;
arc_end = i;
}
while( arc_start < 0 )
{
arc_start += 360;
arc_end += 360;
}
while( arc_end > 360 )
{
arc_end -= 360;
arc_start -= 360;
}
if( arc_end - arc_start > 360 )
{
arc_start = 0;
arc_end = 360;
}
icvSinCos( angle, &alpha, &beta );
icvSinCos( arc_start, &arc_al, &arc_be );
icvSinCos( delta, &da, &db );
for( i = arc_start; i < arc_end + delta; i += delta, pts++ )
{
float x, y;
if( i > arc_end )
{
icvSinCos( arc_end, &arc_al, &arc_be );
}
x = size_a * arc_al;
y = size_b * arc_be;
pts->x = cvRound( cx + x * alpha - y * beta );
pts->y = cvRound( cy - x * beta - y * alpha );
x = arc_al * da - arc_be * db;
arc_be = arc_al * db + arc_be * da;
arc_al = x;
}
return pts - pts_origin;
}
typedef enum CvEllipseKind
{
Ellipse_Antialiazed = -1,
Ellipse_Filled = 0,
Ellipse_Simple = 1
} CvEllipseKind;
static void
icvEllipseEx( CvMat* mat, CvPoint center, CvSize axes,
int angle, int arc_start, int arc_end,
CvEllipseKind kind, int scale,
int thickness, const void* color )
{
CvMemStorage* st = 0;
CV_FUNCNAME( "icvEllipseEx" );
__BEGIN__;
CvPoint pts[1 << 8];
int npts;
if( (axes.width | axes.height) < 0 )
CV_ERROR( CV_StsBadSize, "" );
if( (unsigned)scale > XY_SHIFT )
CV_ERROR( CV_StsBadFlag, "" );
if( thickness < 0 )
CV_ERROR( CV_StsBadFlag, "" );
assert( kind == Ellipse_Antialiazed || scale == 0 );
npts = icvEllipse2Poly( center, axes, angle, arc_start, arc_end,
pts, kind == Ellipse_Filled ? 2 : 2 );
switch (kind)
{
case Ellipse_Simple:
CV_CALL( icvPolyLine( mat, pts, npts, 0, thickness, color ));
break;
case Ellipse_Filled:
if( arc_end - arc_start >= 360 )
{
CV_CALL( icvFillConvexPoly( mat, pts, npts, color ));
}
else
{
CvContour* edges;
CvSeq vtx;
CvSeqBlock block;
CV_CALL( st = cvCreateMemStorage( (1<<12) - 128 ));
CV_CALL( edges = (CvContour*)cvCreateSeq( 0, sizeof(CvContour),
sizeof(CvPolyEdge), st ));
pts[npts++] = center;
CV_CALL( cvMakeSeqHeaderForArray( 0, sizeof(CvSeq), sizeof(CvPoint),
pts, npts, &vtx, &block ));
CV_CALL( icvCollectPolyEdges( mat, &vtx, edges, color ));
CV_CALL( icvFillEdgeCollection( mat, edges, color ));
}
break;
case Ellipse_Antialiazed:
CV_CALL( icvPolyLineAA( mat, pts, npts, 0, scale, color ));
break;
default:
CV_ERROR( CV_StsBadFlag, "" );
}
__END__;
if( st )
cvReleaseMemStorage( &st );
}
/****************************************************************************************\
* Polygons filling *
\****************************************************************************************/
/* helper macros: filling horizontal row */
#define ICV_HLINE( ptr, xl, xr, color, pix_size ) \
{ \
uchar* hline_ptr = (uchar*)(ptr) + (xl)*(pix_size); \
uchar* hline_max_ptr = (uchar*)(ptr) + (xr)*(pix_size); \
\
for( ; hline_ptr <= hline_max_ptr; hline_ptr += (pix_size))\
{ \
int hline_j; \
for( hline_j = 0; hline_j < (pix_size); hline_j++ ) \
{ \
hline_ptr[hline_j] = ((uchar*)color)[hline_j]; \
} \
} \
}
/* filling convex polygon. v - array of vertices, ntps - number of points */
static void
icvFillConvexPoly( CvMat* img, CvPoint *v, int npts, const void* color )
{
const int scale = 16;
const int delta = 1 << (scale - 1);
struct
{
int idx, di;
int x, dx, ye;
}
edge[2];
int i, y, imin = 0, left = 0, right = 1, x1, x2;
int edges = npts;
int xmin = SHRT_MAX, ymin = xmin, xmax = SHRT_MIN, ymax = xmax;
uchar* ptr = img->data.ptr;
CvSize size = icvGetMatSize( img );
int pix_size = icvPixSize[CV_MAT_TYPE(img->type)];
CvPoint p0;
p0 = v[npts - 1];
//icvPolyLine( img, v, npts, 0, 1, color );
for( i = 0; i < npts; i++ )
{
CvPoint p = v[i];
int mask = p.y < ymin ? -1 : 0;
imin ^= (imin ^ i) & mask;
ymin ^= (ymin ^ p.y) & mask;
ymax = CV_MAX( ymax, p.y );
xmax = CV_MAX( xmax, p.x );
xmin = CV_MIN( xmin, p.x );
icvLine( img, p0, p, color, 8 );
p0 = p;
}
if( npts < 3 || (ymax | xmax) < 0 || ymin >= size.height || xmin >= size.width )
return;
ymax = CV_MIN( ymax, size.height - 1 );
edge[0].idx = edge[1].idx = imin;
y = v[imin].y;
edge[0].ye = edge[1].ye = y;
edge[0].di = 1;
edge[1].di = npts - 1;
ptr += img->step * y;
do
{
for( i = 0; i < 2; i++ )
{
if( y == edge[i].ye )
{
int idx = edge[i].idx, di = edge[i].di;
int xs = 0, xe, ye;
while( y >= v[idx].y && edges > 0 )
{
xs = v[idx].x;
idx += di;
idx -= ((idx < npts) - 1) & npts; /* idx -= idx >= npts ? npts : 0 */
edges--;
}
ye = v[idx].y;
xe = v[idx].x;
/* no more edges */
if( y >= ye )
return;
edge[i].ye = ye;
edge[i].dx = (((xe - xs) << (scale + 1)) + (ye - y)) / (2 * (ye - y));
edge[i].x = xs << scale;
edge[i].idx = idx;
}
}
if( edge[left].x > edge[right].x )
{
left ^= 1;
right ^= 1;
}
x1 = edge[left].x;
x2 = edge[right].x;
if( y >= 0 )
{
int xx1 = (x1 + delta) >> scale;
int xx2 = (x2 + delta) >> scale;
if( xx2 >= 0 && xx1 < size.width )
{
if( xx1 < 0 )
xx1 = 0;
if( xx2 >= size.width )
xx2 = size.width - 1;
ICV_HLINE( ptr, xx1, xx2, color, pix_size );
}
}
x1 += edge[left].dx;
x2 += edge[right].dx;
edge[left].x = x1;
edge[right].x = x2;
ptr += img->step;
}
while( ++y <= ymax );
}
/******** Arbitrary polygon **********/
static void
icvCollectPolyEdges( CvMat* img, CvSeq* v, CvContour* edges, const void* color )
{
int i, count = v->total;
CvRect bounds = edges->rect;
CvSeqReader reader;
CvSeqWriter writer;
cvStartReadSeq( v, &reader );
cvStartAppendToSeq( (CvSeq*)edges, &writer );
for( i = 0; i < count; i++ )
{
CvPoint pt0, pt1;
CvPolyEdge edge;
CV_READ_EDGE( pt0, pt1, reader );
icvLine( img, pt0, pt1, color );
if( pt0.y == pt1.y )
continue;
if( pt0.y > pt1.y )
{
CvPoint t;
CV_SWAP( pt0, pt1, t );
}
bounds.y = CV_MIN( bounds.y, pt0.y );
bounds.height = CV_MAX( bounds.height, pt1.y );
if( pt0.x < pt1.x )
{
bounds.x = CV_MIN( bounds.x, pt0.x );
bounds.width = CV_MAX( bounds.width, pt1.x );
}
else
{
bounds.x = CV_MIN( bounds.x, pt1.x );
bounds.width = CV_MAX( bounds.width, pt0.x );
}
edge.y0 = pt0.y;
edge.y1 = pt1.y;
edge.x = pt0.x << 16;
edge.dx = ((pt1.x - pt0.x) << 16) / (pt1.y - pt0.y);
CV_WRITE_SEQ_ELEM( edge, writer );
}
edges->rect = bounds;
cvEndWriteSeq( &writer );
}
#define ICV_CMP_EDGES( e1, e2 ) \
((e1).y0 < (e2).y0 || (e1).y0 == (e2).y0 && \
((e1).x < (e2).x || (e1).x == (e2).x && (e1).dx <= (e2).dx))
static
CV_IMPLEMENT_SEQ_QSORT( icvSortPolyEdges, CvPolyEdge, ICV_CMP_EDGES );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?