• 手写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;
        }
    }
  • 相关阅读:
    Jest | expect常用匹配方法
    typescript | typeScript 笔记
    好用的思维脑图
    VSCode launch.json 配置详解
    各种语法技术栈文档汇总|api文档集合
    浏览器的运行机制
    js字符串转数字长度限制|超过长度有误差
    css对话框| 气泡框| css箭头
    nginx和php-fpm的用户权限
    mac安装redis拓展
  • 原文地址:https://www.cnblogs.com/wangtianning1223/p/13849516.html
Copyright © 2020-2023  润新知