10---OpenCV:图像进阶操作之连通区域分析

这篇具有很好参考价值的文章主要介绍了10---OpenCV:图像进阶操作之连通区域分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、图像连通区域

图像的连通域是指图像中具有相同像素值并且位置相邻的像素组成的区域,连通域分析是指在图像中寻找出彼此互相独立的连通域并将其标记出来。提取图像中不同的连通域是图像处理中较为常用的方法,例如在车牌识别、文字识别、目标检测等领域对感兴趣区域分割与识别。一般情况下,一个连通域内只包含一个像素值,因此为了防止像素值波动对提取不同连通域的影响,连通域分析常处理的是二值化后的图像

二、邻域

邻域即相邻得区域,opencv中有以下两种形式得领域

  • 4-邻域:必须在水平和垂直方向上相邻,相邻的两个像素坐标必须只有一位不同而且只能相差1个像素

  • 8-邻域: 九宫格形式,相邻的两个像素坐标必须只有一位不同而且只能相差1个像素

图示如下:

opencv 连通域分析,OpenCV,计算机视觉,opencv,图像处理

三、图像邻域分析法

两遍扫描法

两遍扫描法会遍历两次图像,第一次遍历图像时会给每一个非0像素赋予一个数字标签,当某个像素的上方和左侧邻域内的像素已经有数字标签时,取两者中的最小值作为当前像素的标签,否则赋予当前像素一个新的数字标签。第一次遍历图像的时候同一个连通域可能会被赋予一个或者多个不同的标签

opencv 连通域分析,OpenCV,计算机视觉,opencv,图像处理

种子填充法

首先将所有非0像素放到一个集合中,之后在集合中随机选出一个像素作为种子像素,根据邻域关系不断扩充种子像素所在的连通域,并在集合中删除掉扩充出的像素,直到种子像素所在的连通域无法扩充,之后再从集合中随机选取一个像素作为新的种子像素,重复上述过程直到集合中没有像素(类似DFS)

opencv 连通域分析,OpenCV,计算机视觉,opencv,图像处理

四、连通区域操作

不带统计信息的API

此处的OutputArray labels是不能直接imshow的,需要进行相应的转换,才能正常显示

int connectedComponents(InputArray image, OutputArray labels,int connectivity = 8, int ltype = CV_32S);
/*******************************************************************
*           image:                  输入二值图像
*           labels:                 输出图像
*           connectivity:            邻域
*           ltype:                   输出图深度
*********************************************************************/

带有统计信息的API

int connectedComponentsWithStats(InputArray image, OutputArray labels, OutputArray stats, OutputArray centroids,int connectivity, int ltype, int ccltype);
/*******************************************************************
*           image:                  输入二值图像
*           labels:                 输出图像
*           stats:                   统计信息,包括每个组件的位置、宽、高与面积
*           centroids:               每个组件的中心位置坐标cx, cy
*           connectivity:            邻域
*           ltype:                   输出图深度
*           ccltype:                 连通组件算法
*********************************************************************/
//ccltype取值
enum ConnectedComponentsTypes {
    CC_STAT_LEFT   = 0, //        组件的左上角点像素点坐标的X位置             
    CC_STAT_TOP    = 1, //        组件的左上角点像素点坐标的Y位置
    CC_STAT_WIDTH  = 2, //        组件外接矩形的宽度
    CC_STAT_HEIGHT = 3, //        组件外接矩形的高度
    CC_STAT_AREA   = 4, //        当前连通组件的面积(像素单位)
    CC_STAT_MAX    = 5  //        最大枚举值,仅在内部用于内存分配(可忽略)
};

五、综合代码

注意at函数通过宏的设置获取Mat的一系列的属性(x,y,width,height)

#include <iostream>
#include <string>
#include <time.h>
#include <map>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class Connection
{
public:
    Connection() :img(imread("text.jpg",IMREAD_GRAYSCALE))
    {//在构造函数中进行二值化处理.
        result["原图"] = img;
        threshold(img, result["阈值化"], 200, 255, THRESH_BINARY_INV);
    }
    //着色
    void DrawColor(Mat& src, Mat& result, int nCount)
    {
        vector<Vec3b> colors(nCount);
        for (int i = 1; i < nCount; i++)
        {
            colors[i] = Vec3b(rand() % 256, rand() % 256, rand() % 256);
        }
        //连通区域着色
        result = Mat::zeros(img.size(), CV_8UC3);
        //这里的CV_8UC3实际上就是完成了输出图片格式的转换。
        for (int y = 0; y < img.rows; y++)
        {
            for (int x = 0; x < img.cols; x++)
            {
                int label = src.at<int>(y, x);
                if (label > 0 && label <= nCount)
                {//着色
                    result.at<Vec3b>(y, x) = colors[label];
                }
                if (label == 0)
                {//黑色部分直接用白色来填充(一开始用的反二值化--->见下面的原理图)
                    result.at<Vec3b>(y, x) = Vec3b(255, 255, 255);
                }
            }
        }
​
    }
    void NoCount()
    {
        Mat temp;
        int nCount = connectedComponents(result["阈值化"], temp);
        //temp不能直接显示,需要转换后才能显示(在DrawColor里面res的CV_8UC3完成转换) 
        DrawColor(temp, result["不统计"], nCount);
    }
    void Count() 
    {
        Mat stats, center, temp;
        int nCount = connectedComponentsWithStats(result["阈值化"], temp, stats, center, 8, CC_STAT_AREA);
        DrawColor(temp, result["统计"], nCount);
        //利用统计信息标记连通域
        for (int i = 1; i < nCount; i++) 
        {
            int x = stats.at<int>(i, CC_STAT_LEFT);
            int y = stats.at<int>(i, CC_STAT_TOP);
            int w = stats.at<int>(i, CC_STAT_WIDTH);
            int h = stats.at<int>(i, CC_STAT_HEIGHT);
            rectangle(result["统计"], Rect(x, y, w, h), Scalar(0, 0, 0), 2);
        }
    }
    void Show() 
    {
        for (auto& v : result) 
        {
            imshow(v.first, v.second);
        }
        waitKey(0);
    }
protected:
    Mat img;
    map<string, Mat> result;
};
​
int main() 
{
    srand((unsigned int)time(nullptr));
    Connection* p = new Connection;
    p->NoCount();
    p->Count();
    p->Show();
    return 0;
}

