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

📄 cvpyrsegmentation.cpp

📁 opencv库在TI DM6437上的移植,目前包括两个库cv.lib和cxcore.lib的工程
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    _CvPyramid temp_cmp;
    _CvPyramidBase *first_level_start = (_CvPyramidBase *) first_level_end -
        first_level_size.width * first_level_size.height;
    int c, i, count = cmp_seq->total;

    cvStartReadSeq( cmp_seq, &reader, 0 );
    cvStartAppendToSeq( res_seq, &writer );

    if( threshold < eps )
    {
        /* if threshold is too small then simply copy all
           the components to the output sequence */
        for( i = 0; i < count; i++ )
        {
            CvConnectedComp comp;
            _CvPyramid *cmp = (_CvPyramid *) (((_CvListNode *) reader.ptr)->data);
            Cv32suf _c;

            if( cmp < first_level_end )
            {
                icvExpandBaseLevelC1( cmp, &temp_cmp, first_level_start,
                                      first_level_size.width );
                cmp = &temp_cmp;
            }

            _c.i = cvRound( cmp->c );
            cmp->c = _c.f;
            comp.value = cvRealScalar(_c.i);
            comp.area = cmp->a;
            comp.rect.x = cmp->rect.x1;
            comp.rect.y = cmp->rect.y1;
            comp.rect.width = cmp->rect.x2 - cmp->rect.x1;
            comp.rect.height = cmp->rect.y2 - cmp->rect.y1;
            comp.contour = 0;

            CV_WRITE_SEQ_ELEM( comp, writer );
            CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
        }
    }
    else
    {
        _CvListNode stub_node;
        _CvListNode *prev = &stub_node;

        stub_node.next = 0;

        for( i = 0; i < count; i++ )
        {
            _CvListNode *node = (_CvListNode *) reader.ptr;

            prev->next = node;
            prev = node;
            CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
        }
        prev->next = 0;
        prev = stub_node.next;

        while( prev )
        {
            _CvListNode *node = prev->next;
            _CvListNode *acc = prev;
            _CvPyramid *cmp = (_CvPyramid *) (acc->data);
            CvConnectedComp comp;
            float c0 = cmp->c;

            if( cmp < first_level_end )
            {
                icvExpandBaseLevelC1( cmp, &temp_cmp, first_level_start,
                                      first_level_size.width );
            }
            else
            {
                temp_cmp = *cmp;
                temp_cmp.c *= temp_cmp.a;
            }

            acc->next = 0;
            stub_node.next = 0;
            prev = &stub_node;

            while( node )
            {
                cmp = (_CvPyramid *) (node->data);
                if( fabs( c0 - cmp->c ) < threshold )
                {
                    _CvPyramid temp;

                    /* exclude from global list and add to list of joint component */
                    prev->next = node->next;
                    node->next = acc;
                    acc = node;

                    if( cmp < first_level_end )
                    {
                        icvExpandBaseLevelC1( cmp, &temp, first_level_start,
                                              first_level_size.width );
                        cmp = &temp;
                    }

                    temp_cmp.a += cmp->a;
                    temp_cmp.c += cmp->c * cmp->a;
                    icvMaxRoi( &(temp_cmp.rect), &(cmp->rect) );
                }
                else
                {
                    if( prev == &stub_node )
                    {
                        stub_node.next = node;
                    }
                    prev = node;
                }
                node = prev->next;
            }

            if( temp_cmp.a != 0 )
            {
                c = cvRound( temp_cmp.c / temp_cmp.a );
            }
            else
            {
                c = cvRound( c0 );
            }
            node = acc;

            while( node )
            {
                Cv32suf _c;
                cmp = (_CvPyramid *) (node->data);
                _c.i = c; cmp->c = _c.f;
                node = node->next;
            }

            comp.value = cvRealScalar(c);
            comp.area = temp_cmp.a;
            comp.rect.x = temp_cmp.rect.x1;
            comp.rect.y = temp_cmp.rect.y1;
            comp.rect.width = temp_cmp.rect.x2 - temp_cmp.rect.x1;
            comp.rect.height = temp_cmp.rect.y2 - temp_cmp.rect.y1;
            comp.contour = 0;

            CV_WRITE_SEQ_ELEM( comp, writer );
            prev = stub_node.next;
        }
    }

    cvEndWriteSeq( &writer );
    return CV_OK;
}

/****************************************************************************************\

    clusterization segmented components    

\****************************************************************************************/
static void
icvExpandBaseLevelC3( _CvPyramidC3 * base_p, _CvPyramidC3 * p,
                      _CvPyramidBaseC3 * start, int width )
{
    int x = (int)((_CvPyramidBaseC3 *) base_p - start);
    int y = x / width;

    x -= y * width;
    p->a = 1;
    p->rect.x1 = (ushort) x;
    p->rect.y1 = (ushort) y;
    p->rect.x2 = (ushort) (x + 1);
    p->rect.y2 = (ushort) (y + 1);
    p->c = base_p->c;
}

