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 + -
显示快捷键?