zoukankan      html  css  js  c++  java
  • 手写01矩阵连通域分析

    连通域分析其实是一个路径搜索问题,搜索方式就看联通的规则(4联通:上下左右算是联通,8联通:上下左右还有四个对角)

    01矩阵背景是0,黑色的,有色区域是1,白色的,从图像的左上角(最外围的边要去掉)进行遍历,将找到的第一个值为1的像素点作为起点,对他进行连通域搜寻,将搜寻到的整个连通域内的像素点标为2(为了避免与本来的颜色1冲突)

    继续搜索像素值为1的点(之前联通域分析过的已经将像素值改为大于1的值,所以像素值为1的就是还没有分析过的),直到整个图像遍历完成

    遍历方法:

    找到起点后初始化一个栈,存放连通域的点坐标(pair),将起点的横纵坐标压入栈中,连通域的标记值自增(第一个连通域的标记值为2,从2开始,第二个连通域的标记值为3,以此类推)

    当栈不为空时,从栈顶取点,读出他的横纵坐标,在Label图中,根据横纵坐标对连通域进行对应标记值的赋值,然后将该点出栈,同时按照联通规则,根据坐标找到它的相邻像素点,看相邻像素点的值是否为1,如果是1,则是连通域,将这个点入栈(判断时记得要加上边界条件,防止点下标溢出,我的代码偷懒了没有加,正常要加上 0<=Row<BinaryImg.rows&&0<=Col<BinaryImg.cols)

    代码

    void SeedFilling(const Mat &BinaryImg, Mat &LabelImg)
    {
        if (BinaryImg.empty || BinaryImg.type() != CV_8UC1)
            return;
    
        BinaryImg.convertTo(LabelImg, CV_32SC1);
    
        int Label = 1;// 从2开始,防止和二值图像的像素值重合
    
        int Row = BinaryImg.rows - 1;
        int Col = BinaryImg.cols - 1;
    
        for (int i = 1; i < Row; ++i)
        {
            int* data = LabelImg.ptr<int>(i);
    
            for (int j = 1; j < Col - 1; ++j)
            {
                if (data[j] == 1)
                {
                    stack<pair<int, int>> NeighborPixel;
                    NeighborPixel.push(pair<int, int>(i, j));
    
                    ++Label;// 新标签
    
                    while (!NeighborPixel.empty)// 栈不为空
                    {
                        pair<int, int> CurPixel = NeighborPixel.top();
                        int CurRow = CurPixel.first;
                        int CurCol = CurPixel.second;
                        LabelImg.at<int>(CurRow, CurCol) = Label;
                        NeighborPixel.pop();// 出栈
    
                        if (LabelImg.at<int>(CurRow, CurCol - 1) == 1)
                            NeighborPixel.push(pair<int, int>(CurRow, CurCol - 1));
    
                        if (LabelImg.at<int>(CurRow, CurCol + 1) == 1)
                            NeighborPixel.push(pair<int, int>(CurRow, CurCol + 1));
    
                        if (LabelImg.at<int>(CurRow - 1, CurCol) == 1)
                            NeighborPixel.push(pair<int, int>(CurRow - 1, CurCol));
    
                        if (LabelImg.at<int>(CurRow + 1, CurCol) == 1)
                            NeighborPixel.push(pair<int, int>(CurRow + 1, CurCol));
                    }
                }
            }
    
            return;
        }
    }
  • 相关阅读:
    [总结] XPO (eXpress Persistent Objects) 学习总结一
    [总结]工作中常用的正则表达式,有了它事半功倍!
    用JS实现页面滚动位置保持的方法
    [总结]TLF论坛全功略,下载指南!
    Javascript里使用Dom操作Xml
    。NET构架相关资源
    [收藏]关于用Asp.Net论坛发帖软件的实现
    匹配Unicode字符的正则表达式(中文)
    [转贴]如何实现TreeView的双击事件?
    [转贴]客户端不装adobe reader,打开pdf文件的插件
  • 原文地址:https://www.cnblogs.com/wangtianning1223/p/13849516.html
Copyright © 2011-2022 走看看