CvStatus
icvSegmentClusterC3( CvSeq * cmp_seq, CvSeq * res_seq,
                     double threshold,
                     _CvPyramidC3 * first_level_end, CvSize first_level_size )
{
    const double eps = 1.;
    CvSeqWriter writer;
    CvSeqReader reader;
    _CvPyramidC3 temp_cmp;
    _CvPyramidBaseC3 *first_level_start = (_CvPyramidBaseC3 *) first_level_end -
        first_level_size.width * first_level_size.height;
    int i, count = cmp_seq->total;
    int c_blue, c_green, c_red;

    cvStartReadSeq( cmp_seq, &reader, 0 );
    cvStartAppendToSeq( res_seq, &writer );

    if( threshold < eps )
    {
        /* if threshold is too small then simply copy all
           the components to the output sequence */
        for( i = 0; i < count; i++ )
        {
            CvConnectedComp comp;
            _CvPyramidC3 *cmp = (_CvPyramidC3 *) (((_CvListNode *) reader.ptr)->data);
            Cv32suf _c;

            if( cmp < first_level_end )
            {
                icvExpandBaseLevelC3( cmp, &temp_cmp, first_level_start,
                                      first_level_size.width );
                cmp = &temp_cmp;
            }

            c_blue = cvRound( cmp->c.blue );
            c_green = cvRound( cmp->c.green );
            c_red = cvRound( cmp->c.red );
            _c.i = c_blue; cmp->c.blue = _c.f;
            _c.i = c_green; cmp->c.green = _c.f;
            _c.i = c_red; cmp->c.red = _c.f;
            comp.value = cvScalar( c_blue, c_green, c_red );
            comp.area = cmp->a;
            comp.rect.x = cmp->rect.x1;
            comp.rect.y = cmp->rect.y1;
            comp.rect.width = cmp->rect.x2 - cmp->rect.x1;
            comp.rect.height = cmp->rect.y2 - cmp->rect.y1;
            comp.contour = 0;

            CV_WRITE_SEQ_ELEM( comp, writer );
            CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
        }
    }
    else
    {
        _CvListNode stub_node;
        _CvListNode *prev = &stub_node;

        stub_node.next = 0;

        for( i = 0; i < count; i++ )
        {
            _CvListNode *node = (_CvListNode *) reader.ptr;

            prev->next = node;
            prev = node;
            CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
        }
        prev->next = 0;
        prev = stub_node.next;

        while( prev )
        {
            _CvListNode *node = prev->next;
            _CvListNode *acc = prev;
            _CvPyramidC3 *cmp = (_CvPyramidC3 *) (acc->data);
            CvConnectedComp comp;
            _CvRGBf c0 = cmp->c;

            if( cmp < first_level_end )
            {
                icvExpandBaseLevelC3( cmp, &temp_cmp, first_level_start,
                                      first_level_size.width );
            }
            else
            {
                temp_cmp = *cmp;
                temp_cmp.c.blue *= temp_cmp.a;
                temp_cmp.c.green *= temp_cmp.a;
                temp_cmp.c.red *= temp_cmp.a;
            }

            acc->next = 0;
            stub_node.next = 0;
            prev = &stub_node;

            while( node )
            {
                cmp = (_CvPyramidC3 *) (node->data);
                if( _CV_RGB_DIST( c0, cmp->c ) < threshold )
                {
                    _CvPyramidC3 temp;

                    /* exclude from global list and add to list of joint component */
                    prev->next = node->next;
                    node->next = acc;
                    acc = node;

                    if( cmp < first_level_end )
                    {
                        icvExpandBaseLevelC3( cmp, &temp, first_level_start,
                                              first_level_size.width );
                        cmp = &temp;
                    }

                    temp_cmp.a += cmp->a;
                    temp_cmp.c.blue += cmp->c.blue * cmp->a;
                    temp_cmp.c.green += cmp->c.green * cmp->a;
                    temp_cmp.c.red += cmp->c.red * cmp->a;
                    icvMaxRoi( &(temp_cmp.rect), &(cmp->rect) );
                }
                else
                {
                    if( prev == &stub_node )
                    {
                        stub_node.next = node;
                    }
                    prev = node;
                }
                node = prev->next;
            }

            if( temp_cmp.a != 0 )
            {
                c_blue = cvRound( temp_cmp.c.blue / temp_cmp.a );
                c_green = cvRound( temp_cmp.c.green / temp_cmp.a );
                c_red = cvRound( temp_cmp.c.red / temp_cmp.a );
            }
            else
            {
                c_blue = cvRound( c0.blue );
                c_green = cvRound( c0.green );
                c_red = cvRound( c0.red );
            }
            node = acc;

            while( node )
            {
                Cv32suf _c;
                cmp = (_CvPyramidC3 *) (node->data);
                _c.i = c_blue; cmp->c.blue = _c.f;
                _c.i = c_green; cmp->c.green = _c.f;
                _c.i = c_red; cmp->c.red = _c.f;
                node = node->next;
            }

            comp.value = cvScalar( c_blue, c_green, c_red );
            comp.area = temp_cmp.a;
            comp.rect.x = temp_cmp.rect.x1;
            comp.rect.y = temp_cmp.rect.y1;
            comp.rect.width = temp_cmp.rect.x2 - temp_cmp.rect.x1;
            comp.rect.height = temp_cmp.rect.y2 - temp_cmp.rect.y1;
            comp.contour = 0;

            CV_WRITE_SEQ_ELEM( comp, writer );
            prev = stub_node.next;
        }
    }

    cvEndWriteSeq( &writer );
    return CV_OK;
}

