图像分割 - 分水岭算法

article/2025/10/16 5:36:37

目录

1. 介绍

2.  分水岭算法的实现

距离变换

连接连通分量

3. 代码


1. 介绍

图像是由x,y表示的,如果将灰度值也考虑进去的话,那么一幅图像需要一个三维的空间去表示。

这样就可以把x,y轴比作大地,将灰度值的z轴比作地面上的坡度。

因为图像的灰度值是不均匀的,那么也意味着这个地面也是坑坑洼洼的。那么试想一下,下雨的时候,由于地面是不平坦的,雨水会顺着高的地面流向地处。必然会导致有的地方堆满了水,有的地方由于地势较陡,没有雨水

分水岭算法就是利用这种“地形学”,或者说灰度值的不均匀对图像进行分割。 

在这种将图像类比成地形的方法里,主要考虑三种点:

  • 属于区域极小值的点
  • 水滴所在位置的点,如果把水滴放在任意位置,水滴必然流向某个极小值
  • 水等概率的流向不止一个极小值的点

在这里,如果某个区域是极小值,且满足第二个条件的点集称为汇水盆地或者分水岭

满足第三个条件的点形成地形表面的线,称为分界线

分水岭算法实现的思路是:

找到一些初始点,然后对这些点集进行灌水。随着水位的上升,不同区域的水会开始融合。为了阻止这种现象,在这些融合处建立拦水坝,这样拦水坝就把图像进行了分割

初始点的选择需要用到距离变换

2.  分水岭算法的实现

首先尝试对下面的算法进行分水岭算法的分割

 


这里读取的是彩色图像,因为最后的 watershed 函数需要传入彩色图像

这里对图像进行阈值处理的结果为

 


阈值处理发现,这里硬币内部出现了孔洞,在背景上也出现了白色的噪声点

因为开运算可以消除白色的噪声,而闭运算可以消除内部的孔洞,所以这里采用形态学的方法进行处理。具体的可以参考:灰度级形态学 - 灰度开运算和灰度闭运算

 


接下来,通过膨胀,将前景扩大,这样就可以确定哪些是背景,哪些是前景

 

这一步主要为了确定真正的前景区域


距离变换

接下来,通过距离变换可以找到这些硬币近似的中心点。先展示下效果,在做讲解

 

因为数据类型的原因,这种用 matplotlib 展示。这里距离变换会计算前景像素点到周围最近背景像素点的距离,所以这里像素点越亮,距离背景越远。并且输入图像必须是个二值图像

 


然后,获取距离变换中距离背景远处的点,这些点就是我们分水岭算法的初始点

因为现在的前景区域一定是硬币的位置

 


unknown 是不确定区域,或者说,这里是有分线线的地方

 


连接连通分量

它会把将背景标记为 0,其他的对象使用从 1 开始的正整数标记

 

这样,分水岭算法会从每个标记的位置开始注水,除了0未知区域。这样水位升高的时候,不同区域的水就会在未知区域相遇,这样分界线就被找出来了

 

 


分水岭算法会将不同区域之间的边界设置为 -1

watershed的结果中只有-1,0,1,2这样的数

 分水岭算法的结果:

 分割的结果:

 

3. 代码

import cv2
import numpy as np
import matplotlib.pyplot as pltsrc = cv2.imread('./img.png')                       # 彩色图像img = src.copy()
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)          # 转为灰度图像ret, img_bin = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)   # 阈值处理kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))                            # 获取结构元
img_close = cv2.morphologyEx(img_bin, cv2.MORPH_CLOSE, kernel, iterations=3)        # 闭运算填充内部的孔洞
img_open = cv2.morphologyEx(img_close, cv2.MORPH_OPEN, kernel, iterations=2)        # 开运算消除白色噪声img_bin = cv2.dilate(img_open, kernel, iterations=2)                                # 膨胀确定前景和背景
dist_transform = cv2.distanceTransform(img_bin, cv2.DIST_L2, 5)                     # 距离变换ret, img_seed = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, cv2.THRESH_BINARY)   # 获取距离背景最远的点
img_seed = np.uint8(img_seed)       # 转为图像的形式unknown = cv2.subtract(img_bin,img_seed)                # 可能是背景,可能是前景ret, markers = cv2.connectedComponents(img_seed)       # 连接连通分量
markers = markers + 1                                  # 确保背景是1不是0
markers[unknown == 255] = 0                            # 未知区域标记为0markers = cv2.watershed(src, markers)                 # 分水岭算法
src[markers == -1] = [255,0,0]                        # 将边界找出plt.imshow(np.abs(markers),cmap = 'jet')                # 分水岭算法结果
plt.show()cv2.imshow('img',src)                                   # 分割结果
cv2.waitKey()
cv2.destroyAllWindows()


