⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cxdrawing.c

📁 Xilinx ISE&EDK 8.2平台的人脸检测系统设计
💻 C
📖 第 1 页 / 共 5 页
字号:
    *sinval = icvSinTable[angle];
    *cosval = icvSinTable[450 - angle];
}

/* 
   constructs polygon that represents elliptic arc.
*/
CV_IMPL int
cvEllipse2Poly( CvPoint center, CvSize axes, int angle,
                int arc_start, int arc_end, CvPoint* pts, int delta )
{
    float alpha, beta;
    double size_a = axes.width, size_b = axes.height;
    double cx = center.x, cy = center.y;
    CvPoint *pts_origin = pts;
    int i;

    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 );

    for( i = arc_start; i < arc_end + delta; i += delta )
    {
        double x, y;
        angle = i;
        if( angle > arc_end )
            angle = arc_end;
        if( angle < 0 )
            angle += 360;
        
        x = size_a * icvSinTable[450-angle];
        y = size_b * icvSinTable[angle];
        pts->x = cvRound( cx + x * alpha - y * beta );
        pts->y = cvRound( cy - x * beta - y * alpha );
        pts += i == arc_start || pts->x != pts[-1].x || pts->y != pts[-1].y;
    }

    i = (int)(pts - pts_origin);
    for( ; i < 2; i++ )
        pts_origin[i] = pts_origin[i-1];
    return i;
}