/****************************************************************************************\

                 definition of the maximum roi size 

\****************************************************************************************/
void
icvMaxRoi( _CvRect16u * max_rect, _CvRect16u * cur_rect )
{
    if( max_rect->x2 == 0 )
        *max_rect = *cur_rect;
    else
    {
        if( max_rect->x1 > cur_rect->x1 )
            max_rect->x1 = cur_rect->x1;
        if( max_rect->y1 > cur_rect->y1 )
            max_rect->y1 = cur_rect->y1;

        if( max_rect->x2 < cur_rect->x2 )
            max_rect->x2 = cur_rect->x2;
        if( max_rect->y2 < cur_rect->y2 )
            max_rect->y2 = cur_rect->y2;
    }
}

void
icvMaxRoi1( _CvRect16u * max_rect, int x, int y )
{
    if( max_rect->x2 == 0 )
    {
        max_rect->x1 = (ushort) x;
        max_rect->y1 = (ushort) y;

        ++x;
        ++y;

        max_rect->x2 = (ushort) x;
        max_rect->y2 = (ushort) y;
    }
    else
    {
        if( max_rect->x1 > x )
            max_rect->x1 = (ushort) x;
        if( max_rect->y1 > y )
            max_rect->y1 = (ushort) y;

        ++x;
        ++y;

        if( max_rect->x2 < x )
            max_rect->x2 = (ushort) x;
        if( max_rect->y2 < y )
            max_rect->y2 = (ushort) y;
    }
}


/*F///////////////////////////////////////////////////////////////////////////////////////
//    Name:    cvPyrSegmentation
//    Purpose:
//      segments an image using pyramid-linking technique
//    Context: 
//    Parameters:
//      src - source image
//      dst - destination image
//      comp - pointer to returned connected component sequence
//      storage - where the sequence is stored
//      level - maximal pyramid level
//      threshold1 - first threshold, affecting on detalization level when pyramid
//                   is built.
//      threshold2 - second threshold - affects on final components merging.
//    Returns:
//    Notes:
//      Source and destination image must be equal types and channels
//F*/
CV_IMPL void
cvPyrSegmentation( IplImage * src,
                   IplImage * dst,
                   CvMemStorage * storage,
                   CvSeq ** comp, int level, double threshold1, double threshold2 )
{
    CvSize src_size, dst_size;
    uchar *src_data = 0;
    uchar *dst_data = 0;
    int src_step = 0, dst_step = 0;
    int thresh1 = cvRound( threshold1 );
    int thresh2 = cvRound( threshold2 );

    CV_FUNCNAME( "cvPyrSegmentation" );

    __BEGIN__;

    if( src->depth != IPL_DEPTH_8U )
        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );

    if( src->depth != dst->depth || src->nChannels != dst->nChannels )
        CV_ERROR( CV_StsBadArg, "src and dst have different formats" );

    cvGetRawData( src, &src_data, &src_step, &src_size );
    cvGetRawData( dst, &dst_data, &dst_step, &dst_size );

    if( src_size.width != dst_size.width ||
        src_size.height != dst_size.height )
        CV_ERROR( CV_StsBadArg, "src and dst have different ROIs" );

    switch (src->nChannels)
    {
    case 1:
        IPPI_CALL( icvPyrSegmentation8uC1R( src_data, src_step,
                                            dst_data, dst_step,
                                            src_size,
                                            CV_GAUSSIAN_5x5,
                                            comp, storage, level, thresh1, thresh2 ));
        break;
    case 3:
        IPPI_CALL( icvPyrSegmentation8uC3R( src_data, src_step,
                                            dst_data, dst_step,
                                            src_size,
                                            CV_GAUSSIAN_5x5,
                                            comp, storage, level, thresh1, thresh2 ));
        break;
    default:
        CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
    }
    __END__;
}


/* End of file. */

⌨️ 快捷键说明

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