分水岭算法-python-opencv

article/2025/10/16 3:15:22

分水岭算法简单原理:

对于一个图像的灰度值,将图像放平,可以看成是类似与山谷与山顶的图像,灰度值小的就是山底。先找到若干个山底,同时加水,当加到一定程度时候,某些山顶会被淹没,此时在山顶修建大坝,避免两处水汇集在一起。此时这个大坝就是分水岭,即边缘。

原图像:

二值化:

 利用OTSU方法首先进行二值化操作:

详情请看:图像阈值处理-OpenCV_独憩的博客-CSDN博客

import cv2.cv2
import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg = cv.imread(r'XXXXX\water_coins.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV+cv.THRESH_OTSU)

形态学得到边界区域:

对于分水岭算法,我们首先要得到边界可能存在的区域,你们对于上述图像来说,我们要得到的图像为”圆环“

开始直接我们采用开运算去除噪声;

故我们先需要得到一些确定的”背景“,和一些确定的”内部“,利用两者相减得到边界可能存在的区域,即圆环;

确定的”背景“可以使原二值图像”膨胀“得到,确定的”内部“可以使原二值图像”腐蚀“得到,具体原理见:图像膨胀、腐蚀、开运算、闭运算---python.opencv_独憩的博客-CSDN博客

kernel = np.ones((3,3),np.uint8)
#去除噪声
opening = cv.morphologyEx(thresh,cv.MORPH_OPEN,kernel, iterations = 3)
#膨胀得到背景
sure_bg = cv.dilate(opening,kernel,iterations=3)
#腐蚀得到前景
sure_fg = cv2.erode(opening, kernel, iterations=3)
sure_fg = np.uint8(sure_fg)
#两者相减得到边缘可能存在区域
unknown = cv.subtract(sure_bg,sure_fg)plt.figure()
plt.subplot(1,3,1)
plt.imshow(sure_bg,'gray')
plt.title('sure background area')
plt.xticks([]),plt.yticks([])
plt.subplot(1,3,2)
plt.imshow(sure_fg,'gray')
plt.title('sure foreground area')
plt.xticks([]),plt.yticks([])
plt.subplot(1,3,3)
plt.imshow(unknown,'gray')
plt.title('unknown')
plt.xticks([]),plt.yticks([])
plt.show()


但是从图像看出,unknown图像中由于硬币重叠,有部分边界被抵消,故我们采用另外一种方法:

首先介绍一个函数:

dist_transform = cv.distanceTransform(opening,cv.DIST_L2,5)

我们只需要知道,这个函数的作用是得到图像(灰度)中所有非零像素与最近的零像素的距离

 我们可以通过对dist_transform图像进行阈值处理得到确定的”内部“,这样的好处是可以控制圆环的粗细,阈值处理 cv.threshold具体见:图像阈值处理-OpenCV_独憩的博客-CSDN博客

kernel = np.ones((3,3),np.uint8)
opening = cv.morphologyEx(thresh,cv.MORPH_OPEN,kernel, iterations = 3)sure_bg = cv.dilate(opening,kernel,iterations=3)dist_transform = cv.distanceTransform(opening,cv.DIST_L2,5)
ret, sure_fg = cv.threshold(dist_transform,0.5*dist_transform.max(),255,0)
sure_fg = np.uint8(sure_fg)
unknown = cv.subtract(sure_bg,sure_fg)plt.figure()
plt.subplot(1,3,1)
plt.imshow(sure_bg,'gray')
plt.title('sure background area')
plt.xticks([]),plt.yticks([])
plt.subplot(1,3,2)
plt.imshow(sure_fg,'gray')
plt.title('sure foreground area')
plt.xticks([]),plt.yticks([])
plt.subplot(1,3,3)
plt.imshow(unknown,'gray')
plt.title('unknown')
plt.xticks([]),plt.yticks([])
plt.show()

背景,前景,边界区域分类:

 然后我们需要对背景,前景(内部),边界区域进行分类:

ret, markers = cv2.connectedComponents(sure_fg)markers = markers+1 #使得背景为1markers[unknown==255] = 0  #使得边界区域为0
markers_copy = markers.copy()markers_copy[markers==0] = 150  # 灰色表示背景
markers_copy[markers==1] = 0    # 黑色表示背景
markers_copy[markers>1] = 255   # 白色表示前景markers_copy = np.uint8(markers_copy)
plt.figure()
plt.imshow(markers_copy,'gray')
plt.title('markers')
plt.xticks([]),plt.yticks([])
plt.show()

 cv2.watershed():

最后直接调用分水岭算法函数:

markers = cv2.watershed(img, markers)
img=cv.cvtColor(img,cv.COLOR_BGR2RGB)
img[markers==-1] = [255,0,0]
plt.figure()
plt.imshow(img,'gray')plt.xticks([]),plt.yticks([])
plt.show()

 


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

相关文章

分水岭算法解析[halcon]

分水岭算法 分水岭算法是根据分水岭的构成来考虑图像的分割, 它是—种基于拓扑理论的数学形态学的分割方法。 首先, 把一幅图像看作起伏的地形, 图像的每像素灰度值作为这个地形的高度, 极小值是盆地, 极大值为山脊。…

opencv-分水岭算法图像分割

分水岭算法图像分割 目标   本节我们将要学习   • 使用分水岭算法基于掩模的图像分割   • 函数:cv2.watershed()    原理   任何一副灰度图像都可以被看成拓扑平面,灰度值高的区域可以被看成是山峰,灰度值低的区域可以被看成是山…

分水岭算法的python实现及解析

1 算法简介 分水岭算法的原理很容易查到,但是很多文章都是直接用的opencv或matlab函数,看不到具体实现方法,这篇文章希望能对大家有点帮助。 分水岭算法就是往山谷中注水,把不同湖水接触的位置称作分水岭,这么做的结…

opencv28:分水岭算法的图像分割

目标 在本章中,将学习 使用分水岭算法实现基于标记的图像分割函数:cv2.watershed() 理论 任何灰度图像都可以看作是一个地形表面,其中高强度的像素表示山峰,低强度表示山谷。可以用不同颜色的水(标签)填充每个孤立的山谷(局部…

OpenCV-分水岭算法

文章目录 分水岭算法cv2.watershed示例 分水岭算法 任何灰度图像都可以看作是一个地形表面,其中高强度表示山峰,低强度表示山谷。你开始用不同颜色的水(标签)填充每个孤立的山谷(局部最小值)。随着水位的上升,根据附近的山峰(坡度)&#xff…

【OpenCV】- 分水岭算法

文章目录 什么是图像分割分水岭算法1、实现分水岭算法:watershed()函数2、处理流程(视频)3、示例程序(书中) 什么是图像分割 将图像中像素根据一定的规则分为若干个cluster集合,每个集合包含一类对象 如下…

OpenCV分水岭算法详解

原理分析 分水岭算法主要用于图像分段,通常是把一副彩色图像灰度化,然后再求梯度图,最后在梯度图的基础上进行分水岭算法,求得分段图像的边缘线。 下面左边的灰度图,可以描述为右边的地形图,地形的高度是由…

分水岭算法 matlab实现

背景 做图像分割的时候用到了,就学习了一下 大概思想 把图像中的像素大小理解成山地的海拔,向山地灌水,海拔低的地方会积水,这些地方称之为谷底。随着水位上升,不同谷底的水会相遇,相遇的地方就是分水岭。…

分水岭算法c语言,Opencv分水岭算法学习

分水岭算法可以将图像中的边缘转化成“山脉”,将均匀区域转化为“山谷”,这样有助于分割目标。 分水岭算法是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中的每一点像素的灰度值表示…

分水岭算法

引言:它是基于拓扑理论的形态学处理方法。将一张图像假想成为一张地貌特征图。 原理理解:灰度图被看作拓扑平面,灰度高看成山峰,灰度低看成山谷。从山谷开始注水,随着水位升高水流会相遇汇合。为了防止汇合&#xff0…

Opencv分水岭算法——watershed自动图像分割用法

分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特征。 其他图像分割方法,如阈值,边缘检测等都不会考虑像素在…

目标分割算法之分水岭算法

分水岭算法 1.经典算法原理及实现 传统的目标分割算法主要分为两种 1.基于像素相似性:阈值分割、k-means分割 2.基于像素邻域关系:区域生长、分水岭、基于标记分水岭 分水岭算法原理 如图中展现了凹凸不平的地貌,视觉上明显的位置有盆地及…

分水岭算法的理解和应用

分水岭算法 主要思想 图像的灰度空间很像地球表面的整个地理结构,每个像素的灰度值代表高度。分水岭就是灰度值较大的像素连成的线。二值化阈值可以理解为水平面,比灰度二值化阈值小的像素区域会被淹没。随着水位线的升高,被淹没的区域越来越…

分水岭算法及其实现

1 - 算法描述 1.1 分水岭算法的原理   分水岭的概念是以三维方式来形象化一幅图像为基础的:两个空间坐标再加上强度。在这种“地形学”解释中,考虑三种类型的点:(a)局部最小值点,该点对应一个…

传统图像分割——分水岭算法(watershed)

传统图像分割——分水岭算法(watershed) 文章目录 传统图像分割——分水岭算法(watershed)前言一、什么是分水岭算法?二、经典的分水岭求解算法1.定义2.算法流程 总结 前言 本篇文章主要梳理分水岭算法的原理&#xf…

图像分割 - 分水岭算法

目录 1. 介绍 2. 分水岭算法的实现 距离变换 连接连通分量 3. 代码 1. 介绍 图像是由x,y表示的,如果将灰度值也考虑进去的话,那么一幅图像需要一个三维的空间去表示。 这样就可以把x,y轴比作大地,将灰度值的z轴…

【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…