探索图像分割技术:使用 OpenCV 的分水岭算法

贾斯卡兰·巴蒂亚

一、说明

        图像分割是计算机视觉的一个基本方面,多年来经历了巨大的转变。这将是一系列三篇博客文章,深入研究三种不同的图像分割技术 - 1使用OpenCV的经典分水岭算法,2使用PyTorch实现的基于深度学习的UNet模型,3 SOTA图像分割模型。同时,这部分重点介绍分水岭算法及其使用 OpenCV 的实现。在下一部分中,我们还将在人类分割数据集上训练UNet模型,展示基于深度学习的技术的强大功能和适用性。

二、什么是图像分割?

        图像分割涉及将图像分区为多个段或区域,每个段或区域包含一组像素。最终目标是将图像的表示简化或修改为更有意义的内容,从而使其更易于分析。这些技术已广泛应用于从图像中的物体识别到医学成像诊断的众多应用中。

三、经典路线:使用 OpenCV 的分水岭算法

        在传统的图像分割方法领域,分水岭算法占有重要地位。该算法将图像可视化为地形景观,在图像内生成“集水盆地”和“分水岭线”以隔离不同的对象。以简化的方式,任何灰度影像都可以被视为地形表面,其中高强度表示山峰和丘陵,而低强度表示山谷。

        尽管在概念上易于理解和有效,但分水岭算法有时会导致过度分割,即对象被分成许多段。但是,微调算法并添加预处理步骤可以提高算法的性能。

四、分水岭算法和OpenCV

  1. 阈值:在分水岭算法的上下文中,阈值在识别图像的某些部分方面起着重要作用。将图像转换为灰度后,该算法对灰度图像应用阈值以获得有助于分离前景(要分割的对象)和背景的二进制图像。
# Load image
img = cv2.imread('water_coins.jpg')
imshow("Original image", img)# Grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Threshold using OTSU
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
imshow("Thresholded", thresh)

        2.开运算(侵蚀后扩张):在此步骤中,执行打开操作,即侵蚀操作,然后进行扩张操作。此步骤的目的主要是消除噪音。侵蚀操作消除了图像中的小白噪声,但它也会缩小我们的对象。在此之后,通过膨胀操作,我们可以保留物体的大小,同时将噪声拒之门外。

        先让我们了解侵蚀和扩张

  1. 侵蚀:此操作会侵蚀前景对象的边界。它的工作原理是创建一个卷积内核并将其传递到图像上。如果内核下区域中的任何像素为黑色,则内核中间的像素设置为黑色。此操作可有效消除小白噪声。
  2. 扩张:侵蚀后进行扩张,这本质上与侵蚀相反。它将像素添加到图像中对象的边界。如果内核下区域中的任何像素为白色,则内核中间的像素设置为白色。
# noise removal
kernel = np.ones((3,3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN,kernel, iterations = 2)

        让我们分解一下:

  1. 创建内核: np.ones((3,3),np.uint8) 创建一个 3x3 矩阵,所有元素为“1”。这体现了我们形态学操作的“结构元素”。它可以是不同的形状(方形、圆形等),但在这里,我们使用方形。
  2. 应用开运算: cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations = 2) 应用开运算。 'thresh' 是阈值处理后获得的二值图像,cv2.MORPH_OPEN 表示我们要执行开运算,'kernel'是我们的结构元素,'iterations = 2' 表示我们要执行该操作两次。
  3. 用于背景识别的膨胀:在此步骤中,膨胀操作用于识别图像的背景区域。上一步的结果是,噪声已被消除,受到膨胀。膨胀后,物体(或前景)周围的很大一部分有望成为背景区域(因为膨胀会扩展物体)。这个“确定背景”区域有助于分水岭算法的后续步骤,我们的目标是识别不同的段/对象。
# sure background area
sure_bg = cv2.dilate(opening, kernel, iterations=3)

        4. 距离变换:流域算法涉及应用距离变换来识别可能成为前景的区域。下面是此步骤的代码:

# Finding sure foreground area
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2,5)
ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)

        在此步骤中,我们将执行两项操作:

  • 应用距离变换: cv2.distanceTransform 函数使用 cv2.DIST_L2(欧几里德距离)计算从每个二值图像像素到最近的零像素的距离。距离变换帮助我们识别可能位于前景的区域。函数 cv2.distanceTransform(opening, cv2.DIST_L2, 5) 计算此变换。
  • 对距离变换进行阈值处理:计算距离变换后,我们对该变换后的图像应用阈值处理以获得确定的前景区域。 cv2.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0) 函数调用应用阈值。第二个参数 0.7*dist_transform.max() 将阈值级别设置为距离变换找到的最大距离的 70%。距离变换值高于此阈值的像素被设置为确定前景。

        5.识别未知区域:我们识别未知区域,即既不是确定前景也不是确定背景的区域。我们首先将确定的前景(sure_fg)转换为无符号的8位整数。然后我们从确定背景(sure_bg)中减去确定前景以获得未知区域。未知区域是分水岭算法的关键,因为它表示不同对象之间或对象与背景之间的过渡区域。

