核心概念梳理
1. 低通滤波的核心作用
低通滤波允许图像中低频信息(大面积、平缓的像素变化,如主体轮廓)通过,抑制高频信息(小范围、剧烈的像素变化,如噪声、细节),最终实现:
- 平滑图像、去除噪声;
- 不可避免造成图像模糊,但核心特征(如轮廓)会保留;
- 本质是卷积操作(中值/双边滤波为非线性,除外)。
2. 卷积基础
卷积是“局部扫描+区域感知”的核心操作,步骤:
- 卷积核(Kernel):正方形矩阵(通常为奇数,如3×3、5×5),是滤波的“权重模板”;
- 步长(Stride, s):卷积核在原图上滑动的像素步距,默认s=1,s=2时图像尺寸会减半;
- 填充(Padding, p):当卷积核滑到图像边缘时,若像素不足则补0(或补边),避免输出图像尺寸缩小;
- 计算规则:卷积核覆盖的像素区域,与核内权重做点积求和(线性滤波),逐行逐列滑动。
3. 输出图像尺寸计算公式
输入图像尺寸:H×W(高×宽),卷积核尺寸:k×k,步长s,填充p,则输出尺寸:
输出高 H' = ((H - k) + 2×p) // s + 1 输出宽 W' = ((W - k) + 2×p) // s + 1示例:输入640×480,核5×5,步长1,填充2(补0)→ 输出仍为640×480(无尺寸损失);步长2→输出320×240。
4. 卷积核尺寸的参数规则
| 滤波类型 | ksize参数形式 | 原因 |
|---|---|---|
| 均值/高斯/方框 | 元组(如(5,3)) | 支持非正方形核(如5行3列),需明确高×宽 |
| 中值滤波 | 单个整数(如5) | 仅支持正方形核,简化参数避免冗余 |
六大低通滤波
前置准备:环境与基础代码
import cv2 import numpy as np import matplotlib.pyplot as plt # 读取图像(工程上优先处理灰度图) img = cv2.imread("test.jpg") # 彩色图:BGR格式 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转灰度图(核心处理对象) # 图像显示辅助函数 def show_imgs(imgs, titles, rows=1, cols=2): plt.figure(figsize=(12, 6)) for i in range(len(imgs)): plt.subplot(rows, cols, i+1) plt.imshow(imgs[i], cmap="gray" if len(imgs[i].shape)==2 else None) plt.title(titles[i]) plt.axis("off") plt.show()1. 均值滤波
原理
线性滤波,卷积核内所有像素取算术平均值作为输出像素值,核内权重均等。
特点
- 去噪效果一般,模糊程度较明显;
- 适合去除均匀分布的弱噪声。
代码
# 均值滤波:ksize=(5,5)(5×5核),步长默认1,填充默认适配核尺寸 blur_gray = cv2.blur(gray, ksize=(5,5)) show_imgs([gray, blur_gray], ["原图(灰度)", "均值滤波(5×5)"])2. 方框滤波
原理
均值滤波的“变种”,可选择是否对核内像素归一化(除以核面积):
- 归一化(默认):等价于均值滤波;
- 不归一化:像素值易溢出(超过255),仅特殊场景使用。
代码
# 归一化方框滤波(等价均值滤波) box_norm = cv2.boxFilter(gray, -1, (5,5), normalize=True) # 不归一化方框滤波(演示用,实际少用) box_unnorm = cv2.boxFilter(gray, -1, (5,5), normalize=False) show_imgs([gray, box_norm, box_unnorm//10], ["原图", "归一化方框滤波", "不归一化(缩放后)"])3. 高斯滤波
原理
线性滤波,卷积核权重符合高斯分布(中心像素权重最高,向边缘递减),更贴合人眼视觉特性。
特点
- 去噪效果优于均值滤波,模糊程度更柔和;
- 工程上最常用,常循环多次增强效果;
- 需要指定
sigmaX(X方向标准差),sigmaY默认等于sigmaX(越大,滤波越平滑)。
代码(工程常用:循环高斯滤波)
# 单次高斯滤波:(5,5)核,sigmaX=1.5 gauss1 = cv2.GaussianBlur(gray, (5,5), sigmaX=1.5) # 循环3次高斯滤波(工程常用,比单次大核更自然) gauss3 = gray.copy() for _ in range(3): gauss3 = cv2.GaussianBlur(gauss3, (5,5), sigmaX=1.5) show_imgs([gray, gauss1, gauss3], ["原图", "单次高斯滤波", "3次循环高斯滤波"])4. 中值滤波
原理
非线性滤波,取卷积核内所有像素的中值作为输出像素值,对“孤立噪声”(如椒盐噪声)效果极佳。
特点
- 核尺寸为单个整数(仅支持正方形);
- 去椒盐噪声远优于线性滤波,且边缘保留更好;
- 适合:相机噪点、图像传输中的椒盐噪声场景。
代码
# 模拟添加椒盐噪声 np.random.seed(0) noise = np.random.choice([0, 255], size=gray.shape, p=[0.98, 0.02]) gray_noise = np.where(noise==255, 255, gray) # 加盐噪声 # 中值滤波去椒盐噪声 median = cv2.medianBlur(gray_noise, 5) # ksize=5(5×5核) show_imgs([gray, gray_noise, median], ["原图", "加椒盐噪声", "中值滤波(5×5)"])5. 双边滤波
原理
非线性滤波,兼顾空间距离和像素值相似度:
- 空间距离:近的像素权重高(类似高斯);
- 像素值相似度:与中心像素值接近的权重高;
特点 - 唯一能“去噪+保边缘”的低通滤波;
- 参数较多:
d(核直径)、sigmaColor(色彩标准差,越大,允许越宽的像素值范围)、sigmaSpace(空间标准差); - 缺点:计算量较大,实时性要求高的场景慎用。
代码
# 双边滤波:d=9(核直径),sigmaColor=75,sigmaSpace=75 bilateral = cv2.bilateralFilter(gray, d=9, sigmaColor=75, sigmaSpace=75) # 对比:高斯滤波(边缘模糊)vs 双边滤波(边缘保留) gauss = cv2.GaussianBlur(gray, (9,9), sigmaX=5) show_imgs([gray, gauss, bilateral], ["原图", "高斯滤波(边缘模糊)", "双边滤波(保边缘)"])工程实践核心要点
1. 图像格式选择
优先处理灰度图:
- 彩色图可先转灰度(
cv2.COLOR_BGR2GRAY),减少计算量; - 若需保留色彩,可分B/G/R通道分别滤波后合并。
2. 滤波选型规则
| 场景 | 首选滤波 | 补充说明 |
|---|---|---|
| 普通随机噪声 | 高斯滤波(循环) | 核5×5,循环2-3次 |
| 椒盐噪声/孤立亮点 | 中值滤波 | 核3×3/5×5,根据噪声大小调整 |
| 需保留边缘的去噪 | 双边滤波 | 牺牲速度换效果 |
| 快速简单去噪(无要求) | 均值滤波 | 仅临时测试/低要求场景 |
3. 调参技巧
- 核尺寸:从3×3开始,逐步增大(越大越模糊,但去噪越强);
- 高斯滤波:
sigmaX建议1.0~3.0(过大会丢失关键细节); - 循环滤波:优先“小核+多次循环”,而非“大核+单次”(模糊更自然)。
4. 避坑点
- 中值滤波核尺寸过大(如9×9)会导致图像“卡通化”,丢失细节;
- 高斯滤波
sigmaX=0时,OpenCV会自动按核尺寸计算(不推荐,显式指定更可控); - 方框滤波不归一化时,需手动缩放像素值(避免溢出为255)。
总结
低通滤波的核心是“trade-off(取舍)”:去噪越强,模糊越明显。工程上需结合业务场景(如监控图像去噪、证件照磨皮、工业检测去噪)选择滤波类型,优先用高斯/中值滤波,配合灰度图+小核循环的方式,既能保证效果,又能控制计算成本。