opencv 连通性分析

本来想偷懒直接在网上找源码,找到了发现都一样,但是有bug,因此参考了https://blog.csdn.net/icvpr/article/details/10259577的介绍与代码,对错误的地方进行了修改,然后将四邻域改为八邻域

原理就不介绍了,可以直接看上面的链接,里面介绍的挺清楚地

 

上面那个链接有执行出问题的地方其实就是没有判断边界,加上去就好了(加粗标红的地方

void icvprCcaBySeedFill(const cv::Mat& _binImg, cv::Mat& _lableImg)
{
    // connected component analysis (4-component)  
    // use seed filling algorithm  
    // 1. begin with a foreground pixel and push its foreground neighbors into a stack;  
    // 2. pop the top pixel on the stack and label it with the same label until the stack is empty  
    //   
    // foreground pixel: _binImg(x,y) = 1  
    // background pixel: _binImg(x,y) = 0  

    if (_binImg.empty() ||
        _binImg.type() != CV_8UC1)
    {
        return;
    }

    _lableImg.release();
    _binImg.convertTo(_lableImg, CV_32SC1);

    int label = 1;  // start by 2  

    int rows = _binImg.rows - 1;
    int cols = _binImg.cols - 1;
    for (int i = 1; i < rows - 1; i++)
    {
        int* data = _lableImg.ptr<int>(i);
        for (int j = 1; j < cols - 1; j++)
        {
            if (data[j] == 1)
            {
                std::stack<std::pair<int, int>> neighborPixels;
                neighborPixels.push(std::pair<int, int>(i, j));     // pixel position: <i,j>  
                ++label;  // begin with a new label  
                while (!neighborPixels.empty())
                {
                    // get the top pixel on the stack and label it with the same label  
                    std::pair<int, int> curPixel = neighborPixels.top();
                    int curX = curPixel.first;
                    int curY = curPixel.second;
                    _lableImg.at<int>(curX, curY) = label;

                    // pop the top pixel  
                    neighborPixels.pop();

                    if (curX >= 1 && curX <= rows - 1 && curY >= 1 && curY <= cols - 1)
                    {

                        // push the 8-neighbors (foreground pixels)  
                        if (_lableImg.at<int>(curX, curY - 1) == 1)
                        {// left pixel  
                            neighborPixels.push(std::pair<int, int>(curX, curY - 1));
                        }
                        if (_lableImg.at<int>(curX, curY + 1) == 1)
                        {// right pixel  
                            neighborPixels.push(std::pair<int, int>(curX, curY + 1));
                        }
                        if (_lableImg.at<int>(curX - 1, curY) == 1)
                        {// up pixel  
                            neighborPixels.push(std::pair<int, int>(curX - 1, curY));
                        }
                        if (_lableImg.at<int>(curX + 1, curY) == 1)
                        {// down pixel  
                            neighborPixels.push(std::pair<int, int>(curX + 1, curY));
                        }

//四邻域分析的话就不需要下面绿色的部分了
                        if (_lableImg.at<int>(curX - 1, curY - 1) == 1)
                        {// left up pixel  
                            neighborPixels.push(std::pair<int, int>(curX - 1, curY - 1));
                        }
                        if (_lableImg.at<int>(curX - 1, curY + 1) == 1)
                        {// left down pixel  
                            neighborPixels.push(std::pair<int, int>(curX - 1, curY + 1));
                        }
                        if (_lableImg.at<int>(curX + 1, curY - 1) == 1)
                        {// right up pixel  
                            neighborPixels.push(std::pair<int, int>(curX + 1, curY - 1));
                        }
                        if (_lableImg.at<int>(curX + 1, curY + 1) == 1)
                        {// roght down pixel  
                            neighborPixels.push(std::pair<int, int>(curX + 1, curY + 1));

                        }
                    }
                }
            }
        }
    }
}

然后需要注意的是, 输入的背景需要是白色的,目标是黑色的, 颜色标记的代码直接参照上面链接的就行。

PS:后期实验发现,建议图像什么的都转为png格式

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值