cvsegment.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 587 行 · 第 1/2 页

SVN-BASE
587
字号
            d[0] = src[0] - src[-3];
            ad[0] = CV_IABS(d[0]);

            d[1] = src[1] - src[-2];
            ad[1] = CV_IABS(d[1]);

            d[2] = src[2] - src[-1];
            ad[2] = CV_IABS(d[2]);

            f0 = ad[1] > ad[0];
            f1 = ad[2] > ad[f0];  

            val = d[tab[f0*2 + f1]];

            d[0] = src[0] - src[-src_step];
            ad[0] = CV_IABS(d[0]);

            d[1] = src[1] - src[1-src_step];
            ad[1] = CV_IABS(d[1]);

            d[2] = src[2] - src[2-src_step];
            ad[2] = CV_IABS(d[2]);

            f0 = ad[1] > ad[0];
            f1 = ad[2] > ad[f0];  

            dst[x] = (uchar)(val + d[tab[f0*2 + f1]] > thresh ? 255 : 0);*/
            dst[x] = (uchar)(val > thresh);
        }

        src = src0;
    }

}
#endif

const CvPoint icvCodeDeltas[8] =
    { {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} };

static CvSeq*
icvGetComponent( uchar* img, int step, CvRect rect,
                 CvMemStorage* storage )
{
    const char nbd = 4;
    int  deltas[16];
    int  x, y;
    CvSeq* exterior = 0;
    char* ptr;

    /* initialize local state */
    CV_INIT_3X3_DELTAS( deltas, step, 1 );
    memcpy( deltas + 8, deltas, 8 * sizeof( deltas[0] ));

    ptr = (char*)(img + step*rect.y);
    rect.width += rect.x;
    rect.height += rect.y;

    for( y = rect.y; y < rect.height; y++, ptr += step )
    {
        int prev = ptr[rect.x - 1] & -2;
        
        for( x = rect.x; x < rect.width; x++ )
        {
            int p = ptr[x] & -2;

            //assert( exterior || ((p | prev) & -4) == 0 );

            if( p != prev )
            {
                CvSeq *seq = 0;
                int is_hole = 0;
                CvSeqWriter  writer;
                char  *i0, *i1, *i3, *i4 = 0;
                int  prev_s = -1, s, s_end;
                CvPoint pt = { x, y };

                if( !(prev == 0 && p == 2) )    /* if not external contour */
                {
                    /* check hole */
                    if( p != 0 || prev < 1 )
                    {
                        prev = p;
                        continue;
                    }

                    is_hole = 1;
                    if( !exterior )
                    {
                        assert(0);
                        return 0;
                    }
                }

                cvStartWriteSeq( CV_SEQ_CONTOUR | (is_hole ? CV_SEQ_FLAG_HOLE : 0),
                                 sizeof(CvContour), sizeof(CvPoint), storage, &writer );
                s_end = s = is_hole ? 0 : 4;
                i0 = ptr + x - is_hole;

                do
                {
                    s = (s - 1) & 7;
                    i1 = i0 + deltas[s];
                    if( (*i1 & -2) != 0 )
                        break;
                }
                while( s != s_end );

                if( s == s_end )            /* single pixel domain */
                {
                    *i0 = (char) (nbd | -128);
                    CV_WRITE_SEQ_ELEM( pt, writer );
                }
                else
                {
                    i3 = i0;
                    prev_s = s ^ 4;

                    /* follow border */
                    for( ;; )
                    {
                        s_end = s;

                        for( ;; )
                        {
                            i4 = i3 + deltas[++s];
                            if( (*i4 & -2) != 0 )
                                break;
                        }
                        s &= 7;

                        /* check "right" bound */
                        if( (unsigned) (s - 1) < (unsigned) s_end )
                        {
                            *i3 = (char) (nbd | -128);
                        }
                        else if( *i3 > 0 )
                        {
                            *i3 = nbd;
                        }

                        if( s != prev_s )
                        {
                            CV_WRITE_SEQ_ELEM( pt, writer );
                            prev_s = s;
                        }

                        pt.x += icvCodeDeltas[s].x;
                        pt.y += icvCodeDeltas[s].y;

                        if( i4 == i0 && i3 == i1 )
                            break;

                        i3 = i4;
                        s = (s + 4) & 7;
                    }                       /* end of border following loop */
                }

                seq = cvEndWriteSeq( &writer );
                cvContourBoundingRect( seq, 1 );

                if( !is_hole )
                    exterior = seq;
                else
                {
                    seq->v_prev = exterior;
                    seq->h_next = exterior->v_next;
                    if( seq->h_next )
                        seq->h_next->h_prev = seq;
                    exterior->v_next = seq;
                }

                prev = ptr[x] & -2;
            }
        }
    }

    return exterior;
}



