【OpenCV 入门到精通 07】滤波、阈值与形态学:图像去噪与形状处理
标签 :
OpenCV图像滤波阈值形态学腐蚀膨胀难度 :⭐⭐ | 阅读时长 :约 65 分钟 | 系列 :第 07/12 集

写在前面
照片有噪点?想提取白色文字?需要连接断裂的线条?本集三个武器帮你解决:滤波 (去噪平滑)、阈值 (二值化分割)、形态学 (形状变换)。对应官方 4_3~4_5。
本集学习目标
- 掌握均值/高斯/中值/双边滤波
- 使用全局和自适应阈值二值化
- 理解腐蚀、膨胀、开运算、闭运算
- 完成文字提取综合实战
目录
- [7.1 图像平滑滤波](#7.1 图像平滑滤波)
- [7.2 图像阈值](#7.2 图像阈值)
- [7.3 形态学操作](#7.3 形态学操作)
- [7.4 综合实战:文字提取](#7.4 综合实战:文字提取)
- [7.5 踩坑指南](#7.5 踩坑指南)
- [7.6 本集小结](#7.6 本集小结)
7.1 图像平滑滤波
为什么需要滤波?
- 去除噪声(椒盐噪点、高斯噪声)
- 模糊图像(减少细节)
- 平滑后再做边缘检测效果更好
四种常用滤波
python
import cv2
img = cv2.imread("noisy.jpg")
# 1. 均值滤波
blur = cv2.blur(img, (5, 5))
# 2. 高斯滤波(最常用)
gaussian = cv2.GaussianBlur(img, (5, 5), 0)
# 3. 中值滤波(去椒盐噪声最佳)
median = cv2.medianBlur(img, 5)
# 4. 双边滤波(保边去噪)
bilateral = cv2.bilateralFilter(img, 9, 75, 75)
| 滤波器 | 特点 | 适用 |
|---|---|---|
| 均值 blur | 简单快速 | 一般平滑 |
| 高斯 GaussianBlur | 加权平均 | 通用去噪 |
| 中值 medianBlur | 取中值 | 椒盐噪声 |
| 双边 bilateralFilter | 保边 | 美颜、细节保留 |
核大小
(5,5)必须为奇数。
7.2 图像阈值
将灰度图转为黑白二值图。
简单阈值
python
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
| 类型 | 效果 |
|---|---|
THRESH_BINARY |
>阈值→255,否则→0 |
THRESH_BINARY_INV |
反转 |
THRESH_TRUNC |
>阈值→阈值,否则不变 |
THRESH_TOZERO |
>阈值→原值,否则→0 |
THRESH_OTSU |
自动计算最佳阈值 |
python
# Otsu 自动阈值
_, otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
自适应阈值
光照不均匀时用:
python
adaptive = cv2.adaptiveThreshold(
gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
blockSize=11, # 邻域大小(奇数)
C=2 # 常数偏移
)
| 方法 | 说明 |
|---|---|
| 全局阈值 | 整图一个阈值,简单 |
| Otsu | 自动选阈值,光照均匀时好 |
| 自适应 | 局部阈值,光照不均 |
7.3 形态学操作
基于 结构元素(kernel)的形状操作,作用于二值图。
腐蚀与膨胀
python
import numpy as np
kernel = np.ones((5, 5), np.uint8)
# 腐蚀:缩小白色区域,去噪点
eroded = cv2.erode(binary, kernel, iterations=1)
# 膨胀:扩大白色区域,填充孔洞
dilated = cv2.dilate(binary, kernel, iterations=1)
腐蚀:●●● → ●● (白色缩小)
●●● ●
●●●
膨胀:●● → ●●● (白色扩大)
● ●●●
●●●
开运算与闭运算
python
# 开运算 = 先腐蚀后膨胀 → 去小噪点
opening = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
# 闭运算 = 先膨胀后腐蚀 → 填小孔洞
closing = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
# 梯度 = 膨胀 - 腐蚀 → 轮廓
gradient = cv2.morphologyEx(binary, cv2.MORPH_GRADIENT, kernel)
| 运算 | 公式 | 效果 |
|---|---|---|
| 开 MORPH_OPEN | 腐蚀→膨胀 | 去小白点 |
| 闭 MORPH_CLOSE | 膨胀→腐蚀 | 填小黑洞 |
| 梯度 MORPH_GRADIENT | 膨胀-腐蚀 | 提取边缘 |
| 顶帽 MORPH_TOPHAT | 原图-开运算 | 亮细节 |
| 黑帽 MORPH_BLACKHAT | 闭运算-原图 | 暗细节 |
7.4 综合实战:文字提取
python
import cv2
import numpy as np
img = cv2.imread("document.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 1. 高斯去噪
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 2. 自适应二值化
binary = cv2.adaptiveThreshold(blurred, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
# 3. 形态学:闭运算连接文字笔画
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
closed = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
cv2.imshow("Result", closed)
cv2.waitKey(0)
7.5 踩坑指南
| 坑 | 解决 |
|---|---|
| 滤波核为偶数 | 必须奇数 |
| 阈值全黑/全白 | 调阈值或用 Otsu/自适应 |
| 形态学过度 | 减小 kernel 或 iterations |
| 双边滤波太慢 | 减小 d 参数 |
7.6 本集小结
| 主题 | 核心 |
|---|---|
| 去噪 | GaussianBlur / medianBlur / bilateralFilter |
| 二值化 | threshold / adaptiveThreshold / Otsu |
| 形态学 | erode / dilate / morphologyEx |
| ← 第06集 | 第08集:边缘与轮廓 → |
|---|