《数字图像处理-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

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

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

相关文章

对 SQL 说“不”~

开发人员注意! 您在当前的应用程序架构中是否面临这些问题? 对 SQL 数据库的高吞吐量。SQL 数据库中的瓶颈。 内存数据存储将是解决问题的方案。Redis 是市场上最受欢迎的内存数据存储和缓存选项。Redis 拥有广泛的生态系统,因为主要科技巨…

54.WEB渗透测试-信息收集- 端口、目录扫描、源码泄露(2)

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于: 易锦网校会员专享课 上一个内容:53.WEB渗透测试-信息收集-端口、目录扫描、源码泄露(1) 关于源码…

Nginx作为下载站点

grep -Ev ^$|# /usr/local/nginx/conf/nginx.conf > /opt/nginx.txt cat /opt/nginx.txt > /usr/local/nginx/conf/nginx.conf用上面的指令提取最小化的配置文件 vim /usr/local/nginx/conf/nginx.conf [rootlocalhost ~]# cat /usr/local/nginx/conf/nginx.conf worker…

解决linux系统求前N月月份的bug

日常工作中,需要获取某个日期(20240531)的前N个月,通常会写命令 date -d "20240531 last-month" %Y%m 我期望得到202404 但是很意外: 经过几轮测试,发现只要月内天数超过30天,即所有…

短视频动画脚本:成都鼎茂宏升文化传媒公司

短视频动画脚本:创作与魅力的探索 在数字化时代的浪潮中,短视频动画以其独特的魅力迅速崛起,成为大众娱乐和信息传播的重要载体。成都鼎茂宏升文化传媒公司作为一名原创文章编辑,我深入探索了短视频动画脚本的创作过程&#xff0…

二,几何相交-5,BO算法分析--(1)正确性

也就是说,BO算法有没有可能误报或者漏报? 一,为什么不会误报? 因为两条线段从不相邻到相邻,或者其中一条线段不存在到相邻,都会进行一次相交测试。所以不会误报。 二,为什么不会漏报&#xff1…

学习算法笔记(7.5)-贪心算法(股票售卖问题)

学到这里的大家应该都非常清楚贪心算法到底是怎么一回事了,说白了就是动态规划的一种特例,没有动态规划的使用范围广,但是效率却比动态规划效率高,贪心算法不考虑之前的情况,只考虑当前的最优选择以期达到最优的结果。…

五款效率软件助你事半功倍

1、🔗 亿可达 作为一款自动化工具,亿可达被誉为国内版的免费Zaiper。它允许用户无需编程知识即可将不同软件连接起来,构建自动化的工作流程。其界面设计清新且直观,描述语言简洁易懂,使得用户可以轻松上手。 2、&…

轻松产出创新点!多元时间序列最新可参考成果,高性能高精度

今天给大家推荐一个好挖创新点的研究方向:多元时间序列。 多元时间序列是我们解决复杂系统分析和预测问题的重要工具。它通过综合分析多个相关时序数据,可以给我们提供更精准的预测结果,非常适合处理涉及多个变量和多个时间点数据的场景&…

基于 GhostNet 不同版本的图像识别

1、介绍 GhostNet 文章地址:[1911.11907] GhostNet: More Features from Cheap Operations (arxiv.org) 主要思想: 特征提取的时候,很多特征图是具有高度相似性的,也就是说存在许多的冗余特征图。 从另一个角度想,…

从零开始实现自己的串口调试助手(5) -实现HEX显示/发送/接收

实现HEX显示: HEX 显示 -- 其实就是 十六进制显示 --> a - 97(10) --> 61(16) 添加槽函数(bool): 实现槽函数: 注意: 注意QString 没有处理HEX显示的相关API 需要使用 toUtf-8 来 转换位QByteArry 类型, 利用其中的API 来处理HEX格式(toHex fromHex) vo…

Kubernetes外部服务管理Ingress介绍

前言 在 Kubernetes 集群中,管理外部服务的访问和流量路由至关重要。通过使用 Ingress 控制器,我们能够实现对外部服务的有效管理,配置灵活的路由规则,并实现负载均衡和流量控制。 目录 一、Ingress 介绍 1. Ingress 概述 2.…

Windows下搭建Cmake编译环境进行C/C++文件的编译

文章目录 1.下载Cmake2.安装MinGW-w643.进行C/C文件的编译 1.下载Cmake 网址:https://cmake.org/download/ 下载完成后安装,勾选“Add CMake to the system PATH for the current user" 点击Finish完成安装,在cmd窗口验证一下是否安…

C++并发之线程(std::thread)

目录 1 概述2 使用实例3 接口使用3.1 construct3.2 assigns3.3 get_id3.4 joinable3.5 join3.6 detach3.7 swap3.8 hardware_concurrency 1 概述 Thread类来表示执行的各个线程。   执行线程是指可以在多线程环境中与其他此类序列同时执行的指令序列,同时共享相同…

python使用pandas的常用操作

文章目录 安装导入主要数据结构常用方法和操作创建数据结构读取和写入数据数据选择和过滤数据操作基本统计分析分组和聚合合并和连接重塑数据1. pivot 和 pivot_table2. melt3. stack和 unstack 常用方法总结pandas操作excel安装相关库 读取单个工作表读取指定工作表读取多个工…

短视频矩阵系统源码---开发BS架构B/S(Browser/Server Architecture)架构

短视频矩阵系统源头开发------- 第一款叫做筷子科技,这个筷子科技剪辑和发布都是没有问题的,但是前一段时间他的剪辑发个公告,每个账号只能发两条,另外它的唯一缺点就是它成本比较高的,入门门槛应该在12800左右&#…

CHATGPT升级plus(已有账号前提下)

注册wildcard(虚拟卡) 注册号账号后先进行充值,充值后选择CHATGPT一键升级按照他的流程来即可 Wildcard网址:Wildcard跳转注册 填写邀请码充值时少两美金合计14¥ 邀请码:OL3QXTRH

【2022-2011年】地级市数字经济指数原始数据+测算dofile+结果

参照赵涛等(2020)的文章,利用熵值法对城市数字经济指数进行测算,包括原始数据、线性插值、回归填补3种版本下测算的数字经济指数。保留原始数据、stata代码和测算结果,大家可进行复现 一、数据介绍 数据名称&#x…

Python爬虫协程批量下载图片

import aiofiles import aiohttp import asyncio import requests from lxml import etree from aiohttp import TCPConnectorclass Spider:def __init__(self, value):# 起始urlself.start_url value# 下载单个图片staticmethodasync def download_one(url):name url[0].spl…