http://chatgpt.dhexx.cn/article/dwdSISh8.shtml

相关文章

【OpenCv】图像分割——分水岭算法

文章目录 1 原理2 算法改进3 API4 实例 1 原理 分水岭分割方法,是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区…

MFC图像处理CImage类常用操作

原文作者&#xff1a;aircraft 原文地址&#xff1a;https://www.cnblogs.com/DOMLX/p/9598974.html MFC图像处理CImage类常用操作 CImage类头文件为#include<atlimage.h> CImage类读取图片CImage.Load("src.bmp"); CImage类保存图片CImage.Save("dst…

使用CImage进行图像处理

MFC和ATL共享的新类CImage为图像处理提供了许多相应的处理方法 CImage类 我们知道&#xff0c;Visual C的CBitmap类和静态图片控件的功能是比较弱的&#xff0c;它只能显示出在资源中的图标、位图、光标以及图元文件的内容&#xff0c;而不像VB中的Image控件可 以显示出绝大多数…

用CImage类来显示PNG、JPG等图片

系统环境&#xff1a;Windows 7 软件环境&#xff1a;Visual Studio 2008 SP1 本次目的&#xff1a;实现VC单文档、对话框程序显示图片效果 CImage 是VC.NET中定义的一种MFC/ATL共享类&#xff0c;也是ATL的一种工具类&#xff0c;它提供增强型的&#xff08;DDB和DIB&#xff…

