人工智能之视觉领域 计算机视觉
第七章 图像形态学操作
文章目录
- [人工智能之视觉领域 计算机视觉](#人工智能之视觉领域 计算机视觉)
- 前言:图像形态学操作(形状调整)
- [1. 通俗理解:什么是形态学操作?](#1. 通俗理解:什么是形态学操作?)
- [2. 核心概念:结构元素(Kernel)](#2. 核心概念:结构元素(Kernel))
- [3. 两大基础操作](#3. 两大基础操作)
- [3.1 腐蚀(Erosion)------"变瘦"](#3.1 腐蚀(Erosion)——“变瘦”)
- [🔧 函数:`cv2.erode(src, kernel, iterations=1)`](#🔧 函数:
cv2.erode(src, kernel, iterations=1))- [3.2 膨胀(Dilation)------"变胖"](#3.2 膨胀(Dilation)——“变胖”)
- [🔧 函数:`cv2.dilate(src, kernel, iterations=1)`](#🔧 函数:
cv2.dilate(src, kernel, iterations=1))- [🖼️ 直观对比(文字说明):](#🖼️ 直观对比(文字说明):)
- [4. 组合操作:开运算 & 闭运算](#4. 组合操作:开运算 & 闭运算)
- [4.1 开运算(Opening) = 先腐蚀 + 后膨胀](#4.1 开运算(Opening) = 先腐蚀 + 后膨胀)
- [4.2 闭运算(Closing) = 先膨胀 + 后腐蚀](#4.2 闭运算(Closing) = 先膨胀 + 后腐蚀)
- [5. 形态学操作流程图(Mermaid)](#5. 形态学操作流程图(Mermaid))
- [6. 完整代码实战:文档图像优化](#6. 完整代码实战:文档图像优化)
- [7. 高级应用:提取水平/垂直线(表格识别)](#7. 高级应用:提取水平/垂直线(表格识别))
- [8. 补充:其他形态学操作](#8. 补充:其他形态学操作)
- [9. 常见误区提醒](#9. 常见误区提醒)
- [✅ 本章总结](#✅ 本章总结)
- 资料关注
前言:图像形态学操作(形状调整)
学习目标:理解"腐蚀"与"膨胀"的几何意义,掌握基本形态学操作(腐蚀、膨胀、开运算、闭运算),能对二值图像进行轮廓优化、去噪、连接断裂等处理。
1. 通俗理解:什么是形态学操作?
想象你有一张黑白打印的文档扫描图:
- 文字边缘有小白点(噪声)
- 字母"o"中间有个小黑点(孔洞)
- 有些笔画断开了
✅ 形态学操作 = 对图像中"前景"(白色)的形状进行数学调整
它不改变颜色,只改变结构------就像用橡皮泥捏形状!
核心思想:用一个结构元素(Kernel) 在图像上滑动,根据邻域像素决定中心像素的命运。
2. 核心概念:结构元素(Kernel)
结构元素是一个小矩阵(通常是正方形或圆形),定义了"邻域范围"和"形状"。
python
import cv2
import numpy as np
# 常见结构元素
kernel_3x3 = np.ones((3, 3), np.uint8) # 3×3 正方形
kernel_5x5 = np.ones((5, 5), np.uint8) # 5×5 正方形
kernel_circle = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) # 圆形
📌 核越大,操作越强 ;形状影响结果方向性(如十字形适合线状结构)
3. 两大基础操作
3.1 腐蚀(Erosion)------"变瘦"
原理 :只有当结构元素完全覆盖在前景(白色)上时,中心点才保留为白色,否则变黑。
👉 效果:
- 前景区域缩小
- 消除小的白色噪点
- 分离粘连物体
🔧 函数:cv2.erode(src, kernel, iterations=1)
python
eroded = cv2.erode(binary_img, kernel, iterations=1)
iterations:重复操作次数(1次通常足够)
3.2 膨胀(Dilation)------"变胖"
原理 :只要结构元素与前景有任何重叠,中心点就变为白色。
👉 效果:
- 前景区域扩大
- 填充小的黑色孔洞
- 连接断裂的轮廓
🔧 函数:cv2.dilate(src, kernel, iterations=1)
python
dilated = cv2.dilate(binary_img, kernel, iterations=1)
🖼️ 直观对比(文字说明):
| 原始二值图 | 腐蚀后 | 膨胀后 |
|---|---|---|
| 白色字母 "A" | 字母变细,可能断开 | 字母变粗,孔洞被填 |
4. 组合操作:开运算 & 闭运算
单独使用腐蚀/膨胀可能带来副作用,因此常组合使用:
4.1 开运算(Opening) = 先腐蚀 + 后膨胀
作用:
- 去除小的白色噪点
- 平滑轮廓外边界
- 不改变大物体尺寸
✅ 适用于:清除前景中的"毛刺"或孤立点
python
opening = cv2.morphologyEx(binary_img, cv2.MORPH_OPEN, kernel)
4.2 闭运算(Closing) = 先膨胀 + 后腐蚀
作用:
- 填充小的黑色孔洞
- 连接邻近的前景区域
- 不改变大物体尺寸
✅ 适用于:补全文字断裂、填充内部空洞
python
closing = cv2.morphologyEx(binary_img, cv2.MORPH_CLOSE, kernel)
5. 形态学操作流程图(Mermaid)
去除白噪点
填充黑孔洞
分离粘连物体
连接断裂轮廓
输入二值图像
目标是什么?
开运算: erode → dilate
闭运算: dilate → erode
腐蚀 erode
膨胀 dilate
输出优化图像
6. 完整代码实战:文档图像优化
python
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 1. 读取并二值化图像(模拟带噪文档)
img = cv2.imread('document_noisy.jpg', cv2.IMREAD_GRAYSCALE)
if img is None:
# 若无图,创建模拟图像
img = np.ones((300, 500), dtype=np.uint8) * 255
# 添加文字(白色背景+黑色文字 → 需反转)
cv2.putText(img, 'OpenCV', (50, 150), cv2.FONT_HERSHEY_SIMPLEX, 3, 0, 5)
# 添加椒盐噪声
noise = np.random.randint(0, 2, img.shape[:2]) * 255
img = np.where(noise == 255, 0, img) # 加黑点(前景噪点)
# 2. 二值化(假设文字是黑色,背景白色 → 反转)
_, binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
# 3. 定义结构元素(5x5 圆形)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
# 4. 应用形态学操作
eroded = cv2.erode(binary, kernel, iterations=1)
dilated = cv2.dilate(binary, kernel, iterations=1)
opening = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
# 5. 显示结果(使用 matplotlib)
images = [img, binary, eroded, dilated, opening, closing]
titles = ['Original', 'Binary (Inverted)', 'Eroded', 'Dilated', 'Opening', 'Closing']
plt.figure(figsize=(15, 10))
for i in range(len(images)):
plt.subplot(2, 3, i+1)
plt.imshow(images[i], cmap='gray')
plt.title(titles[i])
plt.axis('off')
plt.tight_layout()
plt.show()
# 6. 保存关键结果
cv2.imwrite('morph_opening_result.jpg', opening)
cv2.imwrite('morph_closing_result.jpg', closing)
✅ 预期效果:
- 开运算:清除了文字周围的黑点(前景噪点)
- 闭运算:填补了字母"O"内部的小白点(背景孔洞)
7. 高级应用:提取水平/垂直线(表格识别)
利用非对称结构元素可提取特定方向线条:
python
# 提取水平线
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (40, 1))
horizontal_lines = cv2.morphologyEx(binary, cv2.MORPH_OPEN, horizontal_kernel)
# 提取垂直线
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 40))
vertical_lines = cv2.morphologyEx(binary, cv2.MORPH_OPEN, vertical_kernel)
📊 应用:表格检测、文档版面分析
8. 补充:其他形态学操作
| 操作 | 函数 | 用途 |
|---|---|---|
| 形态学梯度 | MORPH_GRADIENT |
膨胀 - 腐蚀 → 获取轮廓边框 |
| 顶帽(Top Hat) | MORPH_TOPHAT |
原图 - 开运算 → 提取亮细节 |
| 黑帽(Black Hat) | MORPH_BLACKHAT |
闭运算 - 原图 → 提取暗细节 |
python
gradient = cv2.morphologyEx(binary, cv2.MORPH_GRADIENT, kernel)
9. 常见误区提醒
| 误区 | 正确认知 |
|---|---|
| "形态学只能用于二值图" | 理论上可用于灰度图,但实践中几乎只用于二值图 |
| "核越大越好" | 过大会导致文字变形、细节丢失 |
| "开运算能去所有噪点" | 仅对小于核的前景噪点有效 |
| "腐蚀后一定变小" | 如果前景是细线,可能直接消失! |
✅ 本章总结
| 操作 | 顺序 | 主要作用 | 典型应用 |
|---|---|---|---|
| 腐蚀 | --- | 缩小前景、去白点 | 分离粘连、去噪 |
| 膨胀 | --- | 扩大前景、填黑洞 | 连接断裂、补洞 |
| 开运算 | 腐蚀 → 膨胀 | 去除小前景噪点 | 清理文字毛刺 |
| 闭运算 | 膨胀 → 腐蚀 | 填充小背景孔洞 | 补全字符、连接笔画 |
🌟 现在可以:
- 把一张带噪点的扫描件变得干净整洁
- 让断裂的验证码文字重新连起来
- 为后续的"轮廓查找"提供高质量二值图!
资料关注
咚咚王
《Python编程:从入门到实践》
《利用Python进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第3版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow机器学习实战指南》
《Sklearn与TensorFlow机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第2版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨+&+张孜铭
《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战AI大模型》
《AI 3.0》