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

📄 cvcontours.cpp

📁 将OpenCV移植到DSP上
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    CvSeqWriter  writer_ext;    CvSeqWriter  writer_int;    CvSeqWriter  writer;    CvSeqReader  reader;    CvSeq* external_contours;    CvSeq* internal_contours;    CvSeq* prev = 0;    if( !storage )        CV_ERROR( CV_StsNullPtr, "NULL storage pointer" );    if( !result )        CV_ERROR( CV_StsNullPtr, "NULL double CvSeq pointer" );    if( contourHeaderSize < (int)sizeof(CvContour))        CV_ERROR( CV_StsBadSize, "Contour header size must be >= sizeof(CvContour)" );    CV_CALL( storage00 = cvCreateChildMemStorage(storage));    CV_CALL( storage01 = cvCreateChildMemStorage(storage));    {        CvMat stub, *mat;        CV_CALL( mat = cvGetMat( src, &stub ));        if( !CV_IS_MASK_ARR(mat))            CV_ERROR( CV_StsBadArg, "Input array must be 8uC1 or 8sC1" );        src_data = mat->data.ptr;        img_step = mat->step;        img_size = cvGetMatSize( mat );    }    // Create temporary sequences    runs = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvLinkedRunPoint), storage00 );    cvStartAppendToSeq( runs, &writer );    cvStartWriteSeq( 0, sizeof(CvSeq), sizeof(CvLinkedRunPoint*), storage01, &writer_ext );    cvStartWriteSeq( 0, sizeof(CvSeq), sizeof(CvLinkedRunPoint*), storage01, &writer_int );    tmp_prev = &(tmp);    tmp_prev->next = 0;    tmp_prev->link = 0;        // First line. None of runs is binded    tmp.pt.y = 0;    i = 0;    CV_WRITE_SEQ_ELEM( tmp, writer );    upper_line = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer );        tmp_prev = upper_line;    for( j = 0; j < img_size.width; )    {        for( ; j < img_size.width && !ICV_IS_COMPONENT_POINT(src_data[j]); j++ )            ;        if( j == img_size.width )            break;        tmp.pt.x = j;        CV_WRITE_SEQ_ELEM( tmp, writer );        tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer );        tmp_prev = tmp_prev->next;        for( ; j < img_size.width && ICV_IS_COMPONENT_POINT(src_data[j]); j++ )            ;        tmp.pt.x = j-1;        CV_WRITE_SEQ_ELEM( tmp, writer );        tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer );        tmp_prev->link = tmp_prev->next;        // First point of contour        CV_WRITE_SEQ_ELEM( tmp_prev, writer_ext );        tmp_prev = tmp_prev->next;    }    cvFlushSeqWriter( &writer );    upper_line = upper_line->next;    upper_total = runs->total - 1;    last_elem = tmp_prev;    tmp_prev->next = 0;        for( i = 1; i < img_size.height; i++ )    {//------// Find runs in next line        src_data += img_step;        tmp.pt.y = i;        all_total = runs->total;        for( j = 0; j < img_size.width; )        {            for( ; j < img_size.width && !ICV_IS_COMPONENT_POINT(src_data[j]); j++ )                ;            if( j == img_size.width ) break;            tmp.pt.x = j;            CV_WRITE_SEQ_ELEM( tmp, writer );            tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer );            tmp_prev = tmp_prev->next;            for( ; j < img_size.width && ICV_IS_COMPONENT_POINT(src_data[j]); j++ )                ;            tmp.pt.x = j-1;            CV_WRITE_SEQ_ELEM( tmp, writer );            tmp_prev = tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer );        }//j        cvFlushSeqWriter( &writer );        lower_line = last_elem->next;        lower_total = runs->total - all_total;        last_elem = tmp_prev;        tmp_prev->next = 0;//------////------// Find links between runs of lower_line and upper_line        upper_run = upper_line;        lower_run = lower_line;        connect_flag = ICV_SINGLE;        for( k = 0, n = 0; k < upper_total/2 && n < lower_total/2; )        {            switch( connect_flag )            {            case ICV_SINGLE:                if( upper_run->next->pt.x < lower_run->next->pt.x )                {                    if( upper_run->next->pt.x >= lower_run->pt.x  -1 )                    {                        lower_run->link = upper_run;                        connect_flag = ICV_CONNECTING_ABOVE;                        prev_point = upper_run->next;                    }                    else                        upper_run->next->link = upper_run;                    k++;                    upper_run = upper_run->next->next;                }                else                {                    if( upper_run->pt.x <= lower_run->next->pt.x  +1 )                    {                        lower_run->link = upper_run;                        connect_flag = ICV_CONNECTING_BELOW;                        prev_point = lower_run->next;                    }                    else                    {                        lower_run->link = lower_run->next;                        // First point of contour                        CV_WRITE_SEQ_ELEM( lower_run, writer_ext );                    }                    n++;                    lower_run = lower_run->next->next;                }                break;            case ICV_CONNECTING_ABOVE:                if( upper_run->pt.x > lower_run->next->pt.x +1 )                {                    prev_point->link = lower_run->next;                    connect_flag = ICV_SINGLE;                    n++;                    lower_run = lower_run->next->next;                }                else                {                    prev_point->link = upper_run;                    if( upper_run->next->pt.x < lower_run->next->pt.x )                    {                        k++;                        prev_point = upper_run->next;                        upper_run = upper_run->next->next;                    }                    else                    {                        connect_flag = ICV_CONNECTING_BELOW;                        prev_point = lower_run->next;                        n++;                        lower_run = lower_run->next->next;                    }                }                break;            case ICV_CONNECTING_BELOW:                if( lower_run->pt.x > upper_run->next->pt.x +1 )                {                    upper_run->next->link = prev_point;                    connect_flag = ICV_SINGLE;                    k++;                    upper_run = upper_run->next->next;                }                else                {                    // First point of contour                    CV_WRITE_SEQ_ELEM( lower_run, writer_int );                    lower_run->link = prev_point;                    if( lower_run->next->pt.x < upper_run->next->pt.x )                    {                        n++;                        prev_point = lower_run->next;                        lower_run = lower_run->next->next;                    }                    else                    {                        connect_flag = ICV_CONNECTING_ABOVE;                        k++;                        prev_point = upper_run->next;                        upper_run = upper_run->next->next;                    }                }                break;                      }        }// k, n        for( ; n < lower_total/2; n++ )        {            if( connect_flag != ICV_SINGLE )            {                prev_point->link = lower_run->next;                connect_flag = ICV_SINGLE;                lower_run = lower_run->next->next;                continue;            }            lower_run->link = lower_run->next;            //First point of contour            CV_WRITE_SEQ_ELEM( lower_run, writer_ext );            lower_run = lower_run->next->next;        }        for( ; k < upper_total/2; k++ )        {            if( connect_flag != ICV_SINGLE )            {                upper_run->next->link = prev_point;                connect_flag = ICV_SINGLE;                upper_run = upper_run->next->next;                continue;            }            upper_run->next->link = upper_run;            upper_run = upper_run->next->next;        }        upper_line = lower_line;        upper_total = lower_total;    }//i    upper_run = upper_line;    //the last line of image    for( k = 0; k < upper_total/2; k++ )    {        upper_run->next->link = upper_run;        upper_run = upper_run->next->next;    }//------////------//Find end read contours    external_contours = cvEndWriteSeq( &writer_ext );    internal_contours = cvEndWriteSeq( &writer_int );    for( k = 0; k < 2; k++ )    {        CvSeq* contours = k == 0 ? external_contours : internal_contours;        cvStartReadSeq( contours, &reader );        for( j = 0; j < contours->total; j++, count++ )        {            CvLinkedRunPoint* p_temp;            CvLinkedRunPoint* p00;            CvLinkedRunPoint* p01;            CvSeq* contour;            CV_READ_SEQ_ELEM( p00, reader );            p01 = p00;            if( !p00->link )                continue;            cvStartWriteSeq( CV_SEQ_ELTYPE_POINT | CV_SEQ_POLYLINE | CV_SEQ_FLAG_CLOSED,                             contourHeaderSize, sizeof(CvPoint), storage, &writer );            do            {                CV_WRITE_SEQ_ELEM( p00->pt, writer );                p_temp = p00;                p00 = p00->link;                p_temp->link = 0;            }            while( p00 != p01 );            contour = cvEndWriteSeq( &writer );            cvBoundingRect( contour, 1 );            if( k != 0 )                contour->flags |= CV_SEQ_FLAG_HOLE;            if( !first )                prev = first = contour;            else            {                contour->h_prev = prev;                prev = prev->h_next = contour;            }        }    }    __END__;    if( !first )        count = -1;    if( result )        *result = first;    cvReleaseMemStorage(&storage00);    cvReleaseMemStorage(&storage01);    return count;}/*F/////////////////////////////////////////////////////////////////////////////////////////    Name: cvFindContours//    Purpose://      Finds all the contours on the bi-level image.//    Context://    Parameters://      img  - source image.//             Non-zero pixels are considered as 1-pixels//             and zero pixels as 0-pixels.//      step - full width of source image in bytes.//      size - width and height of the image in pixels//      storage - pointer to storage where will the output contours be placed.//      header_size - header size of resulting contours//      mode - mode of contour retrieval.//      method - method of approximation that is applied to contours//      first_contour - pointer to first contour pointer//    Returns://      CV_OK or error code//    Notes://F*/CV_IMPL intcvFindContours( void*  img,  CvMemStorage*  storage,                                CvSeq**  firstContour, int  cntHeaderSize,                                 int  mode,                 int  method, CvPoint offset ){    CvContourScanner scanner = 0;    CvSeq *contour = 0;    int count = -1;        CV_FUNCNAME( "cvFindContours" );    __BEGIN__;    if( !firstContour )        CV_ERROR( CV_StsNullPtr, "NULL double CvSeq pointer" );    if( method == CV_LINK_RUNS )    {        if( offset.x != 0 || offset.y != 0 )            CV_ERROR( CV_StsOutOfRange,            "Nonzero offset is not supported in CV_LINK_RUNS yet" );        CV_CALL( count = icvFindContoursInInterval( img, storage,                                    firstContour, cntHeaderSize ));    }    else    {        CV_CALL( scanner = cvStartFindContours( img, storage,                        cntHeaderSize, mode, method, offset ));        assert( scanner );        do        {            count++;            contour = cvFindNextContour( scanner );        }        while( contour != 0 );        *firstContour = cvEndFindContours( &scanner );        }    __END__;    return count;}/* End of file. */

⌨️ 快捷键说明

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