cvcontours.cpp

来自「将OpenCV移植到DSP上」· C++ 代码 · 共 1,561 行 · 第 1/4 页

CPP
1,561
字号
            if( method < 0 )            {                char _s = (char) s;                CV_WRITE_SEQ_ELEM( _s, writer );            }            else if( s != prev_s || method == 0 )            {                CV_WRITE_SEQ_ELEM( pt, writer );            }            if( s != prev_s )            {                /* update bounds */                if( pt.x < rect.x )                    rect.x = pt.x;                else if( pt.x > rect.width )                    rect.width = pt.x;                if( pt.y < rect.y )                    rect.y = pt.y;                else if( pt.y > rect.height )                    rect.height = pt.y;            }            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 */    }    rect.width -= rect.x - 1;    rect.height -= rect.y - 1;    cvEndWriteSeq( &writer );    if( _method != CV_CHAIN_CODE )        ((CvContour*)contour)->rect = rect;    assert( writer.seq->total == 0 && writer.seq->first == 0 ||            writer.seq->total > writer.seq->first->count ||            (writer.seq->first->prev == writer.seq->first &&             writer.seq->first->next == writer.seq->first) );    if( _rect )  *_rect = rect;    return CV_OK;}CvSeq *cvFindNextContour( CvContourScanner scanner ){    char *img0;    char *img;    int step;    int width, height;    int x, y;    int prev;    CvPoint lnbd;    CvSeq *contour = 0;    int nbd;    int mode;    CvStatus result = (CvStatus) 1;    CV_FUNCNAME( "cvFindNextContour" );    __BEGIN__;    if( !scanner )        CV_ERROR( CV_StsNullPtr, "" );    icvEndProcessContour( scanner );    /* initialize local state */    img0 = scanner->img0;    img = scanner->img;    step = scanner->img_step;    x = scanner->pt.x;    y = scanner->pt.y;    width = scanner->img_size.width;    height = scanner->img_size.height;    mode = scanner->mode;    lnbd = scanner->lnbd;    nbd = scanner->nbd;    prev = img[x - 1];    for( ; y < height; y++, img += step )    {        for( ; x < width; x++ )        {            int p = img[x];            if( p != prev )            {                _CvContourInfo *par_info = 0;                _CvContourInfo *l_cinfo = 0;                CvSeq *seq = 0;                int is_hole = 0;                CvPoint origin;                if( !(prev == 0 && p == 1) )    /* if not external contour */                {                    /* check hole */                    if( p != 0 || prev < 1 )                        goto resume_scan;                    if( prev & -2 )                    {                        lnbd.x = x - 1;                    }                    is_hole = 1;                }                if( mode == 0 && (is_hole || img0[lnbd.y * step + lnbd.x] > 0) )                    goto resume_scan;                origin.y = y;                origin.x = x - is_hole;                /* find contour parent */                if( mode <= 1 || (!is_hole && mode == 2) || lnbd.x <= 0 )                {                    par_info = &(scanner->frame_info);                }                else                {                    int lval = img0[lnbd.y * step + lnbd.x] & 0x7f;                    _CvContourInfo *cur = scanner->cinfo_table[lval - 2];                    assert( lval >= 2 );                    /* find the first bounding contour */                    while( cur )                    {                        if( (unsigned) (lnbd.x - cur->rect.x) < (unsigned) cur->rect.width &&                            (unsigned) (lnbd.y - cur->rect.y) < (unsigned) cur->rect.height )                        {                            if( par_info )                            {                                if( icvTraceContour( scanner->img0 +                                                     par_info->origin.y * step +                                                     par_info->origin.x, step, img + lnbd.x,                                                     par_info->is_hole ) > 0 )                                    break;                            }                            par_info = cur;                        }                        cur = cur->next;                    }                    assert( par_info != 0 );                    /* if current contour is a hole and previous contour is a hole or                       current contour is external and previous contour is external then                       the parent of the contour is the parent of the previous contour else                       the parent is the previous contour itself. */                    if( par_info->is_hole == is_hole )                    {                        par_info = par_info->parent;                        /* every contour must have a parent                           (at least, the frame of the image) */                        if( !par_info )                            par_info = &(scanner->frame_info);                    }                    /* hole flag of the parent must differ from the flag of the contour */                    assert( par_info->is_hole != is_hole );                    if( par_info->contour == 0 )        /* removed contour */                        goto resume_scan;                }                lnbd.x = x - is_hole;                cvSaveMemStoragePos( scanner->storage2, &(scanner->backup_pos) );                seq = cvCreateSeq( scanner->seq_type1, scanner->header_size1,                                   scanner->elem_size1, scanner->storage1 );                if( !seq )                {                    result = CV_OUTOFMEM_ERR;                    goto exit_func;                }                seq->flags |= is_hole ? CV_SEQ_FLAG_HOLE : 0;                /* initialize header */                if( mode <= 1 )                {                    l_cinfo = &(scanner->cinfo_temp);                    result = icvFetchContour( img + x - is_hole, step,                                              cvPoint( origin.x + scanner->offset.x,                                                       origin.y + scanner->offset.y),                                              seq, scanner->approx_method1 );                    if( result < 0 )                        goto exit_func;                }                else                {                    union { _CvContourInfo* ci; CvSetElem* se; } v;                    v.ci = l_cinfo;                    cvSetAdd( scanner->cinfo_set, 0, &v.se );                    l_cinfo = v.ci;                    result = icvFetchContourEx( img + x - is_hole, step,                                                cvPoint( origin.x + scanner->offset.x,                                                         origin.y + scanner->offset.y),                                                seq, scanner->approx_method1,                                                nbd, &(l_cinfo->rect) );                    if( result < 0 )                        goto exit_func;                    l_cinfo->rect.x -= scanner->offset.x;                    l_cinfo->rect.y -= scanner->offset.y;                    l_cinfo->next = scanner->cinfo_table[nbd - 2];                    scanner->cinfo_table[nbd - 2] = l_cinfo;                    /* change nbd */                    nbd = (nbd + 1) & 127;                    nbd += nbd == 0 ? 3 : 0;                }                l_cinfo->is_hole = is_hole;                l_cinfo->contour = seq;                l_cinfo->origin = origin;                l_cinfo->parent = par_info;                if( scanner->approx_method1 != scanner->approx_method2 )                {                    result = icvApproximateChainTC89( (CvChain *) seq,                                                      scanner->header_size2,                                                      scanner->storage2,                                                      &(l_cinfo->contour),                                                      scanner->approx_method2 );                    if( result < 0 )                        goto exit_func;                    cvClearMemStorage( scanner->storage1 );                }                l_cinfo->contour->v_prev = l_cinfo->parent->contour;                if( par_info->contour == 0 )                {                    l_cinfo->contour = 0;                    if( scanner->storage1 == scanner->storage2 )                    {                        cvRestoreMemStoragePos( scanner->storage1, &(scanner->backup_pos) );                    }                    else                    {                        cvClearMemStorage( scanner->storage1 );                    }                    p = img[x];                    goto resume_scan;                }                cvSaveMemStoragePos( scanner->storage2, &(scanner->backup_pos2) );                scanner->l_cinfo = l_cinfo;                scanner->pt.x = x + 1;                scanner->pt.y = y;                scanner->lnbd = lnbd;                scanner->img = (char *) img;                scanner->nbd = nbd;                contour = l_cinfo->contour;                result = CV_OK;                goto exit_func;              resume_scan:                prev = p;                /* update lnbd */                if( prev & -2 )                {                    lnbd.x = x;                }            }                   /* end of prev != p */        }                       /* end of loop on x */        lnbd.x = 0;        lnbd.y = y + 1;        x = 1;        prev = 0;    }                           /* end of loop on y */  exit_func:    if( result != 0 )        contour = 0;    if( result < 0 )        CV_ERROR_FROM_STATUS( result );    __END__;    return contour;}/*    The function add to tree the last retrieved/substituted contour,    releases temp_storage, restores state of dst_storage (if needed), and   returns pointer to root of the contour tree */CV_IMPL CvSeq *cvEndFindContours( CvContourScanner * _scanner ){    CvContourScanner scanner;    CvSeq *first = 0;    CV_FUNCNAME( "cvFindNextContour" );    __BEGIN__;    if( !_scanner )        CV_ERROR( CV_StsNullPtr, "" );    scanner = *_scanner;    if( scanner )    {        icvEndProcessContour( scanner );        if( scanner->storage1 != scanner->storage2 )            cvReleaseMemStorage( &(scanner->storage1) );        if( scanner->cinfo_storage )            cvReleaseMemStorage( &(scanner->cinfo_storage) );        first = scanner->frame.v_next;        cvFree( _scanner );    }    __END__;    return first;}#define ICV_SINGLE                  0#define ICV_CONNECTING_ABOVE        1#define ICV_CONNECTING_BELOW        -1#define ICV_IS_COMPONENT_POINT(val) ((val) != 0)#define CV_GET_WRITTEN_ELEM( writer ) ((writer).ptr - (writer).seq->elem_size)typedef  struct CvLinkedRunPoint{    struct CvLinkedRunPoint* link;    struct CvLinkedRunPoint* next;    CvPoint pt;}CvLinkedRunPoint;static inticvFindContoursInInterval( const CvArr* src,                           /*int minValue, int maxValue,*/                           CvMemStorage* storage,                           CvSeq** result,                           int contourHeaderSize ){    int count = 0;    CvMemStorage* storage00 = 0;    CvMemStorage* storage01 = 0;    CvSeq* first = 0;    CV_FUNCNAME( "icvFindContoursInInterval" );    __BEGIN__;    int i, j, k, n;    uchar*  src_data = 0;    int  img_step = 0;    CvSize  img_size;    int  connect_flag;    int  lower_total;    int  upper_total;    int  all_total;    CvSeq*  runs;    CvLinkedRunPoint  tmp;    CvLinkedRunPoint*  tmp_prev;    CvLinkedRunPoint*  upper_line = 0;    CvLinkedRunPoint*  lower_line = 0;    CvLinkedRunPoint*  last_elem;    CvLinkedRunPoint*  upper_run = 0;    CvLinkedRunPoint*  lower_run = 0;    CvLinkedRunPoint*  prev_point = 0;

⌨️ 快捷键说明

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