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

📄 cvpyrsegmentation.cpp

📁 opencv库在TI DM6437上的移植,目前包括两个库cv.lib和cxcore.lib的工程
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                                p_cur[j].c /= a;
                            }

                            cmp_node.data = p_cur + j;
                            CV_WRITE_SEQ_ELEM( cmp_node, writer );
                        }
                        else
                        {
                            p_cur[j].c = p_prev->c;
                        }

                        if( l == 0 )
                        {
                            p_prev = _CV_NEXT_BASE_C1(p_prev, (j * 2 < step - 2 ? 2 : 1));
                        }
                        else
                        {
                            p_prev++;
                        }
                    }
                }

                if( l + 1 == level && !is_last_iter )
                    for( j = 0; j <= size.width; j++ )
                        p_cur[j].a = 0;

                if( !(i & 1) )
                {
                    p_prev = p_row_prev;
                }
                else
                {
                    p_prev = (_CvPyramid*)((char*)p_row_prev + step *
                        (l == 0 ? sizeof(_CvPyramidBase) : sizeof(_CvPyramid)));
                }
            }
        }
    }                           /*  end of the iteration process  */

    /* construct a connected  components   */
    size.width = roi.width >> level;
    size.height = roi.height >> level;

    p_cur = pyram[level];

    for( i = 0; i < size.height; i++, p_cur += size.width + 1 )
    {
        for( j = 0; j < size.width; j++ )
        {
            if( p_cur[j].a != 0 )
            {
                cmp_node.data = p_cur + j;
                CV_WRITE_SEQ_ELEM( cmp_node, writer );
            }
        }
    }

    cvEndWriteSeq( &writer );

/* clusterization segmented components and construction 
   output connected components                            */
    icvSegmentClusterC1( cmp_seq, res_seq, threshold2, pyram[1], roi );

/* convert (inplace) resultant segment values to int (top level) */

/* propagate segment values top down */
    for( l = level - 1; l >= 0; l-- )
    {
        p_cur = pyram[l];

        size.width <<= 1;
        size.height <<= 1;

        if( l == 0 )
        {
            size.width--;
            size.height--;
        }

        for( i = 0; i <= size.height; i++ )
        {
            for( j = 0; j <= size.width; j++ )
            {
                _CvPyramid *p = p_cur->p;

                assert( p != 0 );
                if( p != &stub )
                    p_cur->c = p->c;

                if( l == 0 )
                {
                    Cv32suf _c;
                    /* copy the segmented values to destination image */
                    _c.f = p_cur->c; dst_image[j] = (uchar)_c.i;
                    p_cur = _CV_NEXT_BASE_C1(p_cur, 1);
                }
                else
                {
                    p_cur++;
                }
            }
            if( l == 0 )
                dst_image += dst_step;
        }
    }
  M_END:

    cvFree( &buffer );
    cvReleaseMemStorage( &temp_storage );

    if( status == CV_OK )
        *dst_comp = res_seq;

    return status;
}