opencv 连通域分析,OpenCV,计算机视觉,opencv,图像处理文章来源地址https://www.toymoban.com/news/detail-560133.html

到了这里,关于10---OpenCV:图像进阶操作之连通区域分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenCV学习(五)——图像基本操作(访问图像像素值、图像属性、感兴趣区域ROI和图像边框)

    访问像素值并修改 访问图像属性 设置感兴趣区域(ROI) 分割和合并图像 5.1 访问像素值并修改 访问像素值 修改像素值 简单访问每个像素值并修改比较缓慢,一般不使用。 Numpy数组方法 array.item() 和 array.itemset() 被认为更好,但是它们始终返回标量。 更好的像素访问和编辑方

    2024年02月06日
    浏览(90)
  • OpenCV 通过计算连通域面积过滤面积小的区域–Python

    代码参考:https://blog.csdn.net/u014264373/article/details/119486850 通过卷积神经网络预测图像的分割结果时,会发现分割外部出现了小面积的连通域。 常识告诉我们,这么小的物体一定不是我们的分割目标,因此,我们通过后处理的方法把它过滤掉,可以提高分割准确度。 这种小面积

    2024年02月08日
    浏览(61)
  • 我在Vscode学OpenCV 图像处理一(阈值处理、形态学操作【连通性,腐蚀和膨胀,开闭运算,礼帽和黑帽,内核】)

    例如,设定阈值为127,然后:  将图像内所有像素值大于 127 的像素点的值设为 255。  将图像内所有像素值小于或等于 127 的像素点的值设为 0。 cv2.threshold() 和 cv2.adaptiveThreshold() 是 OpenCV 中用于实现阈值处理的两个函数,它们之间有以下区别: 1.1.1. cv2.threshold(): 这个函数

    2024年02月05日
    浏览(60)
  • 计算机视觉任务图像预处理之去除图像中的背景区域-------使用连通域分析算法(包含完整代码)

    通过连通域分析算法能够找到最大的连通域,即图片的主体部分,然后保存该连通域的最小外接矩阵,即可去除掉无关的背景区域 更多图像预处理操作工具集包含在这个github仓库中

    2024年02月06日
    浏览(56)
  • c++ opencv将彩色图像按连通域区分

    要将彩色图像按连通域区分,您可以使用 OpenCV 中的  cv::connectedComponents  函数。 下面是一个简单的示例代码,说明如何使用  cv::connectedComponents  函数来检测并标记图像中的连通域: 这段代码首先读取彩色图像,然后将其转换为灰度图像。接下来,使用  cv::threshold  函数将

    2024年02月10日
    浏览(44)
  • Opencv 基本操作五 各种连通域处理方法

    在深度学习中,尤其是语义分割模型部署的结果后处理中,离不开各类形态学处理方法,其中以连通域处理为主;同时在一些传统的图像处理算法中,也需要一些形态学、连通域处理方法。为此,整理了一些常用的连通域处理函数:查找图像中最大的连通域、删除图像中小面

    2024年02月02日
    浏览(48)
  • 【Opencv】图像分割——区域生长

    Python 3.8.8 PyCharm 2021 opencv-python   区域生长的基本思想是将具有相似性质的像素集合起来构成区域。具体先对每个需要分割的区域找一个种子像素作为生长的起点,然后将种子像素周围邻域中与种子像素具有相同或相似性质的像素(根据某种事先确定的生长或相似准则来判定

    2024年02月05日
    浏览(44)
  • OPENCV C++(四)形态学操作+连通域统计

    第一个是形状 第二个是卷积核大小 tips:这些都是针对于二值化图像操作的 单独的也有 例如腐蚀函数 这个-1 -1是默认的 不变 2是做两次腐蚀的意思 先定义返回的值 stats :记录了每个连通区域的信息,是一个5列的矩阵,每一行对应一个连通区域,分别为连通区域外接矩形的

    2024年02月14日
    浏览(56)
  • opencv 连通域操作示例代码记录connectedComponentsWithStats()函数示例

    上面这个代码是MFC程序里面的一个函数,不能够直接运行,但是如果学过MFC相信没有问题完全能够看得懂。 上例当中,count=7(也许可能是count,我写成了cout,也就不改了).说明检测到7个连通域。

    2024年02月06日
    浏览(58)
  • OpenCV实战(3)——图像感兴趣区域

    在实际应用场景下,图像处理函数有时只需要应用于图像的部分区域。 OpenCV 中使用了一种优雅而简单的机制来定义图像中的子区域并将可以将其视为常规图像进行操作。本节中,我们将学习如何定义图像内的感兴趣区域 ( region of interest , ROI )。 为了说明如何定义感兴趣区域

    2024年02月09日
    浏览(68)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包