机器视觉opencv教程(三):形态学变换(腐蚀与膨胀)

发布于:2025-09-03 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、形态学变换总览

  • 定义:一种基于图像形状的简单变换,核心是通过「核」与原始图像的交互,调整二值化图像的像素分布。
  • 处理对象:主要是 二值化图像(像素值仅为 0 黑色 / 255 白色)。
  • 核心组成:
    1. 原始二值化图像:待处理的图像。
    2. 核(结构化元素):用于滑动计算的模板,决定变换的范围和形状(常见形状:矩形、十字形、椭圆形)。
  • 基础逻辑:核在图像上从左到右、从上到下滑动,通过特定计算规则(取最小 / 最大值)更新核覆盖区域的中心像素值

二、基本操作:腐蚀与膨胀

形态学变换的两个核心基础操作,二者效果完全相反,是后续组合操作的基础。

在这里插入图片描述

2.1 腐蚀操作(Erosion)

1. 核心原理

核在二值化图像上滑动,对核值为 1 的区域与被覆盖的图像区域进行「相乘」,取计算结果的最小值作为中心像素的新值。

  • 二值图特殊规则:若核覆盖区域内存在黑色像素(0),则中心像素必为黑色(0)
  • 仅当所有覆盖像素均为白色(255)时,中心像素才为白色。
2. 效果

将二值化图像中的白色区域「变瘦」,可削弱细小白色结构、分离邻近的白色区域。

import cv2

# 步骤1:读取彩色图像
image_np = cv2.imread('./test.png')  

# 步骤2:彩色图 → 灰度图(二值化的前提)
image_gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)

# 步骤3:灰度图 → 二值化图(阈值127:>127设为255白,≤127设为0黑)
ret, image_thresh = cv2.threshold(image_gray, 127, 255, cv2.THRESH_BINARY)

# 步骤4:构建核(结构化元素)
# 参数1:核形状(MORPH_CROSS=十字形,MORPH_RECT=矩形,MORPH_ELLIPSE=椭圆形)
# 参数2:核大小((9,9)表示9x9,尺寸越大,腐蚀效果越强)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (9, 9))

# 步骤5:执行腐蚀操作
image_erode = cv2.erode(image_thresh, kernel)  # 输入:二值图+核

# 步骤6:显示结果(按任意键关闭窗口)
cv2.imshow('原始二值图', image_thresh)
cv2.imshow('腐蚀后图像(变瘦)', image_erode)
cv2.waitKey(0)  # 等待按键输入
cv2.destroyAllWindows()  # 关闭所有窗口

2.2 膨胀操作(Dilation)

1. 核心原理

与腐蚀完全相反:核在二值化图像上滑动,对核值为 1 的区域与被覆盖的图像区域进行「相乘」,取计算结果的最大值作为中心像素的新值。

  • 二值图特殊规则:若核覆盖区域内存在白色像素(255),则中心像素必为白色(255);
  • 仅当所有覆盖像素均为黑色(0)时,中心像素才为黑色。
2. 效果

将二值化图像中的白色区域「变胖」,可增强细小白色结构、连接邻近的白色区域。

import cv2

# 步骤1-3:与腐蚀操作一致(读取→灰度化→二值化)
image_np = cv2.imread('./test.png')  
image_gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)
ret, image_thresh = cv2.threshold(image_gray, 127, 255, cv2.THRESH_BINARY)

# 步骤4:构建核(此处用矩形核,与腐蚀的十字形区分)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))  # 7x7核,膨胀强度适中

# 步骤5:执行膨胀操作
image_dilate = cv2.dilate(image_thresh, kernel)

# 步骤6:显示结果
cv2.imshow('原始二值图', image_thresh)
cv2.imshow('膨胀后图像(变胖)', image_dilate)
cv2.waitKey(0)
cv2.destroyAllWindows()

2.3 腐蚀 vs 膨胀 对比表

维度 腐蚀操作(Erosion) 膨胀操作(Dilation)
计算逻辑 核覆盖区域取「最小值」 核覆盖区域取「最大值」
二值图规则 有黑色(0)则中心为黑 有白色(255)则中心为白
白色区域效果 「变瘦」(收缩) 「变胖」(扩张)
核心作用 削弱细小白色结构、分离邻近区域 增强细小白色结构、连接邻近区域

三、组合操作:开运算与闭运算

基于「腐蚀」和「膨胀」的顺序组合,解决更复杂的图像问题(如去噪、填洞)。

3.1 开运算(Opening)

1. 操作顺序

先腐蚀 → 再膨胀(先收缩再扩张)。

2. 核心原理
  • 第一步腐蚀去除图像中的细小白色噪点(小白色区域被腐蚀掉),但会让主要白色物体变瘦。
  • 第二步膨胀:将主要白色物体恢复到接近原始大小,同时保留 “去噪” 的效果。
3. 作用
  • 去除图像中的白色小噪点(不影响主要白色物体的形状和大小)。
  • 分离邻近的白色物体(避免粘连)。
import cv2

# 步骤1-3:读取→灰度化→二值化
img = cv2.imread("img.png")  # 替换为自己的图像路径
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# 步骤4:构建核(5x5矩形核,通用尺寸)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

# 步骤5:执行开运算(用morphologyEx函数,指定操作类型为MORPH_OPEN)
opening = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)

# 步骤6:显示结果
cv2.imshow("原始二值图", binary)
cv2.imshow("开运算结果(去白色噪点)", opening)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.2 闭运算(Closing)

1. 操作顺序

先膨胀 → 再腐蚀(先扩张再收缩)。

2. 核心原理
  • 第一步膨胀填充主要白色物体内部的细小黑色空洞(空洞被白色填充),但会让主要白色物体变胖。
  • 第二步腐蚀:将主要白色物体恢复到接近原始大小,同时保留 “填洞” 的效果。
3. 作用
  • 填充主要白色物体内部的黑色小空洞(不影响物体整体形状)。
  • 连接邻近的白色物体(修复微小断裂)。
import cv2

# 步骤1-4:与开运算一致(读取→灰度化→二值化→构建核)
img = cv2.imread("img.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

# 步骤5:执行闭运算(操作类型为MORPH_CLOSE)
closing = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)

# 步骤6:显示结果
cv2.imshow("原始二值图", binary)
cv2.imshow("闭运算结果(填黑色空洞)", closing)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.3 开运算 vs 闭运算 对比表

维度 开运算(Opening) 闭运算(Closing)
操作顺序 腐蚀 → 膨胀 膨胀 → 腐蚀
核心作用 去除白色小噪点、分离邻近物体 填充黑色小空洞、连接邻近物体
适用场景 图像含细小白色杂点时 图像含细小黑色空洞时
对主要物体影响 形状 / 大小基本不变 形状 / 大小基本不变

四、关键总结

  1. 核心逻辑:形态学变换基于「核滑动」和「极值计算」(最小 / 最大),仅作用于二值化图像。
  2. 操作选择:
    • 想让白色区域变瘦 → 腐蚀;想变胖 → 膨胀。
    • 去除白色小噪点运算;想填充黑色小空洞 → 运算。
  3. 核的影响:核的尺寸越大,变换效果越强;核的形状(矩形 / 十字形 / 椭圆形)影响变换的方向性(如十字形对线性结构更敏感)。

网站公告

今日签到

点亮在社区的每一天
去签到