计算机视觉(opencv)实战五——图像平滑处理(均值滤波、方框滤波、高斯滤波、中值滤波)附加:视频逐帧平滑处理
图像/视频平滑处理
图像平滑(smoothing)也称为“模糊处理”(blurring),是图像处理中常用的一种技术。通过消除图像中的噪声或细节,使图像看起来更加平滑、柔和,从而弱化或消除图像中的突变、噪点和细微纹理。
图像平滑在实际应用中非常重要,例如去噪、降低图像细节对后续处理(如边缘检测、分割)的影响,以及改善视觉效果等。
常用的滤波方法
均值滤波(Average/Blur)
均值滤波通过取邻域像素的平均值来替代中心像素值,从而达到平滑效果。
dst = cv2.blur(src, ksize)
示例代码:
blur_1 = cv2.blur(noise, (3, 3)) # 小卷积核 blur_2 = cv2.blur(noise, (63, 63)) # 大卷积核
dst
:处理后的图像src
:原始图像ksize
:卷积核大小,例如(3, 3)
anchor
:锚点,默认(-1, -1)
,一般无需修改borderType
:边界处理方式,默认即可
方框滤波(Box Filter)
方框滤波类似均值滤波,但提供是否归一化的选项。
dst = cv2.boxFilter(src, ddepth, ksize, normalize=True)
示例代码:
boxFilter_1 = cv2.boxFilter(noise, -1, (3, 3), normalize=True) boxFilter_2 = cv2.boxFilter(noise, -1, (3, 3), normalize=False)
ddepth
:输出图像深度,通常使用-1
表示与原图相同normalize
:是否对邻域像素求平均True
→ 归一化,相当于均值滤波False
→ 不归一化,直接求和
高斯滤波(Gaussian Blur)
高斯滤波使用高斯函数对邻域像素加权平均,更加注重中心像素,能更自然地平滑图像。
GaussianB = cv2.GaussianBlur(src, ksize=(3,3), sigmaX=1)
示例代码:
GaussianB = cv2.GaussianBlur(noise, (3,3), sigmaX=1)
ksize
:滤波器大小sigmaX
/sigmaY
:X/Y方向的标准差dst
:输出图像,可省略
中值滤波(Median Blur)
中值滤波用邻域像素的中位数替代中心像素,特别适合去除椒盐噪声。
medianB = cv2.medianBlur(src, ksize=3)
示例代码:
medianB = cv2.medianBlur(noise, 3)
ksize
必须为奇数对椒盐噪声去除效果明显
案例演示:去除椒盐噪声
1️⃣ 导入库
import cv2
import numpy as np
cv2
:OpenCV库,用于图像读取、显示和处理。numpy
:用于数组和矩阵操作,这里用来生成噪声坐标。
2️⃣ 定义椒盐噪声函数
def add_peppersalt_noise(image, n=10000):result = image.copy()h, w = image.shape[:2] # 获取图片的高和宽for i in range(n): # 生成n个椒盐噪声x = np.random.randint(low=1, high=h)y = np.random.randint(low=1, high=w)if np.random.randint(low=0, high=2) == 0:result[x, y] = 0 # 黑色噪声(椒)else:result[x, y] = 255 # 白色噪声(盐)return result
image.copy()
:复制原图,避免修改原图。h, w = image.shape[:2]
:获取图像高度和宽度,用于随机生成噪声位置。循环
n
次随机生成椒盐噪声像素:np.random.randint(1, h)
随机生成行坐标np.random.randint(1, w)
随机生成列坐标随机选择 0(黑)或 255(白)作为噪声值
作用:生成带有椒盐噪声的图像,用于测试滤波器的去噪能力。
3️⃣ 读取图像
image = cv2.imread('tiger.jpg')
cv2.imshow('yuntu', image)
cv2.waitKey(0)
cv2.imread()
:读取图像,返回 NumPy 数组(BGR格式)。cv2.imshow()
:显示图像窗口cv2.waitKey(0)
:等待按键,按任意键关闭窗口
4️⃣ 添加椒盐噪声
noise = add_peppersalt_noise(image)
cv2.imshow('noise', noise)
cv2.waitKey(0)
调用
add_peppersalt_noise
,生成带噪声的图像显示带噪声的图像,可以看到随机分布的黑白点
5️⃣ 均值滤波(Average Blur)
blur_1 = cv2.blur(noise, (3, 3))
cv2.imshow('blur_(3, 3)', blur_1)
cv2.waitKey(0)blur_2 = cv2.blur(noise, (63, 63))
cv2.imshow('blur_(63, 63)', blur_2)
cv2.waitKey(0)
cv2.blur()
:对图像进行均值滤波(3, 3)
vs(63, 63)
:小卷积核 (3x3):轻微平滑,噪声略有消除
大卷积核 (63x63):强烈平滑,细节和噪声都模糊
作用:消除噪声,但大核可能导致图像模糊严重。
6️⃣ 方框滤波(Box Filter)
boxFilter_1 = cv2.boxFilter(noise, -1, ksize=(3, 3), normalize=True)
cv2.imshow('boxFilter_1', boxFilter_1)
cv2.waitKey(0)boxFilter_2 = cv2.boxFilter(noise, -1, ksize=(3, 3), normalize=False)
cv2.imshow('boxFilter_2', boxFilter_2)
cv2.waitKey(0)
cv2.boxFilter()
类似均值滤波,但可选择是否归一化:normalize=True
→ 等价于均值滤波normalize=False
→ 直接求和,可能产生像素溢出(大于255时截断)
ddepth=-1
表示输出图像与原图同样深度
作用:提供更灵活的滤波控制,既可平滑,也可测试非归一化效果。
7️⃣ 高斯滤波(Gaussian Blur)
GaussianB = cv2.GaussianBlur(noise, ksize=(3,3), sigmaX=1)
cv2.imshow('GaussianBlur', GaussianB)
cv2.waitKey(0)
高斯滤波器对邻域像素加权,中心像素权重更高
ksize=(3,3)
:滤波器大小sigmaX=1
:标准差,控制模糊程度对椒盐噪声和细节平滑效果更自然
8️⃣ 中值滤波(Median Blur)
medianB = cv2.medianBlur(noise, ksize=3)
cv2.imshow('medianBlur', medianB)
cv2.waitKey(0)
cv2.destroyAllWindows()
中值滤波取邻域像素中位数替换中心像素
特别适合去除椒盐噪声
ksize
必须为奇数,越大去噪效果越强,但可能损失细节
🔹 总结
均值滤波 / 方框滤波:简单、快速,但对椒盐噪声不够鲁棒
高斯滤波:平滑自然,对高斯噪声更有效
中值滤波:对椒盐噪声最有效,保留边缘效果更好
通过调整滤波器类型和卷积核大小,可以实现不同程度的图像平滑和去噪效果。
扩展案例:视频逐帧平滑处理
# 视频格式不是一定要是avi格式,可以是mp4等等
import cv2
import numpy as npdef add_peppersalt_noise(image, n=10000):result = image.copy()h, w = image.shape[:2] for i in range(n): x = np.random.randint(low=1, high=h)y = np.random.randint(low=1, high=w)if np.random.randint(low=0, high=2) == 0:result[x, y] = 0else:result[x, y] = 255return resultvideo = cv2.VideoCapture('test.avi') while True: # 每一帧ret, frame = video.read()if not ret: # 判断是否读取到帧breakcv2.imshow('video', frame)noise = add_peppersalt_noise(frame) # 添加椒盐噪声cv2.imshow('noise', noise)medianB = cv2.medianBlur(noise, ksize=3) # 中值滤波cv2.imshow('medianBlur', medianB)if cv2.waitKey(1) == 27: # 1表示每一帧的间隔,27表示按键‘Esc’breakvideo.release()
cv2.destroyAllWindows()