CImage类(外部图像文件(BMP、GIF、JPEG等)

CImage类 我们知道&#xff0c;Visual C的CBitmap类和静态图片控件的功能是比较弱的&#xff0c;它只能显示出在资源中的图标、位图、光标以及图元文件的内容&#xff0c;而不像VB中的Image控件可 以显示出绝大多数的外部图像文件(BMP、GIF、JPEG等)。因此&#xff0c;想要在对…

CImage的一般使用方法和技巧

Visual C的CBitmap类的功能是比较弱的,它只能显示出在资源中的图标、位图、光标以及图元文件的内容&#xff0c;而不像VB中的Image控件可以显示出绝大多数的外部图像文件(BMP、GIF、JPEG等)。如果想要在对话框或其他窗口中显示外部图像文件则只能借助于第三方提供的控件或代码,…

图像处理(C++ CImage class)学习笔记

基础篇 A. 图像三原色及灰度值 A1. 彩色图像的三原色 图像三原色 — R&#xff1a;红色red — G&#xff1a;绿色green — B&#xff1a;蓝色blue三原色的取值范围&#xff1a;0&#xff08;无&#xff09;~255&#xff08;满&#xff09; — 红色&#xff1a;R255 G0 B0 —…

Cimage

本系列文章由zhmxy555编写&#xff0c;转载请注明出处。 http://blog.csdn.net/zhmxy555/article/details/7422922 作者&#xff1a;毛星云 邮箱&#xff1a; happylifemxyqq.com 欢迎邮件交流编程心得 我们知道&#xff0c;Visual C中的CBitmap类的功能简直太弱小了&am…

【无标题】c++ MFC图像处理CImage类常用操作代码

原文作者&#xff1a;aircraft 原文地址&#xff1a;https://www.cnblogs.com/DOMLX/p/9598974.html 我看了一下发现关于c下的CImage图像处理类 的图像处理相关的介绍真的是比较少&#xff0c;因为我要做大二的数据结构的课程设计&#xff0c;要用纯c语言去实现&#xff08;老…

C++,CImage类的建立方法(可以打开图像和保存)

建立CImage类&#xff08;以vs2015为例&#xff09; 一&#xff0c; 新建一个MFC项目&#xff1a;名字为 image3 二&#xff0c; 单个文档&#xff0c;MFC标准&#xff0c;然后完成。 三&#xff0c;打开应用程序的 stdafx.h 文件添加 CImage 类的包含文件&#xff1a; #incl…

VB.net 进程通信中FindWindow、FindWindowEX、SendMessage函数的理解

目录 一、代码背景 二、主要工具 三、函数解析 1、FindWindow&#xff1a; 2、 FindWindowEx&#xff1a; 3、SendMessage&#xff1a; 四、具体代码示例&#xff1a; 1、第一部分功能&#xff1a; A、接收端&#xff1a; B、发送端 C、运行测试 2.第二部分功能&…

C#-FindWindow的用法

C# FindWindow用法 函数功能&#xff1a;该函数获得一个顶层窗口的句柄&#xff0c;该窗口的类名和窗口名与给定的字符串相匹配。 这个函数不查找子窗口。在查找时不区分大小写。 函数型&#xff1a;HWND FindWindow&#xff08;LPCTSTR IpClassName&#xff0c;LPCTSTR IpWi…

vb.net中FindWindow方法的使用

问题描述 遇到的问题是&#xff0c;需要判断MsgBox是否已经弹出&#xff0c;如果已经弹出就不要重复弹出了。 解决方案&#xff1a; 利用FindWindow方法判断MsgBox是否已经出现 MsgBox的本质就是一个窗体&#xff0c;有标题和内容&#xff0c;可以使用FindWindow这个API函数去…

C# FindWindow的用法

找了一大堆C#怎么用FindWindowAPI函数不多说,请看步骤. 创建好WinForm窗口,如果不会创建的话,在图下面有. 项目名字和位置这个自己设置,下面那个框架,目前现在出5.0了,为了演示实例,就4.6吧. 创建完成后,把自己窗口设置一下

FindWindow ,GetWindowThreadProcessId , OpenProcess 和ReadProcessMemory

文章目录 FindWindow函数功能&#xff1a;函数声明&#xff1a;第一个参数第二个参数返回值注意&#xff1a;GetWindowThreadProcessId函数功能函数声明第一个参数&#xff1a;第二个参数&#xff1a;返回值代码实现OpenProcess函数功能&#xff1a;函数声明&#xff1a;第一个…

【CV系列】主动轮廓模型snake及其应用

DATE: 2019.5.30 前言 主动轮廓模型(Active Contour Model)&#xff0c;又被称为Snake&#xff0c;是由Andrew Blake教授提出的一种目标轮廓描述方法&#xff0c;主要应用于基于形状的目标分割。该模型的优越之处在于它对于范围广泛的一系列视觉问题给出了统一的解决方法,在最…

图像分割之Snake主动轮廓模型(Matlab代码)

示例演示 如果在中文搜索的话&#xff0c;一般会找到《数字图像处理-图像分割&#xff1a;Snake主动轮廓模型 Matlab代码及运行结果》。里面有句代码&#xff0c;千万别用&#xff0c;否则出不来效果。&#xff08;别问我怎么知道的&#xff09; % 转化为双精度型 %I im2doub…

Snake活动轮廓模型Matlab实现

1. Snake模型 人为地在图像感兴趣的区域&#xff08;ROI&#xff09;上给出初始轮廓曲线&#xff0c;最小化一个能量函数&#xff0c;使轮廓曲线在图像中运动&#xff08;变形&#xff09;&#xff0c;最终逼近该区域的边界。 设v(s)[x(s),y(s)]为活动轮廓线&#xff0c;s∈[0,…

snake主动轮廓模型

模型&#xff1a;一条可变形的参数曲线及相应的能量函数&#xff0c;以最小化能量函数为目标&#xff0c;控制参数曲线变形&#xff0c;具有最小能量的闭合曲线即是目标轮廓。 snake模型调和了上层知识和底层图像特征矛盾。 上层知识指物体形状。表示内部力。 底层图像特征是局…

Snake活动轮廓模型

1. Snake模型 人为地在图像感兴趣的区域&#xff08;ROI&#xff09;上给出初始轮廓曲线&#xff0c;最小化一个能量函数&#xff0c;使轮廓曲线在图像中运动&#xff08;变形&#xff09;&#xff0c;最终逼近该区域的边界。 设v(s)[x(s),y(s)]为活动轮廓线&#xff0c;s∈[0,…