《使用OpenCV的分水岭算法》 之前利用watershed想对相对前背景较为明显的图像进行图像语义分割的预打标因为虽然前景明显但是边缘打标也是很困难的可以用该方法对大部分的边缘进行获取然后用pixel Annotation进行标注即可。 Key Words分水岭算法、OpenCV、 图像分割 Beijing, 2020 作者RaySue Code
Agile Pioneer
文章目录
- 分水岭算法原理
- OpenCV函数
- 使用流程
- 使用分水岭算法的通用步
- 分割鸡蛋为例
- 参考
分水岭算法原理
算法步骤
OpenCV函数
void watershed( InputArray image, InputOutputArray markers );
cv2.watershed(image, markers)
使用流程
使用分水岭算法的通用步
-
自动生成种子
- 输入图像 -> 灰度 -> 二值化(二值化之后注意一下前景是 255 还是 0) -> 距离变换 -> 寻找种子 -> 生成Marker -> 分水岭变换 -> 输出图像
-
手动指定已经确定的前景2和背景1作为种子
分割鸡蛋为例
- 代码
import cv2import numpy as npimport matplotlib.pyplot as pltdef watershed(image_path):image_name image_path.split("/")[-1]image cv2.imread(image_path)# image multiScaleSharpen(image, 5)# 前提降噪# blurred cv2.pyrMeanShiftFiltering(image, 25, 100)gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 第一步灰度处理# 第二步二值化处理 反色处理 255 -> 0 | 0 -> 255# ret, binary cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)ret, binary cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)# 对二值化的结果执行开运算# noise removalkernel np.ones((3, 3), np.uint8)opening cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations2)# sure background areasure_bg cv2.dilate(opening, kernel, iterations3)# Finding sure foreground areadist_transform cv2.distanceTransform(opening, cv2.DIST_L2, 5)# 通过距离变换的结果取二值化得到前景ret, sure_fg cv2.threshold(dist_transform, 0.5 * dist_transform.max(),255, 0)# Finding unknown regionsure_fg np.uint8(sure_fg)unknown cv2.subtract(sure_bg, sure_fg)# Marker labellingret, markers cv2.connectedComponents(sure_fg)# Add one to all labels so that sure background is not 0, but 1markers markers 1# Now, mark the region of unknown with zeromarkers[unknown 255] 0sure_bg[unknown 255] 0sure_bg[sure_bg 255] 2sure_bg sure_bg.astype(np.int32)# plt.figure(1)# plt.title("sure_bg")# plt.imshow(sure_bg)# 分水岭只是对0的位置进行分割 1-背景 0-待分割 2-前景result cv2.watershed(image, markersmarkers)# 分水岭结果标记轮廓为红色image[result -1] [255, 0, 0]# cv2.imwrite("./watershed_res.jpg", result)plt.figure(0)plt.subplot(231)plt.title("binary")plt.imshow(binary)plt.subplot(232)plt.title("seed new")plt.imshow(sure_bg)plt.subplot(233)plt.title("distance")plt.imshow(dist_transform * 50)plt.subplot(234)plt.title("seed ori")plt.imshow(markers)plt.subplot(235)plt.title("result markers")plt.imshow(result)plt.subplot(236)plt.title("watershed")plt.imshow(image)# plt.savefig(os.path.join(output_dir, "watershed_" image_name))plt.show()watershed("/Users/i/Desktop/Screenshot 2020-10-23_17-48-13-153.jpg")
参考
https://blog.csdn.net/HXG2006/article/details/80019736
https://blog.csdn.net/weixin_40647819/article/details/90231477