static void
icvEllipseEx( CvMat* img, CvPoint center, CvSize axes,
              int angle, int arc_start, int arc_end,
              const void* color, int thickness, int line_type )
{
    CvMemStorage* st = 0;

    CV_FUNCNAME( "icvEllipseEx" );
    
    __BEGIN__

    CvPoint v[1 << 8];
    int count, delta;

    if( axes.width < 0 || axes.height < 0 )
        CV_ERROR( CV_StsBadSize, "" );

    delta = (MAX(axes.width,axes.height)+(XY_ONE>>1))>>XY_SHIFT;
    delta = delta < 3 ? 90 : delta < 10 ? 30 : delta < 15 ? 18 : 5;

    count = cvEllipse2Poly( center, axes, angle, arc_start, arc_end, v, delta );

    if( thickness >= 0 )
    {
        icvPolyLine( img, v, count, 0, color, thickness, line_type, XY_SHIFT );
    }
    else if( arc_end - arc_start >= 360 )
    {
        icvFillConvexPoly( img, v, count, color, line_type, XY_SHIFT );
    }
    else
    {
        CvContour* edges;
        CvSeq vtx;
        CvSeqBlock block;
        
        CV_CALL( st = cvCreateMemStorage( CV_DRAWING_STORAGE_BLOCK ));
        CV_CALL( edges = (CvContour*)cvCreateSeq( 0, sizeof(CvContour), sizeof(CvPolyEdge), st ));
        v[count++] = center;

        CV_CALL( cvMakeSeqHeaderForArray( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint),
                                          v, count, &vtx, &block ));

        CV_CALL( icvCollectPolyEdges( img, &vtx, edges, color, line_type, XY_SHIFT, cvPoint(0,0) ));
        CV_CALL( icvFillEdgeCollection( img, edges, color ));
    }

    __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, int line_type, int shift )
{
    struct
    {
        int idx, di;
        int x, dx, ye;
    }
    edge[2];

    int delta = shift ? 1 << (shift - 1) : 0;
    int i, y, imin = 0, left = 0, right = 1, x1, x2;
    int edges = npts;
    int xmin, xmax, ymin, ymax;
    uchar* ptr = img->data.ptr;
    CvSize size = cvGetMatSize( img );
    int pix_size = CV_ELEM_SIZE(img->type);
    CvPoint p0;
    int delta1, delta2;

    if( line_type < CV_AA )
        delta1 = delta2 = XY_ONE >> 1;
        //delta1 = 0, delta2 = XY_ONE - 1;
    else
        delta1 = XY_ONE - 1, delta2 = 0;

    p0 = v[npts - 1];
    p0.x <<= XY_SHIFT - shift;
    p0.y <<= XY_SHIFT - shift;

    assert( 0 <= shift && shift <= XY_SHIFT );
    xmin = xmax = v[0].x;
    ymin = ymax = v[0].y;

    for( i = 0; i < npts; i++ )
    {
        CvPoint p = v[i];
        if( p.y < ymin )
        {
            ymin = p.y;
            imin = i;
        }

        ymax = MAX( ymax, p.y );
        xmax = MAX( xmax, p.x );
        xmin = MIN( xmin, p.x );

        p.x <<= XY_SHIFT - shift;
        p.y <<= XY_SHIFT - shift;

        if( line_type <= 8 )
        {
            if( shift == 0 )
            {
                CvPoint pt0, pt1;
                pt0.x = p0.x >> XY_SHIFT;
                pt0.y = p0.y >> XY_SHIFT;
                pt1.x = p.x >> XY_SHIFT;
                pt1.y = p.y >> XY_SHIFT;
                icvLine( img, pt0, pt1, color, line_type );
            }
            else
                icvLine2( img, p0, p, color );
        }
        else
            icvLineAA( img, p0, p, color );
        p0 = p;
    }

    xmin = (xmin + delta) >> shift;
    xmax = (xmax + delta) >> shift;
    ymin = (ymin + delta) >> shift;
    ymax = (ymax + delta) >> shift;

    if( npts < 3 || xmax < 0 || ymax < 0 || xmin >= size.width || ymin >= size.height )
        return;

    ymax = MIN( ymax, size.height - 1 );
    edge[0].idx = edge[1].idx = imin;

    edge[0].ye = edge[1].ye = y = ymin;
    edge[0].di = 1;
    edge[1].di = npts - 1;

    ptr += img->step*y;

    do
    {
        if( line_type < CV_AA || y < ymax || y == ymin )
        {
            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, ty = 0;

                    for(;;)
                    {
                        ty = (v[idx].y + delta) >> shift;
                        if( ty > y || edges == 0 )
                            break;
                        xs = v[idx].x;
                        idx += di;
                        idx -= ((idx < npts) - 1) & npts;   /* idx -= idx >= npts ? npts : 0 */
                        edges--;
                    }

                    ye = ty;
                    xs <<= XY_SHIFT - shift;
                    xe = v[idx].x << (XY_SHIFT - shift);

                    /* no more edges */
                    if( y >= ye )
                        return;

                    edge[i].ye = ye;
                    edge[i].dx = ((xe - xs)*2 + (ye - y)) / (2 * (ye - y));
                    edge[i].x = xs;
                    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 + delta1) >> XY_SHIFT;
            int xx2 = (x2 + delta2) >> XY_SHIFT;

            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 line_type, int shift,
                     CvPoint offset )
{
    int  i, count = v->total;
    CvRect bounds = edges->rect;
    int delta = offset.y + (shift ? 1 << (shift - 1) : 0);
    int elem_type = CV_MAT_TYPE(v->flags);

    CvSeqReader reader;
    CvSeqWriter writer;

    cvStartReadSeq( v, &reader, 0 );
    cvStartAppendToSeq( (CvSeq*)edges, &writer );

    for( i = 0; i < count; i++ )
    {
        CvPoint pt0, pt1, t0, t1;
        CvPolyEdge edge;
        CV_READ_EDGE( pt0, pt1, reader );
        
        if( elem_type == CV_32SC2 )
        {
            pt0.x = (pt0.x + offset.x) << (XY_SHIFT - shift);
            pt0.y = (pt0.y + delta) >> shift;
            pt1.x = (pt1.x + offset.x) << (XY_SHIFT - shift);
            pt1.y = (pt1.y + delta) >> shift;
        }
        else
        {
            Cv32suf x, y;
            assert( shift == 0 );

            x.i = pt0.x; y.i = pt0.y;
            pt0.x = cvRound((x.f + offset.x) * XY_ONE);
            pt0.y = cvRound(y.f + offset.y);
            x.i = pt1.x; y.i = pt1.y;
            pt1.x = cvRound((x.f + offset.x) * XY_ONE);
            pt1.y = cvRound(y.f + offset.y);
        }

        if( line_type < CV_AA )
        {
            t0.y = pt0.y; t1.y = pt1.y;
            t0.x = (pt0.x + (XY_ONE >> 1)) >> XY_SHIFT;
            t1.x = (pt1.x + (XY_ONE >> 1)) >> XY_SHIFT;
            icvLine( img, t0, t1, color, line_type );
        }
        else
        {
            t0.x = pt0.x; t1.x = pt1.x;
            t0.y = pt0.y << XY_SHIFT;
            t1.y = pt1.y << XY_SHIFT;
            icvLineAA( img, t0, t1, color );
        }

        if( pt0.y == pt1.y )
            continue;

        if( pt0.y > pt1.y )
            CV_SWAP( pt0, pt1, t0 );

        bounds.y = MIN( bounds.y, pt0.y );
        bounds.height = MAX( bounds.height, pt1.y );

        if( pt0.x < pt1.x )
        {
            bounds.x = MIN( bounds.x, pt0.x );
            bounds.width = MAX( bounds.width, pt1.x );
        }
        else
        {
            bounds.x = MIN( bounds.x, pt1.x );
            bounds.width = MAX( bounds.width, pt0.x );
        }

        edge.y0 = pt0.y;
        edge.y1 = pt1.y;
        edge.x = pt0.x;
        edge.dx = (pt1.x - pt0.x) / (pt1.y - pt0.y);
        assert( edge.y0 < edge.y1 );

        CV_WRITE_SEQ_ELEM( edge, writer );
    }

    edges->rect = bounds;
    cvEndWriteSeq( &writer );
}

static int
icvCmpEdges( const void* _e1, const void* _e2, void* userdata )
{
    CvPolyEdge *e1 = (CvPolyEdge*)_e1, *e2 = (CvPolyEdge*)_e2;
    return e1->y0 - e2->y0 ? e1->y0 - e2->y0 :
           e1->x - e2->x ? e1->x - e2->x : e1->dx - e2->dx;
}

/**************** helper macros and functions for sequence/contour processing ***********/

static void
icvFillEdgeCollection( CvMat* img, CvContour* edges, const void* color )
{
    CvPolyEdge tmp;
    int i, y, total = edges->total;
    CvSeqReader reader;
    CvSize size = cvGetMatSize(img);
    CvPolyEdge* e;
    int y_max = INT_MIN;
    int pix_size = CV_ELEM_SIZE(img->type);

    __BEGIN__
    
    memset( &tmp, 0, sizeof(tmp));
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -