当前位置: 首页 > news >正文

《数字图像处理-OpenCV/Python》第15章:图像分割

《数字图像处理-OpenCV/Python》第15章:图像分割


本书京东 优惠购书链接 https://item.jd.com/14098452.html
本书CSDN 独家连载专栏 https://blog.csdn.net/youcans/category_12418787.html

在这里插入图片描述


第15章:图像分割


图像分割是由图像处理到图像分析的关键步骤,是计算机视觉的基础,也是图像理解的重要组成部分。图像分割的基本方法是指基于图像灰度值的不连续性和相似性,根据灰度、彩色、空间纹理和几何形状等特征,把图像划分成若干个具有特殊性质的区域,或把目标从背景中分离出来。

本章内容概要

  • 介绍区域生长与分离和超像素区域分割算法。
  • 学习分水岭算法,实现图像分割。
  • 学习图割分割算法,实现图像分割。
  • 学习均值漂移算法,实现目标描述与定位。
  • 学习运动图像分割算法,如帧间差分法、背景差分法和密集光流法。

15.3 分水岭算法

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

分水岭算法是指将像素值视为海拔高度,图像就像一张高低起伏的地形图,每个局部极小值及其影响区域称为集水盆,集水盆的边界则形成分水岭。

算法的实现过程可以理解为洪水淹没的过程:最低点首先被淹没,然后水逐渐淹没整个山谷;水位升高到一定高度就会溢出,于是在溢出位置修建堤坝;不断提高水位,重复上述过程,直到所有的点被淹没。所建立的一系列堤坝就成为分隔各个盆地的分水岭。

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

分水岭算法是基于形态学的图像分割算法,体现了边缘检测、阈值处理和区域提取的概念和思想,往往会产生更稳定的分割结果。

最简单的分水岭算法能基于距离变换,通过像素到最近的零像素点的距离生成标注图像;基于梯度的分水岭算法能通过梯度函数使集水盆只响应想要探测的目标,对微弱边缘有良好的响应,但噪声容易导致过分割;基于标记点(标记符控制)的分水岭算法是主流的分割算法,其思想是利用先验知识来帮助分割。


OpenCV中的函数cv.watershed能实现基于标记点的分水岭算法。
使用函数cv.watershed输入标记图像,图像中每个非零像素代表一个标签,对图像的部分像素做标记,表明它的所属区域是已知的。

函数原型

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

参数说明

  • image:输入图像,是8位三通道彩色图像。
  • markers:标记图像,是32位单通道图像。

注意问题

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

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


【例程1504】基于距离变换的分水岭算法

本例程介绍基于距离变换的分水岭算法的实现方法,通过每个像素到最近的零像素点生成标注图像。
基于距离变换的分水岭算法的主要步骤如下。
(1) 通过阈值分割将灰度图像转换为二值图像,使用开运算消除噪点。
(2) 通过形态学的膨胀运算,生成确定背景区域sureBG。
(3) 通过距离变换,由阈值分割得到高亮区域,生成确定前景区域sureFG。
(4) 对确定前景区域进行连通性分析,即对多个分割目标编号。
(5) 确定前景区域与确定背景区域重合的部分,作为待定区域unknown。
(6) 从连通域标记图像中去除确定背景区域,作为标注图像。
(7) 基于标记图像使用分水岭算法进行分割,得到分割的目标轮廓,标注为-1。


# 【1504】基于距离变换的分水岭算法
import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltif __name__ == '__main__':img = cv.imread("../images/Fig0301.png", flags=1)  # 彩色图像(BGR)gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)  # 灰度图像# 阈值分割,将灰度图像分为黑白二值图像ret, thresh = cv.threshold(gray, 0, 255, cv.THRESH_OTSU)# 形态学操作,生成确定背景区域 sureBGkernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))  # 生成 3×3 结构元opening = cv.morphologyEx(thresh, cv.MORPH_OPEN, kernel, iterations=2)  # 开运算,消除噪点sureBG = cv.dilate(opening, kernel, iterations=3)  # 膨胀操作,生成确定背景区域# 距离变换,生成确定前景区域 sureFGdistance = cv.distanceTransform(opening, cv.DIST_L2, 5)  # DIST_L2: 3/5_, sureFG = cv.threshold(distance, 0.1 * distance.max(), 255, cv.THRESH_BINARY)  # 阈值选择 0.1max 效果较好sureFG = np.uint8(sureFG)# 连通域处理ret, component = cv.connectedComponents(sureFG, 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, size=(1, 3))markersBGR[markers==i] = colorKind# 去除连通域中的背景区域部分unknown = cv.subtract(sureBG, sureFG)  # 待定区域,前景与背景的重合区域markers[unknown==255] = 0  # 去掉属于背景的区域 (置零)# 用分水岭算法标注目标的轮廓markers = cv.watershed(img, markers)  # 分水岭算法,将所有轮廓的像素点标注为 -1# 把轮廓添加到原始图像上mask = np.zeros(img.shape[:2], np.uint8)mask[markers==-1] = 255mask = cv.dilate(mask, kernel=np.ones((3,3)))  # 轮廓膨胀,使显示更明显imgWatershed = img.copy()imgWatershed[mask==255] = [255, 0, 0]  # 将分水岭算法标注的轮廓点设为蓝色plt.figure(figsize=(9, 6))plt.subplot(231), plt.axis('off'), plt.title("1. Original")plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))plt.subplot(232), plt.axis('off'), plt.title("2. Gray image")plt.imshow(gray, 'gray')plt.subplot(233), plt.axis('off'), plt.title("3. Sure background")plt.imshow(sureBG, 'gray')  # 确定背景plt.subplot(234), plt.axis('off'), plt.title("4. Sure frontground")plt.imshow(sureFG, 'gray')  # 确定前景plt.subplot(235), plt.axis('off'), plt.title("5. Markers")plt.imshow(cv.cvtColor(markersBGR, cv.COLOR_BGR2RGB))plt.subplot(236), plt.axis('off'), plt.title("6. Watershed")plt.imshow(cv.cvtColor(imgWatershed, cv.COLOR_BGR2RGB))plt.tight_layout()plt.show()

在这里插入图片描述

图15-4 基于距离变换的分水岭算法

程序说明:

(1) 运行结果,基于距离变换的分水岭算法如图15-4所示。图15-4(1)所示为原始图像,图15-4(2)所示为图15-4(1)的灰度图。
(2) 图15-4(3)所示为确定背景,图中的黑色区域为确定背景区域,由阈值分割和形态学处理得到。图15-4(4)所示为确定前景,图中的白色区域为确定前景区域,由距离变换和阈值处理得到。
(3) 图15-4(5)所示为由分水岭算法得到的标记图像,图15-4(6)所示为把标记的轮廓添加到图15-4(1)上的图像。其中,轮廓膨胀并非必要步骤,只是为了使图像中的轮廓显示更醒目。


【例程1505】基于轮廓标记的分水岭算法

基于轮廓标记的分水岭算法的思想是利用先验知识帮助分割。本例程先用梯度算子进行边缘检测,然后通过查找图像轮廓,生成标记图像来引导分割。
基于轮廓标记的分水岭算法的步骤如下。
(1) 对图像进行梯度处理,以获得梯度图像。
(2) 查找梯度图像和绘制图像轮廓。
(3) 基于图像轮廓生成标记图像。
(4) 基于标记图像使用分水岭算法进行分割,得到各个分割目标的轮廓。


版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/139433259)
Copyright 2024 youcans, XUPT
Crated:2024-06-04

《数字图像处理-OpenCV/Python》 独家连载专栏 : https://blog.csdn.net/youcans/category_12418787.html

相关文章:

  • IDEA 2023.3.6 下载、安装、激活与使用
  • 碳微球是新型碳材料 在高科技领域应用价值极高
  • Re0:从零开始的C++游戏开发【中】
  • 计网期末复习指南(六):应用层(DNS、FTP、URL、HTTP、SMTP、POP3)
  • Java学习19-List、set容器
  • 【云原生 | 60】Docker中通过docker-compose部署kafka集群
  • python-web应用程序-Django-From组件
  • jeecg dictText字典值
  • C++:栈(stack)、队列(queue)、优先级队列(priority_queue)
  • 【计算机毕设】基于SpringBoot的民宿在线预定平台设计与实现 - 源码免费(私信领取)
  • Java算法篇之二分查找模板
  • C++ Thread多线程并发记录(3)线程创建总结
  • 基础—SQL—DML(数据操作语言)修改和删除
  • 力扣----轮转数组
  • 重学java 61.IO流 ② 字节输出流
  • 分享一款快速APP功能测试工具
  • [译]CSS 居中(Center)方法大合集
  • ➹使用webpack配置多页面应用(MPA)
  • 30天自制操作系统-2
  • CentOS7简单部署NFS
  • HTTP请求重发
  • JS 面试题总结
  • Lucene解析 - 基本概念
  • PHP 的 SAPI 是个什么东西
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • Sequelize 中文文档 v4 - Getting started - 入门
  • Web设计流程优化:网页效果图设计新思路
  • 多线程 start 和 run 方法到底有什么区别?
  • 来,膜拜下android roadmap,强大的执行力
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 小李飞刀:SQL题目刷起来!
  • 一道面试题引发的“血案”
  • 怎样选择前端框架
  • Java性能优化之JVM GC(垃圾回收机制)
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • .NET Core WebAPI中封装Swagger配置
  • .Net Remoting常用部署结构
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET 直连SAP HANA数据库
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • @Autowired注解的实现原理
  • @NestedConfigurationProperty 注解用法
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [].slice.call()将类数组转化为真正的数组
  • [383] 赎金信 js
  • [ACP云计算]易混淆知识点(考题总结)
  • [BZOJ] 3262: 陌上花开