Opencv 学习笔记:腐蚀操作 + 轮廓标记 + 分水岭分割

腐蚀是形态学操作的核心,常与轮廓分析、分水岭算法结合实现图像分割。本文整合「腐蚀去噪→轮廓标记→分水岭分割」全流程,演示从预处理到最终分割的完整逻辑,新手可直接复用。

核心代码实现

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()

关键知识点解析

1. 核心流程拆解

步骤 核心 API 作用说明
腐蚀操作 cv.erode() 用 9×9 矩形核腐蚀图像,消除小噪点,让前景轮廓更清晰
轮廓检测 cv.findContours() 提取腐蚀后图像的轮廓,为分水岭提供前景标记
轮廓标记 cv.drawContours() 为每个轮廓分配唯一数值标记(i+5),生成分水岭标记图
分水岭分割 cv.watershed() 基于标记图分割图像,result7 == -1为分割边界

2. 核心参数与避坑点

  • 腐蚀核参数 :cv.getStructuringElement(cv.MORPH_RECT, (9,9)):矩形核尺寸越大,腐蚀效果越强,需根据图像噪点大小调整(小噪点用 3×3,大噪点用 9×9);
  • 轮廓标记值:标记值从 5 开始(而非 0/1),避免与分水岭算法的「背景(0)」「未知区域(1)」冲突,是分割成功的关键;
  • 数据类型要求 :
    • 轮廓检测输入必须为uint8类型,因此需result6 = np.uint8(result5);
    • 分水岭标记图必须为float32类型,因此初始化result7时指定np.float32;
  • 分割边界标注 :watershed执行后,标记图中值为-1的像素是分割边界,用红色标注可直观验证分割效果。

3. 形态学操作扩展

操作 API 作用
膨胀 cv.dilate() 与腐蚀相反,扩大前景区域,修复轮廓断裂
开运算 cv.morphologyEx(src, cv.MORPH_OPEN, kernel) 先腐蚀后膨胀,去除小噪点且不改变前景大小
闭运算 cv.morphologyEx(src, cv.MORPH_CLOSE, kernel) 先膨胀后腐蚀,填充前景孔洞

总结

  1. 腐蚀操作是分水岭分割的关键预处理,核心作用是去除小噪点、强化前景轮廓,核尺寸需适配噪点大小;
  2. 分水岭算法的核心是「标记图」:轮廓标记值需避开 0/1,避免与背景 / 未知区域冲突;
  3. 数据类型严格匹配(轮廓检测→uint8,分水岭标记图→float32)是流程运行的基础。
相关推荐
代码山河2 小时前
Python就业方向全解析:后端、爬虫、数据分析、AI你选哪个?
python·学习·架构·教程·面向对象·项目
sbjdhjd2 小时前
网工进阶笔记:H3CSE 园区网全栈技术与协议汇总
网络·笔记·云计算·ssh·网络工程·vlan·aaa
释厄6233 小时前
AI学习层更新与跨体转移律——人类社会同构·不缺理解缺 U
人工智能·学习
海绵宝宝的月光宝盒6 小时前
14-AutoCAD-阵列命令应用与案例实战(AR)
经验分享·笔记·自动化·课程设计·制造·学习方法·cad
小嘉丶学长7 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
白山编程大哥7 小时前
接口幂等性是什么?如何设计?
笔记
ACP广源盛139246256737 小时前
6 盘位存储扩展方案选型笔记:YLB3116 @ACP评估记录
笔记·硬件架构·硬件工程·国产芯片
小李不想当小白7 小时前
SPI通信外设与W25Q64 (硬件SPI)(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
weixin_4481199410 小时前
Datawhale Jev Cookbook 202610 笔记3
笔记
姚瑞南10 小时前
【PRD】招投标商机雷达爬虫系统
人工智能·经验分享·笔记·爬虫·产品运营·产品经理