【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法

OpenCV 例程200篇 总目录-202205更新

【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法
【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法
【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法
【youcans 的 OpenCV 例程200篇】183.基于轮廓标记的分水岭算法
【youcans 的 OpenCV 例程200篇】184.鼠标交互标记的分水岭算法


【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法


7. 图像分割之分水岭算法

分水岭算法是一种图像区域分割法,以临近像素间的相似性作为重要特征,从而将空间位置相近且灰度值相近的像素点互相连接起来,构成一个封闭的轮廓。

分水岭算法是基于形态学的图像分割方法,体现了边缘检测、阈值处理和区域提取的概念和思想,往往会产生更稳定的分割结果。算法的实现过程可以理解为洪水淹没的过程:最低点首先被淹没,然后水逐渐淹没整个山谷;水位升高到一定高度就会溢出,于是在溢出位置修建堤坝;不断提高水位,重复上述过程,直到所有的点全部被淹没;所建立的一系列堤坝就成为分隔各个盆地的分水岭。

分水岭的计算过程是一个迭代标注过程,通过寻找集水盆和分水岭对图像进行分割。经典的分水岭算法分为排序过程和淹没过程两个步骤,首先对每个像素的灰度级从低到高排序,然后在从低到高的淹没过程中,对每一个局部极小值在 h 阶高度的影响域进行判断及标注。

OpenCV 提供了函数 cv.watershed 实现基于标记的分水岭算法。

使用函数 cv.watershed 需要输入一个CV_32S 类型的标记图像,图像中每个非零像素代表一个标签。对图像中部分像素做标记,表明它的所属区域是已知的。

cv.watershed(image, markers[, ]	) → markers 

参数说明:

  • image:输入图像,8-bit/3-channel 彩色图像
  • markers:标记图像,32-bit 单通道图像,大小与 image 相同

注意事项:

  • 分水岭算法要求必须在标记图像 markers 中用索引勾勒出需要分割的区域,每个区域被赋值为 1、2、3… 等索引编号,对应于不同的目标物体。
  • 图像标记 markers 中未知区域的像素值设置为 0,通过分水岭算法确定这些像素属于背景还是前景区域。
  • 输出的图像标记 markers 中,每个像素都被赋值为 1、2、3… 等索引编号,或以 -1 表示区域之间的边界(分水岭)。

OpenCV 提供了函数 cv.distanceTransform 实现距离变换,计算图像中每个像素到最近的零像素点的距离。

函数说明:

cv.distanceTransform(src, distanceType, maskSize[, dst=None, dstType=CV_32F]) → dst
cv.distanceTransformWithLabels(src, distanceType, maskSize[, dst=None, labels=None, labelType=DIST_LABEL_CCOMP]) → dst, labels

参数说明:

  • src:输入图像,8-bit 单通道灰度图像
  • distanceType:距离的类型
    • cv.DIST_USER:用户定义的距离
    • cv.DIST_L1:dist=∣x1−x2∣+∣y1−y2∣dist = |x1-x2|+|y1-y2|dist=x1x2+y1y2
    • cv.DIST_L2:欧几里德距离
    • cv.DIST_C:dist=max(∣x1−x2∣,∣y1−y2∣)dist = max(|x1-x2|, |y1-y2|)dist=max(x1x2,y1y2)
  • maskSize:距离变换遮罩的大小,通常取 3, 5
  • labelType:生成的标签数组的类型
    • cv.DIST_LABEL_CCOMP:每个连接的零组件(及最接近连接组件的所有非零像素)被指定相同的标签
    • cv.DIST_LABEL_PIXEL:每个零像素(及离它最近的所有非零像素)都有自己的标签
  • dst:计算距离的输出图像,8-bit 或 32-bit 单通道图像,大小与 src 相同
  • labels:标签的输出图像,CV_32SC1类型, 大小与 src 相同

例程 11.39 基于形态学梯度的分水岭算法

梯度处理可以使用 Sobel、Canny 梯度算子,也可以用形态学梯度操作获得梯度图像。

基于梯度的分水岭算法对微弱的边缘有着良好的响应,但图像中的噪声容易导致图像的过分割。对此,在对梯度图像进行阈值分割转换为二值图像后,运用开运算消除噪点非常重要,可以有效地抑制梯度图像的过分割。

    # 11.39 基于形态学梯度的分水岭算法img = cv2.imread("../images/Fig1039a.tif", flags=1)  # 读取彩色图像(BGR)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转为灰度图像# 图像的形态学梯度kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 生成 5*5 结构元grad = cv2.morphologyEx(gray, cv2.MORPH_GRADIENT, kernel)  # 形态学梯度# 阈值分割,将灰度图像分为黑白二值图像_, thresh = cv2.threshold(np.uint8(grad), 0.2*grad.max(), 255, cv2.THRESH_BINARY)# 形态学操作,生成 "确定背景" 区域kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))  # 生成 3*3 结构元opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)  # 开运算,消除噪点sure_bg = cv2.dilate(opening, kernel, iterations=3)  # 膨胀操作,生成 "确定背景" 区域# 距离变换,生成 "确定前景" 区域distance = cv2.distanceTransform(opening, cv2.DIST_L2, 5)  # DIST_L2: 3/5_, sure_fg = cv2.threshold(distance, 0.1 * distance.max(), 255, 0)  # 阈值选择 0.1*max 效果较好sure_fg = np.uint8(sure_fg)# 连通域处理ret, component = cv2.connectedComponents(sure_fg, connectivity=8)  # 对连通区域进行标号,序号为 0-N-1markers = component + 1  # OpenCV 分水岭算法设置标注从 1 开始,而连通域编从 0 开始kinds = markers.max()  # 标注连通域的数量maxKind = np.argmax(np.bincount(markers.flatten()))  # 出现最多的序号,所占面积最大,选为底色markersBGR = np.ones_like(img) * 255for i in range(kinds):if (i!=maxKind):colorKind = [np.random.randint(0, 255), np.random.randint(0, 255), np.random.randint(0, 255)]markersBGR[markers==i] = colorKind# 去除连通域中的背景区域部分unknown = cv2.subtract(sure_bg, sure_fg)  # 待定区域,前景与背景的重合区域markers[unknown == 255] = 0  # 去掉属于背景的区域 (置零)# 分水岭算法标注目标的轮廓markers = cv2.watershed(img, markers)  # 分水岭算法,将所有轮廓的像素点标注为 -1kinds = markers.max()  # 标注连通域的数量# 把轮廓添加到原始图像上imgWatershed = img.copy()imgWatershed[markers == -1] = [0, 0, 255]  # 将分水岭算法标注的轮廓点设为红色print(img.shape, markers.shape, markers.max(), markers.min(), ret)plt.figure(figsize=(10, 6))plt.subplot(231), plt.axis('off'), plt.title("Origin xupt")plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))  # 显示 img(RGB)plt.subplot(232), plt.axis('off'), plt.title("Gradient")plt.imshow(grad, 'gray')  # 钝化掩蔽plt.subplot(233), plt.axis('off'), plt.title("Sure_bg")plt.imshow(sure_bg, 'gray')  # 确定背景plt.subplot(234), plt.axis('off'), plt.title("Sure_fg")plt.imshow(sure_fg, 'gray')  # 确定前景plt.subplot(235), plt.axis('off'), plt.title("Markers")# plt.imshow(markers, 'gray')  # 图像标注plt.imshow(cv2.cvtColor(markersBGR, cv2.COLOR_BGR2RGB))plt.subplot(236), plt.axis('off'), plt.title("Watershed")plt.imshow(cv2.cvtColor(imgWatershed, cv2.COLOR_BGR2RGB))plt.tight_layout()plt.show()

在这里插入图片描述



(本节完)


版权声明:

OpenCV 例程200篇 总目录-202205更新
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/124813539)

Copyright 2022 youcans, XUPT
Crated:2022-5-15


欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中

【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法
【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法
【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法
【youcans 的 OpenCV 例程200篇】183.基于轮廓标记的分水岭算法
【youcans 的 OpenCV 例程200篇】184.鼠标交互标记的分水岭算法
更多内容,请见:
【OpenCV 例程200篇 总目录-202206更新】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/565500.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

procyon java8_java jdk 8反编译工具JD-GUI、procyon-decompiler、luyten、crf下载使用简介

本文对常用的反编译工具进行简单介绍JD-GUI、procyon-decompiler、luyten、crf反编译工具分类JD-GUIJDK7以及之前可以使用 JD-GUI,如果版本>1.8 各种问题http://java-decompiler.github.ioprocyon-decompiler如果版本>1.8 ,可以使用 procyon-dec…

SpringBoot页面出现 Whitelabel Error Page

我们运行SpringBoot项目之后需要通过Tomcat进行访问,但是我们访问的时候出现了Whitelabel Error Page的错误,我们该如何解决呢??? 错误页面 究其原因是我们的主程序缺少一个RestController的注解。 没有使用RestCon…

SpringBoot入门小案例

使用SpringBoot项目输出一个hello SpringBoot的入门小项目。 1.再IDEA中创建SpringBoot项目,创建完成如下所示。 2.项目创建完后打开包结构,WebApplication是项目的入口,是启动类,SpringBootApplication,这个注解非常…

mysql5.6 python_Centos-6.5 + python3 + mysql5.6 环境搭建

注意:Centos6.5 是刚装好的系统yum install lrzsz (ftp上传和下载)yum install -y gcc yum install -y gcc gcc-c yum install zlib-devel yum install zlib(编译环境的4个依赖)yum install openssl-devel -y (这个是解决python3 中pip3 会报ssl的错)安装…

