标记连通四邻域的

  1. 速度比老版Two_Pass快很多,后续看明白怎么改8邻域的再改,改完再看性能吧

  2. void Two_PassNew( const Mat &bwImg, Mat &labImg )
    
    {
    
    assert( bwImg.type()==CV_8UC1 );
    
    labImg.create( bwImg.size(), CV_32SC1 ); //bwImg.convertTo( labImg, CV_32SC1 );
    
    labImg = Scalar(0);
    
    labImg.setTo( Scalar(1), bwImg );
    
    assert( labImg.isContinuous() );
    
    const int Rows = bwImg.rows - 1, Cols = bwImg.cols - 1;
    
    int label = 1;
    
    vector<int> labelSet;
    
    labelSet.push_back(0);
    
    labelSet.push_back(1);
    
    //the first pass
    
    int *data_prev = (int*)labImg.data; //0-th row : int* data_prev = labImg.ptr<int>(i-1);
    
    int *data_cur = (int*)( labImg.data + labImg.step ); //1-st row : int* data_cur = labImg.ptr<int>(i);
    
    for( int i = 1; i < Rows; i++ )
    
    {
    
    data_cur++;
    
    data_prev++;
    
    for( int j=1; j<Cols; j++, data_cur++, data_prev++ )
    
    {
    
    if( *data_cur!=1 )
    
    continue;
    
    int left = *(data_cur-1);
    
    int up = *data_prev;
    
    int neighborLabels[2];
    
    int cnt = 0;
    
    if( left>1 )
    
    neighborLabels[cnt++] = left;
    
    if( up > 1)
    
    neighborLabels[cnt++] = up;
    
    if( !cnt )
    
    {
    
    labelSet.push_back( ++label );
    
    labelSet[label] = label;
    
    *data_cur = label;
    
    continue;
    
    }
    
    int smallestLabel = neighborLabels[0];
    
    if( cnt==2 && neighborLabels[1]<smallestLabel )
    
    smallestLabel = neighborLabels[1];
    
    *data_cur = smallestLabel;
    
    // 保存最小等价表
    
    for( int k=0; k<cnt; k++ )
    
    {
    
    int tempLabel = neighborLabels[k];
    
    int& oldSmallestLabel = labelSet[tempLabel]; //这里的&不是取地址符号,而是引用符号
    
    if( oldSmallestLabel > smallestLabel )
    
    {
    
    labelSet[oldSmallestLabel] = smallestLabel;
    
    oldSmallestLabel = smallestLabel;
    
    }
    
    else if( oldSmallestLabel<smallestLabel )
    
    labelSet[smallestLabel] = oldSmallestLabel;
    
    }
    
    }
    
    data_cur++;
    
    data_prev++;
    
    }
    
    //更新等价队列表,将最小标号给重复区域
    
    for( size_t i = 2; i < labelSet.size(); i++ )
    
    {
    
    int curLabel = labelSet[i];
    
    int prelabel = labelSet[curLabel];
    
    while( prelabel != curLabel )
    
    {
    
    curLabel = prelabel;
    
    prelabel = labelSet[prelabel];
    
    }
    
    labelSet[i] = curLabel;
    
    }
    
    //second pass
    
    data_cur = (int*)labImg.data;
    
    for( int i = 0; i < Rows; i++ )
    
    {
    
    for( int j = 0; j < bwImg.cols-1; j++, data_cur++)
    
    *data_cur = labelSet[ *data_cur ];
    
    data_cur++;
    
    }
    
    }
    
    
    
    八连通改完了 速度依然杠杠的 
    
    
    
    void  Two_PassNewEight( const Mat &bwImg, Mat &labImg )
    {
        assert( bwImg.type()==CV_8UC1 );
        labImg.create( bwImg.size(), CV_32SC1 );   //bwImg.convertTo( labImg, CV_32SC1 );
        labImg = Scalar(0);
        labImg.setTo( Scalar(1), bwImg );
        assert( labImg.isContinuous() );
        const int Rows = bwImg.rows - 1, Cols = bwImg.cols - 1;
        int label = 1;
        vector<int> labelSet;
        labelSet.push_back(0);
        labelSet.push_back(1);
        //the first pass
        int *data_prev = (int*)labImg.data;   //0-th row : int* data_prev = labImg.ptr<int>(i-1);
        int *data_cur = (int*)( labImg.data + labImg.step ); //1-st row : int* data_cur = labImg.ptr<int>(i);
        for( int i = 1; i < Rows; i ++ )
        {
            data_cur ++;
            data_prev ++;
            for( int j = 1; j < Cols; j ++, data_cur ++, data_prev ++ )
            {
                if( *data_cur!=1 )
                    continue;
                int left = *(data_cur-1);//左
                int up = *data_prev;//上
    
                int leftup = *(data_prev - 1);//左
                int rightup = *(data_prev + 1);//上
    
    
                int neighborLabels[4];
                int cnt = 0;
                if( left>1 )
                    neighborLabels[cnt ++] = left;
                if( up > 1)
                    neighborLabels[cnt ++] = up;
                if( leftup > 1)
                    neighborLabels[cnt ++] = leftup;
                if( rightup > 1)
                    neighborLabels[cnt ++] = rightup;
                if( !cnt )
                {
                    labelSet.push_back( ++label );
                    labelSet[label] = label;
                    *data_cur = label;
                    continue;
                }
                int smallestLabel = neighborLabels[0];
                if( cnt == 4 && neighborLabels[1]<smallestLabel )
                    smallestLabel = neighborLabels[1];
                *data_cur = smallestLabel;
                // 保存最小等价表
                for( int k=0; k< cnt; k++ )
                {
                    int tempLabel = neighborLabels[k];
                    int& oldSmallestLabel = labelSet[tempLabel];  //这里的&不是取地址符号,而是引用符号
                    if( oldSmallestLabel > smallestLabel )
                    {
                        labelSet[oldSmallestLabel] = smallestLabel;
                        oldSmallestLabel = smallestLabel;
                    }
                    else if( oldSmallestLabel<smallestLabel )
                        labelSet[smallestLabel] = oldSmallestLabel;
                }
            }
            data_cur++;
            data_prev++;
        }
        //更新等价队列表,将最小标号给重复区域
        for( size_t i = 2; i < labelSet.size(); i++ )
        {
            int curLabel = labelSet[i];
            int prelabel = labelSet[curLabel];
            while( prelabel != curLabel )
            {
                curLabel = prelabel;
                prelabel = labelSet[prelabel];
            }
            labelSet[i] = curLabel;
        }
        //second pass
        data_cur = (int*)labImg.data;
        for( int i = 0; i < Rows; i++ )
        {
            for( int j = 0; j < bwImg.cols-1; j++, data_cur++)
                *data_cur = labelSet[ *data_cur ];
            data_cur++;
        }
        for(int i = 0; i < Rows; i ++)
        {
            labImg.at<int>(i, 0) = 0;
            labImg.at<int>(i, Cols - 1) = 0;
        }
        for(int i = 0; i < Cols; i ++)
        {
            labImg.at<int>(0, i) = 0;
            labImg.at<int>(Rows - 1, i) = 0;
        }
    }
    
    
    
  3.  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值