提供企业网站建设,我想做app推广代理,教学单位 网站建设,租车网站建设原理 任何一副灰度图像都可以被看成拓扑平面#xff0c;灰度值高的区域可以被看成是山峰#xff0c;灰度值低的区域可以被看成是山谷。我们向每一个山谷中灌不同颜色的水。随着水的位的升高#xff0c;不同山谷的水就会相遇汇合#xff0c;为了防止不同山谷的水汇合#x…原理 任何一副灰度图像都可以被看成拓扑平面灰度值高的区域可以被看成是山峰灰度值低的区域可以被看成是山谷。我们向每一个山谷中灌不同颜色的水。随着水的位的升高不同山谷的水就会相遇汇合为了防止不同山谷的水汇合我们需要在水汇合的地方构建起堤坝。不停的灌水不停的构建堤坝知道所有的山峰都被水淹没。我们构建好的堤坝就是对图像的分割。这就是分水岭算法的背后哲理。 分水岭算法是一种图像分割算法常用于分割具有重叠目标的图像。它基于数学形态学的理念将图像看作地形图水流在图像的低谷目标边界聚集形成分割线。OpenCV 提供了 cv2.watershed() 函数来执行分水岭算法。
基本的语法如下
cv2.watershed(image, markers)参数说明
image: 输入的图像通常是一个三通道彩色图像。markers: 标记图像用于指定分水岭算法的初始标记。标记图像应该是单通道灰度图像其中不同的标记值表示不同的区域。
cv2.watershed 函数会修改输入图像将标记图像中的区域分割开并用不同的颜色标记不同的分割区域。分水岭算法通常用于从预先标记的图像中分割出目标区域。
以下是一个简单的示例演示如何使用分水岭算法进行图像分割
import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图像
img cv2.imread(rC:\Users\mzd\Desktop\opencv\4.jpg)
img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 转换为灰度图像
gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 使用阈值分割获取前景区域掩码
_, thresh cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)
#cv2.threshold 是 OpenCV 中用于图像阈值化的函数。阈值化是一种将图像分割成两个区域的方法通常用于目标检测、边缘检测等应用。
# 对前景区域进行形态学操作消除小的噪点
kernel np.ones((3, 3), np.uint8)
#np.ones 是 NumPy 中的一个函数用于创建一个指定形状shape的数组并将数组的所有元素初始化为 1
opening cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations2)# 通过距离变换获取图像的距离变换结果
dist_transform cv2.distanceTransform(opening, cv2.DIST_L2, 5)
_, sure_fg cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)# 获取背景区域掩码
sure_bg cv2.dilate(opening, kernel, iterations3)# 标记不确定的区域
sure_fg np.uint8(sure_fg)
unknown cv2.subtract(sure_bg, sure_fg)# 使用连通组件标记不确定区域
_, markers cv2.connectedComponents(sure_fg)# 将标记1作为不确定区域的标记以避免与已知区域的标记冲突
markers markers 1
markers[unknown 255] 0 # 不确定区域的标记设为0# 应用分水岭算法
cv2.watershed(img, markers)# 将分水岭算法的标记区域设为红色
img[markers -1] [255, 0, 0]# 显示原始图像、阈值分割结果和分水岭算法结果
plt.figure(figsize(12, 6))plt.subplot(131), plt.imshow(img_rgb)
plt.title(Original Image), plt.axis(off)plt.subplot(132), plt.imshow(thresh, cmapgray)
plt.title(Thresholded Image), plt.axis(off)plt.subplot(133), plt.imshow(img)
plt.title(Watershed Result), plt.axis(off)plt.show()在这个示例中我们首先读取了一幅图像将其转换为灰度图像。然后使用阈值分割获取前景区域的掩码并通过形态学操作和距离变换对图像进行预处理。接着通过分水岭算法将图像分割为不同的区域并在结果图像上标记分割线。最后通过 Matplotlib 显示原始图像、阈值分割结果和分水岭算法的分割结果。