OpenCV ----像素距离与连通域

OpenCV16-图像连通域分析 函数可以实现图像中多个连通域的统计,但是只能通过标签将图像中的不同连通域分开,无法得到更多的统计信息。有时,我们希望得到每个连通域中心位置或者在图像中标记出连通域所在的矩形区域,该函数用于计算二值图像中连通域的个数,并在图像中不同的连通域用不同的数字标签标记,其中标签0表示图像中的背景色。函数返回图像中连通域的数目。根据两个像素相邻定义方式不同,得到的连通区域也不相同,因此,在分析连通域的同时,一定要声明是在哪种邻域条件下分析得到的结果。连通域是指图像中具有相同像素值并且位置相邻的像素组成的区域。 阅读详情

一. 图像像素距离变换

1.常用距离的三种定义:

​

(1)欧式距离-----DIST_L2

​ 两像素点的直线距离,利用勾股定理可计算出两点的欧式距离
d = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 2 d = \sqrt[2]{(x_1-x_2)^2 +(y_1-y_2)^2 } d=2(x1​−x2​)2+(y1​−y2​)2 ​

(2)街区距离-----DIST_L1

​ 两像素点X和Y方向距离之和,计算公式为
d = ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ d = |x_1-x_2| +|y_1-y_2| d=∣x1​−x2​∣+∣y1​−y2​∣

(3)棋盘距离------DIST_C

​ 棋盘距离为两像素点移动到同一行或同一列的最大距离,即两点X方向和Y方向上的最大距离

2. distanceTransform() ------ 距离转换函数
(1) 函数原型
void distanceTransform(InputArray src, 
                            OutputArray dst, 
                            int distanceType, 
                            int maskSize, 
                            int dstType=CV_32F )
     
 //distanceTransform()函数有两个原型,此处为较常用的

src:准备作距离变换的原图像。

dst:经过距离变换后的输出图像。

distanceType:距离类型,标志见上

maskSize :计算距离时使用的mask矩阵大小,参数可以为3或5。

dstType: 输出图像(矩阵)的数据类型,可以是CV_8U 或 CV_32F。当选择CV_8U时,distanceType的类型只能为DIST_L1。

distanceTransform()函数计算的是非零像素点到0像素点的距离

(2)运用演示
//计算简易5*5矩阵  1,1,1,1,1
//               1,1,1,1,1
//               1,1,0,1,1
//               1,1,1,1,1
//               1,1,1,1,1  的三种距离


void QuickDemo::distance_demo(Mat& img)
{
	Mat a = (Mat_<uchar>(5, 5) 
		<< 1, 1, 1, 1, 1 ,
		 1, 1, 1, 1, 1,
		 1, 1, 0, 1, 1 ,
		 1, 1, 1, 1, 1 ,
		 1, 1, 1, 1, 1);

	Mat dis_L1, dis_L2, dis_C;


	distanceTransform(a, dis_L1, DIST_L1, 3, CV_8U);
	cout << "街区距离" << endl << dis_L1 << endl;


	distanceTransform(a, dis_L2, DIST_L2, 3, CV_8U);
	cout << "欧式距离" << endl << dis_L2 << endl;


	distanceTransform(a, dis_C, DIST_C, 3, CV_8U);
	cout << "棋盘距离" << endl << dis_L1 << endl;
}

由于distanceTransform()函数计算的是非零像素点到0像素点的距离,得到下列输出

在这里插入图片描述

二. 图像连通域

(1)定义

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

(2)邻域

​ opencv中有以下两种形式领域:

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

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

在这里插入图片描述

(3)标记连通域函数-----connectedComponents()
int connectedComponents(InputArray image, OutputArray labels,
                          int connectivity, int ltype, int ccltype);

image: 输入二值图像

labels: 输出图像

connectivity: 邻域种类,4或8

ltype: 输出图深度,支持CV_32S 和CV_16S

代码演示:


int main()
{
     Mat img,M,dst;
     img = imread("D:/OpenCV/photo/R.png",1);
	 //对图像进行距离变换
	 if (img.empty())
	 {
		 cout << "请确认图像文件名称是否正确" << endl;
		 return -1;
	 }
	 cv::Mat rice, riceBW;

	 //将图像转成二值图像,用于统计连通域
	 cv::cvtColor(img, rice, cv::COLOR_BGR2GRAY);
	 cv::threshold(rice, riceBW, 50, 255, cv::THRESH_BINARY);

	 //生成随机颜色,用于区分不同连通域
	 cv::RNG rng(10086);
	 cv::Mat out;
	 int number = connectedComponents(riceBW, out, 8, CV_16U);  //统计图像中连通域的个数
	 vector<cv::Vec3b> colors;
	 for (int i = 0; i < number; i++)
	 {
		 //使用均匀分布的随机数确定颜色
		 cv::Vec3b vec3 = cv::Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
		 colors.push_back(vec3);
	 }

	 //以不同颜色标记出不同的连通域
	 cv::Mat result = cv::Mat::zeros(rice.size(), img.type());
	 int w = result.cols;
	 int h = result.rows;
	 for (int row = 0; row < h; row++)
	 {
		 for (int col = 0; col < w; col++)
		 {
			 int label = out.at<uint16_t>(row, col);
			 if (label == 0)  //背景的黑色不改变
			 {
				 continue;
			 }
			 result.at<cv::Vec3b>(row, col) = colors[label];
		 }
	 }

	 //显示结果
	 cv::imshow("原图", img);
	 cv::imshow("标记后的图像", result);

	 cv::waitKey(0);
	 return 0;
}

在这里插入图片描述

(3)connectedComponents()函数

connectedComponents()函数除了输出连通区域标签图像外,还会输出每个连通区域的一些统计信息,如像素数目、外接矩形等。该函数的原型如下:

int connectedComponentsWithStats(InputArray image,
                                 OutputArray labels,
                                 OutputArray stats,
                                 OutputArray centroids,
                                 int connectivity = 8,
                                 int ltype = CV_32S);

参数 stats 为输出的统计信息,参数 centroids 为输出的连通区域质心。

代码演示:

void QuickDemo::connectedComponentsWithstats_demo(Mat& img)
{
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return;
	}

	GaussianBlur(img, img, Size(7, 7),3);
	Mat rice, riceBW;
	cout << img.type() << endl;
	cvtColor(img, rice, COLOR_BGR2GRAY);
	threshold(rice, riceBW, 50, 255, THRESH_BINARY);

	RNG rng(10086);
	Mat out;
	Mat satas, cen;
	int number = connectedComponentsWithStats(riceBW, out, satas, cen, 8, CV_16U);
	vector<Vec3b> colors;
	for (int i = 0; i < number; i++)
	{

		cv::Vec3b vec3 = cv::Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
		colors.push_back(vec3);
	}


	cv::Mat result = cv::Mat::zeros(rice.size(), img.type());
	//int w = result.cols;
	//int h = result.rows;

	for (int i = 1; i < number; ++i)
	{
		int center_x = cen.at<double>(i, 0);
		int center_y = cen.at<double>(i, 1);
		int x = satas.at<int>(i, CC_STAT_LEFT);
		int w = satas.at<int>(i, CC_STAT_WIDTH);
		int y = satas.at<int>(i, CC_STAT_TOP);
		int h = satas.at<int>(i, CC_STAT_HEIGHT);
		Rect rect(x, y, w, h);
		rectangle(img, rect, Scalar(255, 255, 255), 1, 8);
	}


	//cv::imshow("原图", img);
	cv::imshow("标记后的图像", img);

}

在这里插入图片描述

OpenCV(二十八):连通域分割 连通域分割是一种图像处理技术,用于将图像中的相邻像素组成的区域划分为不同的连通域。这些像素具有相似的特性,如相近的灰度值或颜色。连通域分割可以用于物体检测、图像分割、目标跟踪等应用。在连通域分割中,常用的领域关系有四领域和八领域。四领域表示一个像素与其上下左右四个相邻像素连接。八领域表示一个像素与其上、下、左、右、左上、右上、左下、右下八个相邻像素连接。 阅读详情

相关推荐

OpenCV Distance Transform (距离变换)

OpenCV 距离变换C++例子

weixin_46206829的博客 612

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

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

zjjaibc的博客 9902

day18:像素距离与连通域

在图像形态学运算中,常将不与其他区域连接的独立区域称为集合或者连通域,这个集合中的元素就是包含在连通域内的每一个像素,可以用该像素在图像中的坐标来描述,像素之间的距离可以用来表示两个连通域之间的关系.在了解图像形态学运算之前,首先需要了解图像中两个像素之间的距离描述方式,以及如何从图像中分离出不同的连通域。 欧式距离: 街道距离:d=|x1-x2|+|y1-y2| 棋盘距离: d=max(|x1-x2|,|y1-y2|),两个像素点X方向,y方向距离的最大值 ...

m0_57747965的博客 850

OpenCV——图像连通域分析

Opencv图像连通性分析的C++和python代码实现。

点云侠的博客 5059

告别魔改参数!深入理解OpenCV分水岭算法中的‘距离变换’与‘标记’,让你的图像分割更稳定

本文深入解析OpenCV分水岭算法中的距离变换与标记生成原理,帮助开发者实现更稳定的图像分割。通过地形学隐喻和实战代码示例,详细讲解距离变换的类型选择、标记生成的优化策略,以及预处理和后处理的技巧,适用于硬币检测、工业零件分割等多种场景。