【youcans 的 OpenCV 例程200篇】183.基于轮廓标记的分水岭算法

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法 【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】183.基…

【youcans 的 OpenCV 例程200篇】184.鼠标交互标记的分水岭算法

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法 【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】183.基…

java排班_使用java规则引擎Drools自动排班前言.doc

使用java规则引擎Drools自动排班前言使用java规则引擎Drools自动排班前言本文以一个经简化的运输车队自动排班需求为例,详细讲解了如何使用java规则引擎Drools进行商业规则的形式语言描述,并编写java代码实现问题求解。?背景介绍(引自Drools中文文档)?…

SpringBoot多环境配置与使用

我们在开发应用的时候,通常同一套程序会被应用和安装到几个不同的环境中,比如开发、测试、生产等。 其中每个环境的数据库地址、服务器端口等配置都不同。如果在为不同环境打包时都要频繁的修改配置文件,那必将是个非常繁琐的且容易出错的事…

【youcans 的 OpenCV 例程200篇】185.图像金字塔之高斯金字塔

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】185.图像金字塔之高斯金字塔 6. 图像金字塔 图像金字塔是一种以多分辨率来解释图像的结构,常用于图像分割、图像压缩和机器视觉。 图像金字塔是一系列来源于同一张原始图像、以金字塔形状排列…

java常用的缓存_java 常用缓存 - 只对肉有感觉的个人空间 - OSCHINA - 中文开源技术交流社区...

缓存是日常开发的粗茶淡饭,如果应用对某类数据有着较高的读取频次,并且改动较小时那就非常适合利用缓存来提高性能JVM 缓存使用全局变量,如 Map、List等容器用于存放数据,可以认为是堆缓存ehcacheehcache直接在jvm虚拟机中缓存&am…

SpringBoot获取配置文件常量值

在我们你的日常开发中,经常会有一些常量,变动较少,但是我们不能在java代码中写死,这样每次修改都得去java代码中修改,引用地方较多时我们需要修改很多java文件;我们可以集中写在某个配置文件中,…

【youcans 的 OpenCV 例程200篇】186.图像金字塔之拉普拉斯金字塔

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】186.图像金字塔之拉普拉斯金字塔 图像金字塔是一种以多分辨率来解释图像的结构,常用于图像分割、图像压缩和机器视觉。 图像金字塔是一系列来源于同一张原始图像、以金字塔形状排列的分辨率逐步…

java string format s_JAVA字符串格式化-String.format()的使用

常规类型的格式化String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处。format()方法有两种重载形式。format(String format, Object... args) 新字符串使用本地语言环境&#xff0c…

【youcans 的 OpenCV 例程200篇】187.由拉普拉斯金字塔还原图像

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】187.由拉普拉斯金字塔还原图像 图像金字塔是一系列来源于同一张原始图像、以金字塔形状排列的分辨率逐步降低的图像集合。从底层图像可以看清更多细节,从顶层图像可以看到更多的轮廓特征。通常&…

wifidog java_wifidog 配置中文说明

#网关IDGatewayID default#外部网卡ExternalInterface eth0#无线网卡GatewayInterface eth0#无线IPGatewayAddress 192.168.1.1#路由状态HTMLHtmlMessageFile wifidog-msg.html#验证服务器#AuthServer {# Hostname (Mandatory; Default: NONE)# SSLAvail…

整型和浮点型之间的转化

在Java中,我们如何将整型转化为浮点型,或者我们如何将浮点型转化成整型的呢? 结果演示 代码演示 package com.ten;public class Zidongzh {public static void main(String[] args) {double a 127.0;float b(float)a;float c(float)b;int…

【youcans 的 OpenCV 例程200篇】188.基于拉普拉斯金字塔的图像融合

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】188.基于拉普拉斯金字塔的图像融合 图像金字塔是一系列来源于同一张原始图像、以金字塔形状排列的分辨率逐步降低的图像集合。从底层图像可以看清更多细节,从顶层图像可以看到更多的轮廓特征。通…

leetcode combinations java_[LeetCode][Java] Combinations

题目:Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.For example,If n 4 and k 2, a solution is:[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],]题意:给定两个整数 n 和 k,返回1 ...n中k个数字的全部的组合。…

【youcans 的 OpenCV 例程200篇】189.基于掩模的拉普拉斯金字塔图像融合

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】189.基于掩模的拉普拉斯金字塔图像融合 图像金字塔是一系列来源于同一张原始图像、以金字塔形状排列的分辨率逐步降低的图像集合。从底层图像可以看清更多细节,从顶层图像可以看到更多的轮廓特征…

中奖程序

使用Java做了一个中奖程序,程序中已经设置中奖的号码,根据文本提示会让你输入四个数字,当你输入你的四个数字之后程序会给出你是否中奖的结果显示。 结果演示 代码演示 package com.ten; import java.util.Scanner; public class ZhongJi…