# Finding unknown region
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)imshow("SureFG", sure_fg)
imshow("SureBG", sure_bg)
imshow("unknown", unknown)

  • sure_fg(确定前景):硬币占据的区域,或者更确切地说,硬币的中心(由于使用了距离变换和随后的阈值),将被标识为确定前景。
  • sure_bg(确定背景):硬币周围的区域以及硬币内部足够大以至于无法通过形态操作去除的任何区域都标记为确定背景。从本质上讲,这些是没有硬币的区域。
  • 未知(未知区域):这些区域既不是确定前景的一部分,也不是确定背景的一部分。这些是靠近硬币边缘的区域,算法没有足够的信心将它们指定为前景(硬币)或背景(硬币周围的区域)。

        6. 标记sure_bg、sure_fg和未知区域:这涉及创建标记并标记其中的区域。我们标记的区域是确定背景 ()、确定前景 () 和未知区域。下面是此步骤的代码片段:sure_bgsure_fg

# Marker labelling
# Connected Components determines the connectivity of blob-like regions in a binary image.
ret, markers = cv2.connectedComponents(sure_fg)# Add one to all labels so that sure background is not 0, but 1
markers = markers+1# Now, mark the region of unknown with zero
markers[unknown==255] = 0

        此外,我们希望确定背景的标记与确定前景不同,我们为标记图像中的所有标签添加 1。执行此操作后,确定背景像素标记为 1,确定前景像素从 2 开始标记。

7. 应用分水岭算法

        接下来,步骤是将分水岭算法应用于标记(在前面的步骤中找到的标记区域)

markers = cv2.watershed(img,markers)
img[markers == -1] = [255,0,0]
imshow("img", img)

        cv2.watershed() 函数修改标记图像(标记)本身。对象的边界在标记图像中用 -1 标记。图像中的不同对象用不同的正整数标记。我们不确定是背景还是前景的区域是由分水岭算法确定的——它们要么被分配给背景,要么被分配给某个对象,从而在对象和背景之间产生清晰的边界划分。

五、分水岭算法如何工作?

        流域算法中的“洪水”和“大坝建设”概念本质上是一种描述算法如何工作的隐喻方式

  1. 泛滥:“泛洪”过程是指根据图像的梯度扩展每个标记区域(标记)。在此上下文中,梯度表示地形高程,高强度像素值表示峰值,低强度像素值表示山谷。洪水从山谷或强度值最低的地区开始。泛洪过程的执行方式是,图像中的每个像素都被分配一个标签。它收到的标签取决于哪个标记的“洪水”首先到达它。如果一个像素与多个标记等距,则它目前仍作为未知区域的一部分。
  2. 大坝建设: 随着洪水过程的继续,来自不同标记(代表图像中的不同区域)的洪水最终将开始相遇。当他们这样做时,就会建造一个“大坝”。在算法方面,这种大坝建设对应于标记图像中边界的创建。这些边界被分配一个特殊的标签(通常为 -1)。大坝建在不同标记的洪水相遇的位置,这些位置通常是图像中强度快速变化的区域 - 表示图像中不同区域之间的边界。

        应用分水岭算法后,我们的标记图像(最初具有确定前景、确定背景和未知区域的标签)现在包含图像中每个不同对象的标签。我们有效地将图像分割成不同的对象(硬币)和背景。

六、结论

        分水岭算法提供了一种直观高效的图像分割方法,允许从复杂图像中有意义地提取特征。使用 OpenCV 库在 Python 中的实际实现进一步简化了该过程,并提供了一种执行图像分割的快速方法。虽然它的基本形式可能会受到过度分割的影响,但适当的图像预处理和参数调整可以有效地解决这个问题,使其成为图像分析领域的强大工具。永远记住,分割技术的选择取决于项目的具体要求和约束。

参考资料:

What is OpenCV? The Complete Guide (2023) - viso.ai

Jaskaran Bhatia – Medium        

 

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

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

相关文章

Ubuntu小知识总结

Ubuntu相关的小知识总结 一、Ubuntu系统下修改用户开机密码二、Vmware虚拟机和主机之间复制、粘贴内容、拖拽文件的详细方法问题描述Vmware tools灰色不能安装解决方法小知识点:MarkDown的空格 三、Ubuntu虚拟机网络无法连接的几种解决方法1.重启网络编辑器2. 重启虚…

Linux下使用openssl为harbor制作证书

openssl是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证…

免费高清壁纸下载(静态和动态壁纸)

一、网址下载(静态壁纸) 高清图片直接另存为就可以了。然后在电脑空白处右键——个性化设置即可替换壁纸。 ①网址:https://www.hippopx.com ②极简壁纸:https://bz.zzzmh.cn/index ③彼岸图网:http://pic.netbian…

OpenCV17-图像形态学操作

OpenCV17-图像形态学操作 1.形态学操作1.1腐蚀1.2膨胀 2.形态学应用2.1开运算2.2闭运算2.3形态学梯度2.4顶帽运算2.5黑帽运算2.6击中击不中变换2.7形态学应用示例 1.形态学操作 1.1腐蚀 图像腐蚀(Image erosion)可用于减小图像中物体的大小、填充孔洞或…