weixin_30443075的博客 218

opencv (三十五)连通域分析

小白学视觉,笔记,扩展

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 2252

OpenCV---007(图像形态学基础操作)

图像形态学操作 一些情况下 相比于物体的纹理信息 物体的形状和位置信息对我们更加重要 因此可以忽略物体内部的信息 而是以形态为基础对物体进行分析 所以对于图像形态学我们使用一定的形态的结构元素 来去度量和提取图像中的相应形状 以达到对图像进行分析和识别的目的 图像形态学操作主要包括图像的腐蚀 膨胀 开运算 闭运算 像素距离和连通域 图像形态学主要应用于从图像中提取对于表达和描述区域有意义的...

CYK的博客 141

从零构建:ESP32S3无线DAP-Link调试器的硬件与软件协同设计

本文详细介绍了基于ESP32S3的无线DAP-Link调试器的硬件与软件协同设计,涵盖关键元器件选型、无线通信协议优化、双核任务处理及低功耗调试方案。通过ESP-NOW协议实现低延迟无线调试,结合USB协议栈与双核协同,为嵌入式开发提供高效灵活的调试解决方案。

gitlab7runner的博客 860

Opencv4 c++ 自用笔记 05 形态学操作

图像形态学主要获取物体的形状与位置信息。利用具有一定形态的结构元素度量和提取图像中的对应形状,达到对图像分析和识别的目的。操作主要包括腐蚀、膨胀、开运算和闭运算。

qq_37231166的博客 1050

RocketMQ5.3.0-control-多 Master 多 Salve-异步复制-集群搭建

RocketMQ5.3.0-control-多 Master 多 Salve-异步复制-集群搭建(详细文档)

m0_52369979的博客 732

【5G全网建设】Option3X和Option2模式建安市、兴城市和四水市核心网、承载网网络设计与部署

拓扑规划: Option 3X网络拓扑图规划 Option 2网络拓扑图规划 设备部署: 建安市核心网 建安市承载中心机房 建安市骨干汇聚机房 建安市3区汇聚机房 建安市C站点无线机房 兴城市核心网 兴城市承载中心机房 兴城市骨干汇聚机房 兴城市2区汇聚机房 兴城市B站点无线机房 数据配置: 建安市核心网 建安市承载中心机房 建安市骨干汇聚机房 建安市3区汇聚机房 建安市C站点无线机房 兴城市核心网 兴城市承载中心机房 兴城市骨干汇聚机房 兴城市2区汇聚机房 兴城市B站点无线机房 业务调试

weixin_67183034的博客 8869

连通域与相距变换

【代码】连通域与相距变换。

qq_57594025的博客 297

用Python玩转Carla-Apollo联合仿真:手把手教你实现自动驾驶测试

本文详细介绍了如何使用Python实现Carla-Apollo联合仿真,从环境搭建到自动驾驶算法测试的全流程。通过Carla提供的高逼真仿真环境和Apollo的自动驾驶算法栈,开发者可以高效验证感知、规划和控制模块。文章包含环境配置、Python API操作、桥接实现及实战测试,为自动驾驶开发提供完整解决方案。

wasm7browser的博客 269

Python图片换底色实战:从颜色距离到洪水填充的完整方案

图像处理是Python工程实践中最常见的需求之一,而底色替换则是其中的典型任务。无论是证件照背景调整、电商产品图规范化,还是PPT配图统一风格,都离不开对像素颜色和区域连通性的精准控制。本文从最基础的RGB通道与颜色距离概念入手,讲解如何用Python与OpenCV识别背景像素,并逐步深入到洪水填充算法、轮廓检测与形态学优化等进阶技术。通过对比不同方案的适用场景,帮助读者理解掩膜生成这一核心本质,并掌握批量处理与防呆设计的工程技巧。无论你是初学者还是工程开发者,都能通过这个项目学会如何构建一套高效、可靠的图

weixin_34050005的博客 393

深入剖析RDMA Netlink:Linux内核中高效通信的基石

RDMA Netlink:Linux内核中高效通信控制的核心机制 RDMA技术通过绕过内核实现高速数据传输,但其管理控制仍需内核参与。drivers/infiniband/core/netlink.c文件作为RDMA子系统的心脏,构建了用户空间与内核间的高效通信桥梁。该模块采用模块化客户端架构,通过全局数组管理不同类型的RDMA功能,如设备管理、连接服务和链路层操作。从最初的全局锁到细粒度读写锁的演进,展现了Linux内核追求高性能的持续优化。同时,通过条件编译支持新旧内核版本和网络命名空间,体现了稳定性与