/****************************************************************************************\
    color!!!  image segmentation by pyramid-linking   
\****************************************************************************************/
static CvStatus
icvPyrSegmentation8uC3R( uchar * src_image, int src_step,
                         uchar * dst_image, int dst_step,
                         CvSize roi, CvFilter filter,
                         CvSeq ** dst_comp, CvMemStorage * storage,
                         int level, int threshold1, int threshold2 )
{
    int i, j, l;

    int step;
    const int max_iter = 3;     /* maximum number of iterations */
    int cur_iter = 0;           /* current iteration */

    _CvPyramidC3 *pyram[16];    /* pointers to the pyramid down up to level */

    float *pyramida = 0;
    _CvPyramidC3 stub;

    _CvPyramidC3 *p_cur;
    _CvPyramidBaseC3 *p_base;
    _CvListNode cmp_node;

    CvSeq *cmp_seq = 0;
    CvSeq *res_seq = 0;
    CvMemStorage *temp_storage = 0;
    CvSize size;
    CvStatus status;
    CvSeqWriter writer;

    int buffer_size;
    char *buffer = 0;

    status = CV_OK;

    threshold1 *= _CV_RGB_THRESH_SCALE;
    threshold2 *= _CV_RGB_THRESH_SCALE;

    /* clear pointer to resultant sequence */
    if( dst_comp )
        *dst_comp = 0;

    /* check args */
    if( !src_image || !dst_image || !storage || !dst_comp )
        return CV_NULLPTR_ERR;
    if( roi.width <= 0 || roi.height <= 0 ||
        src_step < roi.width * 3 || dst_step < roi.width * 3 ) return CV_BADSIZE_ERR;
    if( filter != CV_GAUSSIAN_5x5 )
        return CV_BADRANGE_ERR;
    if( threshold1 < 0 || threshold2 < 0 )
        return CV_BADRANGE_ERR;
    if( level <= 0 )
        return CV_BADRANGE_ERR;

    if( ((roi.width | roi.height) & ((1 << level) - 1)) != 0 )
        return CV_BADCOEF_ERR;

    temp_storage = cvCreateChildMemStorage( storage );

    /* sequence for temporary components */
    cmp_seq = cvCreateSeq( 0, sizeof( CvSeq ), sizeof( _CvListNode ), temp_storage );
    assert( cmp_seq != 0 );

    res_seq = cvCreateSeq( CV_SEQ_CONNECTED_COMP, sizeof( CvSeq ),
                           sizeof( CvConnectedComp ), storage );
    assert( res_seq != 0 );

    /* calculate buffer size */
    buffer_size = roi.width * roi.height * (sizeof( _CvRGBf ) + sizeof( _CvPyramidBaseC3 ));

    for( l = 1; l <= level; l++ )
        buffer_size += ((roi.width >> l) + 1) * ((roi.height >> l) + 1) * sizeof(_CvPyramidC3);

    /* allocate buffer */
    buffer = (char *) cvAlloc( buffer_size );
    if( !buffer )
    {
        status = CV_OUTOFMEM_ERR;
        goto M_END;
    }

    pyramida = (float *) buffer;

    /* initialization pyramid-linking properties down up to level */
    step = roi.width * sizeof( _CvRGBf );

    {
        CvMat _src;
        CvMat _pyramida;
        cvInitMatHeader( &_src, roi.height, roi.width, CV_8UC3, src_image, src_step );
        cvInitMatHeader( &_pyramida, roi.height, roi.width, CV_32FC3, pyramida, step );
        cvConvert( &_src, &_pyramida );
        /*_CV_CHECK( icvCvtTo_32f_C1R( src_image, src_step, pyramida, step,
                                 cvSize( roi.width * 3, roi.height ), CV_8UC1 ));*/
    }

    p_base = (_CvPyramidBaseC3 *) (buffer + step * roi.height);
    pyram[0] = (_CvPyramidC3 *) p_base;

    /* fill base level of pyramid */
    for( i = 0; i < roi.height; i++ )
    {
        for( j = 0; j < roi.width; j++, p_base++ )
        {
            p_base->c = ((_CvRGBf *) pyramida)[i * roi.width + j];
            p_base->p = &stub;
        }
    }

    p_cur = (_CvPyramidC3 *) p_base;
    size = roi;

    /* calculate initial pyramid */
    for( l = 1; l <= level; l++ )
    {
        CvSize dst_size = { size.width/2 + 1, size.height/2 + 1 };
        CvMat prev_level = cvMat( size.height, size.width, CV_32FC3 );
        CvMat next_level = cvMat( dst_size.height, dst_size.width, CV_32FC3 );

        cvSetData( &prev_level, pyramida, step );
        cvSetData( &next_level, pyramida, step );
        cvPyrDown( &prev_level, &next_level );

        //_CV_CHECK( icvPyrDown_Gauss5x5_32f_C3R( pyramida, step, pyramida, step, size, buff ));
        //_CV_CHECK( icvPyrDownBorder_32f_CnR( pyramida, step, size, pyramida, step, dst_size, 3 ));
        pyram[l] = p_cur;

        size.width = dst_size.width - 1;
        size.height = dst_size.height - 1;

        /* fill layer #l */
        for( i = 0; i <= size.height; i++ )
        {
            assert( (char*)p_cur - buffer < buffer_size );
            for( j = 0; j <= size.width; j++, p_cur++ )
            {
                p_cur->c = ((_CvRGBf *) pyramida)[i * roi.width + j];
                p_cur->p = &stub;
                p_cur->a = 0;
                p_cur->rect.x2 = 0;
            }
        }
    }

    cvStartAppendToSeq( cmp_seq, &writer );

    /* do several iterations to determine son-father links */
    for( cur_iter = 0; cur_iter < max_iter; cur_iter++ )
    {
        int is_last_iter = cur_iter == max_iter - 1;

        size = roi;

        /* build son-father links down up to level */
        for( l = 0; l < level; l++ )
        {
            icvUpdatePyrLinks_8u_C3( l, pyram[l], size, pyram[l + 1], &writer,
                                      (float) threshold1, is_last_iter, &stub,
                                      (CvWriteNodeFunction)icvWritePyrNode );

            /* clear last border row */
            if( l > 0 )
            {
                p_cur = pyram[l] + (size.width + 1) * size.height;
                for( j = 0; j <= size.width; j++ )
                    p_cur[j].c.blue = p_cur[j].c.green = p_cur[j].c.red = 0;
            }

            size.width >>= 1;
            size.height >>= 1;
        }

/*  clear the old c value for the last level     */
        p_cur = pyram[level];
        for( i = 0; i <= size.height; i++, p_cur += size.width + 1 )
            for( j = 0; j <= size.width; j++ )
                p_cur[j].c.blue = p_cur[j].c.green = p_cur[j].c.red = 0;

        size = roi;
        step = roi.width;

/* calculate average c value for the 0 < l <=level   */
        for( l = 0; l < level; l++, step = (step >> 1) + 1 )
        {
            _CvPyramidC3 *p_prev, *p_row_prev;

            stub.c.blue = stub.c.green = stub.c.red = 0;

            /* calculate average c value for the next level   */
            if( l == 0 )
            {
                p_base = (_CvPyramidBaseC3 *) pyram[0];
                for( i = 0; i < roi.height; i++, p_base += size.width )
                {
                    for( j = 0; j < size.width; j++ )
                    {
                        _CvPyramidC3 *p = p_base[j].p;

                        p->c.blue += p_base[j].c.blue;
                        p->c.green += p_base[j].c.green;
                        p->c.red += p_base[j].c.red;
                    }
                }
            }
            else
            {
                p_cur = pyram[l];
                for( i = 0; i < size.height; i++, p_cur += size.width + 1 )
                {
                    for( j = 0; j < size.width; j++ )
                    {
                        _CvPyramidC3 *p = p_cur[j].p;
                        float a = (float) p_cur[j].a;

                        p->c.blue += a * p_cur[j].c.blue;
                        p->c.green += a * p_cur[j].c.green;
                        p->c.red += a * p_cur[j].c.red;

                        if( !is_last_iter )
                            p_cur[j].a = 0;
                    }
                    if( !is_last_iter )
                        p_cur[size.width].a = 0;
                }
                if( !is_last_iter )
                {
                    for( j = 0; j <= size.width; j++ )
                    {
                        p_cur[j].a = 0;
                    }
                }
            }

            /* assign random values of the next level null c   */
            p_cur = pyram[l + 1];
            p_row_prev = p_prev = pyram[l];

            size.width >>= 1;
            size.height >>= 1;

            for( i = 0; i <= size.height; i++, p_cur += size.width + 1 )
            {
                if( i < size.height || !is_last_iter )
                {
                    for( j = 0; j < size.width; j++ )
                    {
                        int a = p_cur[j].a;

                        if( a != 0 )
                        {
                            float inv_a;

                            if( a <= _CV_INV_TAB_SIZE )
                            {
                                inv_a = icvInvTab[a - 1];
                            }
                            else
                            {
                                inv_a = 1.f / a;
                            }
                            p_cur[j].c.blue *= inv_a;
                            p_cur[j].c.green *= inv_a;
                            p_cur[j].c.red *= inv_a;
                        }
                        else
                        {
                            p_cur[j].c = p_prev->c;
                        }
                        
                        if( l == 0 )
                            p_prev = _CV_NEXT_BASE_C3( p_prev, 2 );
                        else
                            p_prev += 2;
                    }

                    if( p_cur[size.width].a == 0 )
                    {
                        p_cur[size.width].c = p_prev[(l != 0) - 1].c;
                    }
                    else
                    {
                        p_cur[size.width].c.blue /= p_cur[size.width].a;
                        p_cur[size.width].c.green /= p_cur[size.width].a;
                        p_cur[size.width].c.red /= p_cur[size.width].a;
                        if( is_last_iter )
                        {
                            cmp_node.data = p_cur + size.width;
                            CV_WRITE_SEQ_ELEM( cmp_node, writer );
                        }
                    }
                }
                else
                {
                    for( j = 0; j <= size.width; j++ )
                    {
                        int a = p_cur[j].a;

                        if( a != 0 )
                        {
                            float inv_a;

                            if( a <= _CV_INV_TAB_SIZE )
                            {
                                inv_a = icvInvTab[a - 1];
                            }
                            else
                            {
                                inv_a = 1.f / a;
                            }
                            p_cur[j].c.blue *= inv_a;
                            p_cur[j].c.green *= inv_a;
                            p_cur[j].c.red *= inv_a;

                            cmp_node.data = p_cur + j;
                            CV_WRITE_SEQ_ELEM( cmp_node, writer );
                        }
                        else
                        {
                            p_cur[j].c = p_prev->c;
                        }

                        if( l == 0 )
                        {
                            p_prev = _CV_NEXT_BASE_C3( p_prev, (j * 2 < step - 2 ? 2 : 1));
                        }
                        else
                        {
                            p_prev++;
                        }
                    }
                }

                if( l + 1 == level && !is_last_iter )
                    for( j = 0; j <= size.width; j++ )
                        p_cur[j].a = 0;

                if( !(i & 1) )
                {
                    p_prev = p_row_prev;
                }
                else
                {
                    p_prev = (_CvPyramidC3*)((char*)p_row_prev + step *
                        (l == 0 ? sizeof( _CvPyramidBaseC3 ) : sizeof( _CvPyramidC3 )));
                }
            }
        }
    }                           /*  end of the iteration process  */

    /* construct a connected  components   */
    size.width = roi.width >> level;

⌨️ 快捷键说明

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