腐蚀是形态学操作的核心,常与轮廓分析、分水岭算法结合实现图像分割。本文整合「腐蚀去噪→轮廓标记→分水岭分割」全流程,演示从预处理到最终分割的完整逻辑,新手可直接复用。
python
复制代码
import cv2 as cv
import numpy as np
# 1. 读取图像并初始化(补充完整流程)
src = cv.imread('./image/test.bmp') # 替换为你的图像路径
if src is None:
print('图像读取失败,请检查路径!')
exit()
srcss = src.copy() # 分水岭分割画布
result4 = src.copy() # 腐蚀输入图像(需为单通道二值图,此处补充预处理)
# 预处理:转为灰度图→二值化(腐蚀操作的前提)
gray = cv.cvtColor(result4, cv.COLOR_BGR2GRAY)
ret, result4 = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)
# 2. 腐蚀操作(核心:去除小噪点,强化前景轮廓)
# 创建结构化元素:9×9矩形核(尺寸越大,腐蚀越强)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (9, 9))
result5 = cv.erode(result4, kernel) # 执行腐蚀
# 3. 轮廓检测(基于腐蚀后的图像)
result6 = np.uint8(result5) # 确保为uint8格式(轮廓检测要求)
contours, hierarchy = cv.findContours(result6, cv.RETR_CCOMP, cv.CHAIN_APPROX_SIMPLE)
# 4. 轮廓标记(为分水岭算法生成标记图)
# 初始化标记图:float32类型,尺寸与原图一致
result7 = np.zeros((src.shape[0], src.shape[1]), np.float32)
# 遍历轮廓,为每个轮廓分配唯一标记值(从5开始,避免与背景冲突)
for i, contour in enumerate(contours):
cv.drawContours(result7, contours, i, i+5, 1) # 标记值=i+5,线宽1
# 5. 执行分水岭分割
cv.watershed(srcss, result7)
# 标注分割边界(标记值为-1的区域是分割线)
srcss[result7 == -1] = [0, 0, 255] # 分割线标红
# 6. 显示结果
cv.namedWindow('腐蚀结果', cv.WINDOW_NORMAL)
cv.resizeWindow('腐蚀结果', 600, 600)
cv.imshow('腐蚀结果', result5)
cv.namedWindow('轮廓标记图', cv.WINDOW_NORMAL)
cv.resizeWindow('轮廓标记图', 600, 600)
cv.imshow('轮廓标记图', result7 / result7.max() * 255) # 归一化显示
cv.namedWindow('分水岭分割结果', cv.WINDOW_NORMAL)
cv.resizeWindow('分水岭分割结果', 600, 600)
cv.imshow('分水岭分割结果', srcss)
cv.waitKeyEx(0)
cv.destroyAllWindows()