数字人生 239

4.Simulink基础建模操作——加减乘除运算

加减乘除运算

FPGA/MATLAB学习教程/源码/项目合作开发 9553

用Python+OpenCV搞定数学建模E题:手把手教你从视频里提取车流量数据(附完整代码)

本文详细介绍了如何使用Python和OpenCV从交通视频中提取车流量数据,包括车辆检测、计数和轨迹追踪的全流程实现。通过背景减除、连通域分析等技术,结合完整代码示例,帮助读者快速掌握数学建模E题的解决方案,特别适合参加华为杯中国研究生数学建模竞赛的选手参考。

weixin_30642561的博客 520

Python 爬虫实战:付费 IP 代理使用技巧与爬虫稳定性优化

付费IP代理实战指南:突破反爬与优化稳定性 本文系统讲解付费IP代理在爬虫项目中的高效应用方法。首先对比分析静态代理、动态代理和隧道代理的优缺点及适用场景,推荐高并发项目优先选择隧道代理。然后详细演示了主流代理服务商的集成方法,包括代理池的自动更新和健康检测机制。核心部分重点介绍了爬虫稳定性优化策略,如智能重试、频率控制和请求间隔优化等关键技术。最后通过压力测试验证优化效果,并提供成本控制方案,包括代理复用、错峰爬取等实用技巧。通过本教程,开发者可有效解决高并发爬虫中的IP封禁问题,显著提升系统稳定性和抗风

2503_91057718的博客 2451

OpenCV4 快速入门 学习笔记分享【第六章】

至此,第六章就结束了,望各位读者“一键三连”有任何问题欢迎评论区留言或者私信。

2201_75933254的博客 931

手把手教你学SOME/IP「1.0•概述」

本文介绍了SOME/IP协议的基本概念和主要特点。SOME/IP全称为"Scalable service-Oriented MiddlewarE over IP",是一种面向服务的车载嵌入式通信协议,支持远程过程调用、事件通知等功能。文章指出SOME/IP是AUTOSAR标准的一部分,在车载以太网架构中处于应用层位置,负责服务调度和通信封装。协议具有可扩展性强、资源消耗低、兼容性好等优势,能满足汽车电子领域对实时性、可靠性的严格要求。同时,文章也说明了SOME/IP的正确书写规范,并解释

nihaoljq2010的博客 679

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Opencv4图像分割和识别第七课(实战6)如何计算两条直线间的距离

前言 Opencv4图像分割和识别实战6的视频课程(https://edu.youkuaiyun.com/course/detail/24864)主要是讲解如何求两条曲线之间的距离。对应的,本课作业来求下面图所示的两条直线间距离以巩固课堂上所学的知识。 解决方法一 1)通过前面所学的投影分割法来分别获得这2条直线上的离散采样点,然后将它们通过直线拟合求得各自的直线方程,如k1x+b和k2x+b2。...

ltshan139的专栏 4989

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

opencv 图像连通域分析

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

weixin_39354845的博客 7645

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

opencv#35 连通域分析

像素领域介绍:4邻域是指中心的像素与它邻近的上下左右一共有4个像素,那么称这4个像素为中心像素的4邻域。8邻域是以中心像素周围的8个像素分别是上下左右和对角线上的4个像素。连通域的定义(分割)分为两种:以4邻域为相邻判定条件的连通域分割和8邻域为判定条件的连通域分割。连通域指某个区域内所有像素是相邻的,如果一个像素不能够通过这个区域中的像素到达另一个像素,那么这两个像素就不再同一连通域内。连通域的划分通常采用。

2303_77166351的博客 2681

EX5连通域与距离场

实验E5:图像结构1 实验5.1 连通域 并查集基本算法find,unite //并查集找到祖先和合并 int find(int x) { int root = par[x]; while (root!=par[root]) { root = par[root]; } while (x!=root) { int tt = par[x]; par[x] = root; x = tt; } return root; } int unite(int x, int y) { i

qq_48034566的博客 2311

连通域分析之两遍扫描法(Two-Pass)

连通域分析之两遍扫描法(Two-Pass)

qq_41588862的博客 5822

OpenCV3学习(7.2)——图像分割之二(分水岭算法watershed)

分水岭算法原理 分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特征。其他图像分割方法,如阈值,边缘检测等都不会考虑像素在空间关系上的相似性和封闭性这一概念,彼此像素间互相独立,没有统一性。分水岭算法较其他分割方法更具有思想性,更符合人眼...

知识搬运工的博客 8740
上一篇: LC-3 汇编语言实现简易四子棋
下一篇: 角点检测与特征点匹配
sunny_code_
博客等级 码龄3年 174粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值