CV_IMPL CvSeq*
cvSegmentImage( const CvArr* srcarr, CvArr* dstarr,
                double canny_threshold,
                double ffill_threshold,
                CvMemStorage* storage )
{
    CvSeq* root = 0;
    CvMat* gray = 0;
    CvMat* canny = 0;
    //CvMat* temp = 0;
    void* stack = 0;
    
    CV_FUNCNAME( "cvSegmentImage" );

    __BEGIN__;

    CvMat srcstub, *src;
    CvMat dststub, *dst;
    CvMat* mask;
    CvSize size;
    CvPoint pt;
    int ffill_lw_up = cvRound( fabs(ffill_threshold) );
    CvSeq* prev_seq = 0;

    CV_CALL( src = cvGetMat( srcarr, &srcstub ));
    CV_CALL( dst = cvGetMat( dstarr, &dststub ));

    size = cvGetSize( src );

    CV_CALL( gray = cvCreateMat( size.height, size.width, CV_8UC1 ));
    CV_CALL( canny = cvCreateMat( size.height, size.width, CV_8UC1 ));
    //CV_CALL( temp = cvCreateMat( size.height/2, size.width/2, CV_8UC3 ));

    CV_CALL( stack = cvAlloc( size.width * size.height * sizeof(Seg)));

    cvCvtColor( src, gray, CV_BGR2GRAY );
    cvCanny( gray, canny, 0/*canny_threshold*0.4*/, canny_threshold, 3 );
    cvThreshold( canny, canny, 1, 1, CV_THRESH_BINARY );
    //cvZero( canny );
    //color_derv( src, canny, canny_threshold );

    //cvPyrDown( src, temp );
    //cvPyrUp( temp, dst );

    //src = dst;
    mask = canny; // a new name for new role

    // make a non-zero border.
    cvRectangle( mask, cvPoint(0,0), cvPoint(size.width-1,size.height-1), 1, 1 );

    for( pt.y = 0; pt.y < size.height; pt.y++ )
    {
        for( pt.x = 0; pt.x < size.width; pt.x++ )
        {
            if( mask->data.ptr[mask->step*pt.y + pt.x] == 0 )
            {
                CvConnectedComp region;
                int avgVal[3] = { 0, 0, 0 };
                
                icvSegmFloodFill_Stage1( src->data.ptr, src->step,
                                         mask->data.ptr, mask->step,
                                         size, pt, avgVal,
                                         ffill_lw_up, ffill_lw_up,
                                         &region, stack );

                /*avgVal[0] = (avgVal[0] + 15) & -32;
                if( avgVal[0] > 255 )
                    avgVal[0] = 255;
                avgVal[1] = (avgVal[1] + 15) & -32;
                if( avgVal[1] > 255 )
                    avgVal[1] = 255;
                avgVal[2] = (avgVal[2] + 15) & -32;
                if( avgVal[2] > 255 )
                    avgVal[2] = 255;*/

                if( storage )
                {
                    CvSeq* tmpseq = icvGetComponent( mask->data.ptr, mask->step,
                                                     region.rect, storage );
                    if( tmpseq != 0 )
                    {
                        ((CvContour*)tmpseq)->color =
                           CV_RGB(avgVal[2],avgVal[1],avgVal[0]);
                        tmpseq->h_prev = prev_seq;
                        if( prev_seq )
                            prev_seq->h_next = tmpseq;
                        else
                            root = tmpseq;
                        prev_seq = tmpseq;
                    }
                }

                icvSegmFloodFill_Stage2( dst->data.ptr, dst->step,
                                         mask->data.ptr, mask->step,
                                         size, avgVal,
                                         region.rect );
            }
        }
    }

    __END__;

    //cvReleaseMat( &temp );
    cvReleaseMat( &gray );
    cvReleaseMat( &canny );
    cvFree( &stack );

    return root;
}

/* End of file. */

⌨️ 快捷键说明

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