opencv中cvLine的实现

来源:互联网 发布:限制玩手机的软件 编辑:程序博客网 时间:2024/06/18 14:56

//cxcore.h/* Draws 4-connected, 8-connected or antialiased line segment connecting two points */CVAPI(void)  cvLine( CvArr* img, CvPoint pt1, CvPoint pt2,                     CvScalar color, int thickness CV_DEFAULT(1),                     int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );//cxDrawing.cppCV_IMPL voidcvLine( CvArr* _img, CvPoint pt1, CvPoint pt2, CvScalar color,        int thickness, int line_type, int shift ){    cv::Mat img = cv::cvarrToMat(_img);    cv::line( img, pt1, pt2, color, thickness, line_type, shift );}//cxDrawing.cpp/****************************************************************************************\*                              External functions                                        *\****************************************************************************************/void line( Mat& img, Point pt1, Point pt2, const Scalar& color,           int thickness, int line_type, int shift ){    if( line_type == CV_AA && img.depth() != CV_8U )        line_type = 8;    CV_Assert( 0 <= thickness && thickness <= 255 );    CV_Assert( 0 <= shift && shift <= XY_SHIFT );    double buf[4];    scalarToRawData( color, buf, img.type(), 0 );    ThickLine( img, pt1, pt2, buf, thickness, line_type, 3, shift ); }static inline void scalarToRawData(const Scalar& s, void* buf, int type, int unroll_to=0){    int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);    switch(depth)    {    case CV_8U:        s.convertTo((uchar*)buf, cn, unroll_to);        break;    case CV_8S:        s.convertTo((schar*)buf, cn, unroll_to);        break;    case CV_16U:        s.convertTo((ushort*)buf, cn, unroll_to);        break;    case CV_16S:        s.convertTo((short*)buf, cn, unroll_to);        break;    case CV_32S:        s.convertTo((int*)buf, cn, unroll_to);        break;    case CV_32F:        s.convertTo((float*)buf, cn, unroll_to);        break;    case CV_64F:        s.convertTo((double*)buf, cn, unroll_to);        break;    default:        CV_Error(CV_StsUnsupportedFormat,"");    }}static voidThickLine( Mat& img, Point p0, Point p1, const void* color,           int thickness, int line_type, int flags, int shift ){    static const double INV_XY_ONE = 1./XY_ONE;    p0.x <<= XY_SHIFT - shift;    p0.y <<= XY_SHIFT - shift;    p1.x <<= XY_SHIFT - shift;    p1.y <<= XY_SHIFT - shift;    if( thickness <= 1 )    {        if( line_type < CV_AA )        {            if( line_type == 1 || line_type == 4 || shift == 0 )            {                p0.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;                p0.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;                p1.x = (p1.x + (XY_ONE>>1)) >> XY_SHIFT;                p1.y = (p1.y + (XY_ONE>>1)) >> XY_SHIFT;                Line( img, p0, p1, color, line_type );            }            else                Line2( img, p0, p1, color );        }        else            LineAA( img, p0, p1, color );    }    else    {        Point pt[4], dp = Point(0,0);        double dx = (p0.x - p1.x)*INV_XY_ONE, dy = (p1.y - p0.y)*INV_XY_ONE;        double r = dx * dx + dy * dy;        int i, oddThickness = thickness & 1;        thickness <<= XY_SHIFT - 1;        if( fabs(r) > DBL_EPSILON )        {            r = (thickness + oddThickness*XY_ONE*0.5)/std::sqrt(r);            dp.x = cvRound( dy * r );            dp.y = cvRound( dx * r );            pt[0].x = p0.x + dp.x;            pt[0].y = p0.y + dp.y;            pt[1].x = p0.x - dp.x;            pt[1].y = p0.y - dp.y;            pt[2].x = p1.x - dp.x;            pt[2].y = p1.y - dp.y;            pt[3].x = p1.x + dp.x;            pt[3].y = p1.y + dp.y;            FillConvexPoly( img, pt, 4, color, line_type, XY_SHIFT );        }        for( i = 0; i < 2; i++ )        {            if( flags & (i+1) )            {                if( line_type < CV_AA )                {                    Point center;                    center.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;                    center.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;                    Circle( img, center, (thickness + (XY_ONE>>1)) >> XY_SHIFT, color, 1 );                 }                else                {                    EllipseEx( img, p0, cvSize(thickness, thickness),                               0, 0, 360, color, -1, line_type );                }            }            p0 = p1;        }    }}static voidLine( Mat& img, Point pt1, Point pt2,      const void* color, int connectivity = 8 ){    if( connectivity == 0 )        connectivity = 8;    if( connectivity == 1 )        connectivity = 4;    LineIterator iterator(img, pt1, pt2, connectivity, true);    int i, count = iterator.count;    int pix_size = (int)img.elemSize();    for( i = 0; i < count; i++, ++iterator )    {        CV_MEMCPY_AUTO( *iterator, color, pix_size );    }}static voidLine2( Mat& img, Point pt1, Point pt2, const void* color ){    int dx, dy;    int ecount;    int ax, ay;    int i, j;    int x_step, y_step;    int cb = ((uchar*)color)[0];    int cg = ((uchar*)color)[1];    int cr = ((uchar*)color)[2];    int pix_size = (int)img.elemSize();    uchar *ptr = img.data, *tptr;    size_t step = img.step;    Size size = img.size();    //assert( img && (nch == 1 || nch == 3) && img.depth() == CV_8U );    pt1.x -= XY_ONE*2;    pt1.y -= XY_ONE*2;    pt2.x -= XY_ONE*2;    pt2.y -= XY_ONE*2;    ptr += img.step*2 + 2*pix_size;    size.width = ((size.width - 5) << XY_SHIFT) + 1;    size.height = ((size.height - 5) << XY_SHIFT) + 1;    if( !clipLine( size, pt1, pt2 ))        return;    dx = pt2.x - pt1.x;    dy = pt2.y - pt1.y;    j = dx < 0 ? -1 : 0;    ax = (dx ^ j) - j;    i = dy < 0 ? -1 : 0;    ay = (dy ^ i) - i;    if( ax > ay )    {        dx = ax;        dy = (dy ^ j) - j;        pt1.x ^= pt2.x & j;        pt2.x ^= pt1.x & j;        pt1.x ^= pt2.x & j;        pt1.y ^= pt2.y & j;        pt2.y ^= pt1.y & j;        pt1.y ^= pt2.y & j;        x_step = XY_ONE;        y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));        ecount = (pt2.x - pt1.x) >> XY_SHIFT;    }    else    {        dy = ay;        dx = (dx ^ i) - i;        pt1.x ^= pt2.x & i;        pt2.x ^= pt1.x & i;        pt1.x ^= pt2.x & i;        pt1.y ^= pt2.y & i;        pt2.y ^= pt1.y & i;        pt1.y ^= pt2.y & i;        x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));        y_step = XY_ONE;        ecount = (pt2.y - pt1.y) >> XY_SHIFT;    }    pt1.x += (XY_ONE >> 1);    pt1.y += (XY_ONE >> 1);    if( pix_size == 3 )    {        #define  ICV_PUT_POINT()    \        {                           \            tptr[0] = (uchar)cb;    \            tptr[1] = (uchar)cg;    \            tptr[2] = (uchar)cr;    \        }                tptr = ptr + ((pt2.x + (XY_ONE >> 1))>> XY_SHIFT)*3 +            ((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT)*step;        ICV_PUT_POINT();                if( ax > ay )        {            ptr += (pt1.x >> XY_SHIFT) * 3;            while( ecount >= 0 )            {                tptr = ptr + (pt1.y >> XY_SHIFT) * step;                ICV_PUT_POINT();                pt1.y += y_step;                ptr += 3;                ecount--;            }        }        else        {            ptr += (pt1.y >> XY_SHIFT) * step;            while( ecount >= 0 )            {                tptr = ptr + (pt1.x >> XY_SHIFT) * 3;                ICV_PUT_POINT();                pt1.x += x_step;                ptr += step;                ecount--;            }        }        #undef ICV_PUT_POINT    }    else if( pix_size == 1 )    {        #define  ICV_PUT_POINT()            \        {                                   \            tptr[0] = (uchar)cb;            \        }        tptr = ptr + ((pt2.x + (XY_ONE >> 1))>> XY_SHIFT) +            ((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT)*step;        ICV_PUT_POINT();        if( ax > ay )        {            ptr += (pt1.x >> XY_SHIFT);            while( ecount >= 0 )            {                tptr = ptr + (pt1.y >> XY_SHIFT) * step;                ICV_PUT_POINT();                pt1.y += y_step;                ptr++;                ecount--;            }        }        else        {            ptr += (pt1.y >> XY_SHIFT) * step;            while( ecount >= 0 )            {                tptr = ptr + (pt1.x >> XY_SHIFT);                ICV_PUT_POINT();                pt1.x += x_step;                ptr += step;                ecount--;            }        }        #undef ICV_PUT_POINT    }    else    {        #define  ICV_PUT_POINT()                \            for( j = 0; j < pix_size; j++ )     \                tptr[j] = ((uchar*)color)[j];        tptr = ptr + ((pt2.x + (XY_ONE >> 1))>> XY_SHIFT)*pix_size +            ((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT)*step;        ICV_PUT_POINT();                if( ax > ay )        {            ptr += (pt1.x >> XY_SHIFT) * pix_size;            while( ecount >= 0 )            {                tptr = ptr + (pt1.y >> XY_SHIFT) * step;                ICV_PUT_POINT();                pt1.y += y_step;                ptr += pix_size;                ecount--;            }        }        else        {            ptr += (pt1.y >> XY_SHIFT) * step;            while( ecount >= 0 )            {                tptr = ptr + (pt1.x >> XY_SHIFT) * pix_size;                ICV_PUT_POINT();                pt1.x += x_step;                ptr += step;                ecount--;            }        }        #undef ICV_PUT_POINT    }}static voidLineAA( Mat& img, Point pt1, Point pt2, const void* color ){    int dx, dy;    int ecount, scount = 0;    int slope;    int ax, ay;    int x_step, y_step;    int i, j;    int ep_table[9];    int cb = ((uchar*)color)[0], cg = ((uchar*)color)[1], cr = ((uchar*)color)[2];    int _cb, _cg, _cr;    int nch = img.channels();    uchar* ptr = img.data;    size_t step = img.step;    Size size = img.size();    if( !((nch == 1 || nch == 3) && img.depth() == CV_8U) )    {        Line(img, pt1, pt2, color);        return;    }    pt1.x -= XY_ONE*2;    pt1.y -= XY_ONE*2;    pt2.x -= XY_ONE*2;    pt2.y -= XY_ONE*2;    ptr += img.step*2 + 2*nch;    size.width = ((size.width - 5) << XY_SHIFT) + 1;    size.height = ((size.height - 5) << XY_SHIFT) + 1;    if( !clipLine( size, pt1, pt2 ))        return;    dx = pt2.x - pt1.x;    dy = pt2.y - pt1.y;    j = dx < 0 ? -1 : 0;    ax = (dx ^ j) - j;    i = dy < 0 ? -1 : 0;    ay = (dy ^ i) - i;    if( ax > ay )    {        dx = ax;        dy = (dy ^ j) - j;        pt1.x ^= pt2.x & j;        pt2.x ^= pt1.x & j;        pt1.x ^= pt2.x & j;        pt1.y ^= pt2.y & j;        pt2.y ^= pt1.y & j;        pt1.y ^= pt2.y & j;        x_step = XY_ONE;        y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));        pt2.x += XY_ONE;        ecount = (pt2.x >> XY_SHIFT) - (pt1.x >> XY_SHIFT);        j = -(pt1.x & (XY_ONE - 1));        pt1.y += (int) ((((int64) y_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);        slope = (y_step >> (XY_SHIFT - 5)) & 0x3f;        slope ^= (y_step < 0 ? 0x3f : 0);        /* Get 4-bit fractions for end-point adjustments */        i = (pt1.x >> (XY_SHIFT - 7)) & 0x78;        j = (pt2.x >> (XY_SHIFT - 7)) & 0x78;    }    else    {        dy = ay;        dx = (dx ^ i) - i;        pt1.x ^= pt2.x & i;        pt2.x ^= pt1.x & i;        pt1.x ^= pt2.x & i;        pt1.y ^= pt2.y & i;        pt2.y ^= pt1.y & i;        pt1.y ^= pt2.y & i;        x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));        y_step = XY_ONE;        pt2.y += XY_ONE;        ecount = (pt2.y >> XY_SHIFT) - (pt1.y >> XY_SHIFT);        j = -(pt1.y & (XY_ONE - 1));        pt1.x += (int) ((((int64) x_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);        slope = (x_step >> (XY_SHIFT - 5)) & 0x3f;        slope ^= (x_step < 0 ? 0x3f : 0);        /* Get 4-bit fractions for end-point adjustments */        i = (pt1.y >> (XY_SHIFT - 7)) & 0x78;        j = (pt2.y >> (XY_SHIFT - 7)) & 0x78;    }    slope = (slope & 0x20) ? 0x100 : SlopeCorrTable[slope];    /* Calc end point correction table */    {        int t0 = slope << 7;        int t1 = ((0x78 - i) | 4) * slope;        int t2 = (j | 4) * slope;        ep_table[0] = 0;        ep_table[8] = slope;        ep_table[1] = ep_table[3] = ((((j - i) & 0x78) | 4) * slope >> 8) & 0x1ff;        ep_table[2] = (t1 >> 8) & 0x1ff;        ep_table[4] = ((((j - i) + 0x80) | 4) * slope >> 8) & 0x1ff;        ep_table[5] = ((t1 + t0) >> 8) & 0x1ff;        ep_table[6] = (t2 >> 8) & 0x1ff;        ep_table[7] = ((t2 + t0) >> 8) & 0x1ff;    }    if( nch == 3 )    {        #define  ICV_PUT_POINT()            \        {                                   \            _cb = tptr[0];                  \            _cb += ((cb - _cb)*a + 127)>> 8;\            _cg = tptr[1];                  \            _cg += ((cg - _cg)*a + 127)>> 8;\            _cr = tptr[2];                  \            _cr += ((cr - _cr)*a + 127)>> 8;\            tptr[0] = (uchar)_cb;           \            tptr[1] = (uchar)_cg;           \            tptr[2] = (uchar)_cr;           \        }        if( ax > ay )        {            ptr += (pt1.x >> XY_SHIFT) * 3;            while( ecount >= 0 )            {                uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;                int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +                                       (((ecount >= 2) + 1) & (ecount | 2))];                int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;                a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                tptr += step;                a = (ep_corr * FilterTable[dist] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                tptr += step;                a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                pt1.y += y_step;                ptr += 3;                scount++;                ecount--;            }        }        else        {            ptr += (pt1.y >> XY_SHIFT) * step;            while( ecount >= 0 )            {                uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1) * 3;                int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +                                       (((ecount >= 2) + 1) & (ecount | 2))];                int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;                a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                tptr += 3;                a = (ep_corr * FilterTable[dist] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                tptr += 3;                a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                pt1.x += x_step;                ptr += step;                scount++;                ecount--;            }        }        #undef ICV_PUT_POINT    }    else    {        #define  ICV_PUT_POINT()            \        {                                   \            _cb = tptr[0];                  \            _cb += ((cb - _cb)*a + 127)>> 8;\            tptr[0] = (uchar)_cb;           \        }        if( ax > ay )        {            ptr += (pt1.x >> XY_SHIFT);            while( ecount >= 0 )            {                uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;                int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +                                       (((ecount >= 2) + 1) & (ecount | 2))];                int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;                a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                tptr += step;                a = (ep_corr * FilterTable[dist] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                tptr += step;                a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                pt1.y += y_step;                ptr++;                scount++;                ecount--;            }        }        else        {            ptr += (pt1.y >> XY_SHIFT) * step;            while( ecount >= 0 )            {                uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1);                int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +                                       (((ecount >= 2) + 1) & (ecount | 2))];                int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;                a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                tptr++;                a = (ep_corr * FilterTable[dist] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                tptr++;                a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;                ICV_PUT_POINT();                ICV_PUT_POINT();                pt1.x += x_step;                ptr += step;                scount++;                ecount--;            }        }        #undef ICV_PUT_POINT    }}


原创粉丝点击