在计算机视觉领域,噪声处理是图像和视频预处理的重要环节。椒盐噪声(Pepper and Salt Noise)是一种常见的图像噪声,表现为图像中随机出现的黑色(椒)和白色(盐)像素点。本文将基于 Python 和 OpenCV 库,实现为视频逐帧添加椒盐噪声,并使用中值滤波算法去除噪声的完整流程。
一、核心原理介绍
1.1 椒盐噪声
椒盐噪声属于脉冲噪声,其生成逻辑是:在图像的随机位置上,将像素值强制设置为 0(黑色,椒噪声)或 255(白色,盐噪声)。噪声数量越多,图像失真越严重,本次案例中默认生成 10000 个噪声点。
1.2 中值滤波
中值滤波是处理椒盐噪声的经典算法,核心原理是:用像素点邻域内的中值 替代该像素点的原始值。由于椒盐噪声的像素值为 0 或 255(极值),在邻域中值计算时会被排除,因此能有效去除椒盐噪声,同时保留图像的边缘信息。OpenCV 中medianBlur函数默认使用奇数尺寸的核(如 3×3)进行滤波。
二、完整代码实现与解析
2.1 椒盐噪声生成函数
python
import cv2
import numpy as np
def add_peppersalt_noise(image, n=10000):
"""
为图像添加椒盐噪声
:param image: 输入图像(OpenCV读取的BGR格式)
:param n: 噪声点数量,默认10000个
:return: 添加噪声后的图像
"""
# 复制原图像,避免修改原始数据
result = image.copy()
# 获取图像的高(h)和宽(w)
h, w = image.shape[:2]
# 生成n个噪声点
for i in range(n):
# 随机生成噪声点的坐标(x为行,y为列)
x = np.random.randint(0, h)
y = np.random.randint(0, w)
# 随机决定是椒噪声(0)还是盐噪声(255)
if np.random.randint(0, 2) == 0:
result[x, y] = 0 # 椒噪声(黑色)
else:
result[x, y] = 255 # 盐噪声(白色)
return result
-
image.copy():必须复制原图像,否则会直接修改原始帧数据 -
np.random.randint(0, h):生成 0 到 h-1 的随机整数,确保坐标在图像范围内 -
随机选择 0/1 决定噪声类型,保证椒盐噪声随机分布。
2.2 视频处理主逻辑
python
# 打开视频文件(替换为你的视频路径,或用0调用摄像头)
video_capture = cv2.VideoCapture("test.avi")
# 检查视频是否成功打开
if not video_capture.isOpened():
print("无法打开视频文件/摄像头")
exit()
# 循环读取视频帧
while True:
# 逐帧读取:ret为布尔值(是否读取成功),frame为当前帧图像
ret, frame = video_capture.read()
# 若读取失败(如视频结束),退出循环
if not ret:
break
# 1. 显示原始帧
cv2.imshow('Original Video', frame)
# 2. 为当前帧添加椒盐噪声
noise_frame = add_peppersalt_noise(frame)
cv2.imshow('Video with Peppersalt Noise', noise_frame)
# 3. 中值滤波去噪(核大小为3×3,需为奇数)
denoised_frame = cv2.medianBlur(noise_frame, 3)
cv2.imshow('Denoised Video (Median Blur)', denoised_frame)
# 按下ESC键(ASCII码27)退出循环
if cv2.waitKey(20) == 27:
break
# 释放视频捕获资源
video_capture.release()
# 关闭所有OpenCV窗口
cv2.destroyAllWindows()
-
cv2.VideoCapture:参数为视频路径时读取本地视频,为 0 时调用电脑摄像头 -
cv2.waitKey(20):控制视频播放帧率(20ms / 帧),同时监听键盘输入 -
cv2.medianBlur(noise_frame, 3):3 为滤波核大小,核越大去噪效果越强,但图像会越模糊,可根据需求调整为 5、7 等奇数。