华为eNSP配置专题-VRRP的配置

文章目录 华为eNSP配置专题-VRRP的配置0、参考文档1、前置环境1.1、宿主机1.2、eNSP模拟器 2、基本环境搭建2.1、基本终端构成和连接 2.VRRP的配置2.1、PC1的配置2.2、接入交换机acsw的配置2.3、核心交换机coresw1的配置2.4、核心交换机coresw2的配置2.5、配置VRRP2.6、配置出口…

C++多态、虚函数、纯虚函数、抽象类

多态的概念 通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。 举个简单的例子:抢红包,我们每个人都只需要点击一下红包,就会抢到金额。有些人能…

OpenCV中world模块介绍

OpenCV中有很多模块,模块间保持最小的依赖关系,用户可以根据自己的实际需要链接相关的库,而不需链接所有的库,这样在最终交付应用程序时可以减少总库的大小。但如果需要依赖OpenCV的库太多,有时会带来不方便,此时可以使…

vue2 element手术麻醉信息系统源码,手术预约、手术安排、排班查询、手术麻醉监测、麻醉记录单

手术麻醉临床信息系统有着完善的临床业务功能,能够涵盖整个围术期的工作,能够采集、汇总、存储、处理、展现所有的临床诊疗资料。通过该系统的实施,能够规范麻醉科的工作流程,实现麻醉手术过程的信息数字化,自动生成麻…

mac 升级node到指定版本

node版本14.15.1升级到最新稳定版18.18.2 mac系统 先查看一下自己的node版本 node -v开始升级 第一步 清除node的缓存 sudo npm cache clean -f第二步 安装n模块【管理模块 n是管理 nodejs版本】 sudo npm install -g n第三步升级node sudo n stable // 把当前系统的 Node…

计算机毕业设计 基于SpringBoot智慧养老中心管理系统的设计与实现 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…

【趣味随笔】盘点国内外做双足机器人的公司

📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…

leetCode 392. 判断子序列 动态规划 + 优化空间 / 双指针 等多种解法

392. 判断子序列 - 力扣(LeetCode) 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如&#xff0c…

Aocoda-RC F405V2 FC(STM32F405RGT6 v.s. AT32F435RGT7) IO Definitions

[TOC](Aocoda-RC F405V2 FC(STM32F405RGT6 v.s. AT32F435RGT7) IO Definitions) 1. 源由 Aocoda-RC F405V2飞控支持betaflight/inav/Ardupilot固件,是一款固件兼容性非常不错的开源硬件。 之前我们对比过STM32F405RGT6 v.s. AT32F435RGT7 Comparison for Flight …

ThreadLocal源码解密

1 背景 作为一只懒懒地程序员,其实我是不太爱看源码的,晦涩、深奥、难懂、耗费时间等等,就觉得不是我这种能力平平地小老百姓能吃得消的,但现实比人强,记得曾经我就被不懂原理的情况下乱用ThreadLocal给毒打了。 犹记得当时在一个JSF服务中的责任链的校验场景中需要在源…

UART、SPI、I2C通信协议超全入门教程

本文引注: https://mp.weixin.qq.com/s/lVWK8xlDt7cOLi8WHYSuPg 1.SPI协议 1.基础 2.简介 3.工作原理 4.SPI数据传输步骤与优缺点 2.UART协议

分布式微服务技术栈-SpringCloud<Eureka,Ribbon,nacos>

微服务技术栈 一、微服务 介绍了解1 架构结构案例与 springboot 兼容关系拆分案例拆分服务拆分-服务远程调用 2 eureka注册中心Eureka-提供者与消费者Eureka-eureka原理分析Eureka-搭建eureka服务Eureka-服务注册Eureka-服务发现 3 Ribbon组件 负载均衡Ribbon-负载均衡原理Ribb…

python随手小练6

1、汉诺塔 汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放…

ubuntu终端命令行下如何使用NetworkManager(netplan)来配置wifi网络

最近在给家里折腾一个文件共享服务器给家里的小米摄像头保存监控视频用。树莓派太贵了,找来找去发现香橙派orangepi zero3 是最低成本的替代解决方案(网络足够快,CPU的IO能力足够强),香橙派orangepi zero3的操作系统是…

学信息系统项目管理师第4版系列33_信息化发展

1. 企业信息化发展战略要点 1.1. 【高22下选12】 1.2. 以信息化带动工业化 1.3. 信息化与企业业务全过程的融合、渗透 1.4. 信息产业发展与企业信息化良性互动 1.5. 充分发挥政府的引导作用 1.6. 高度重视信息安全 1.7. 企业信息化改组改造和形成现代企业制度有机结合 …

虚拟化、容器与Docker基本介绍以及安装部署(Docker 基本管理)

目录 1 Docker 概述 1.1 Docker与虚拟机的区别 1.2 容器在内核中支持2种重要技术 1.3 Docker核心概念 2 安装 Docker 2 Docker 镜像操作 2.1 搜索镜像 2.2 获取镜像 2.3 镜像加速下载 2.4 查看镜像信息 2.4.1 查看下载的镜像文件信息 2.4.2 查看下载到本地的所有镜像…