计算机视觉——Opencv(图像平滑处理)

什么是图像平滑处理

图像平滑处理 (Image Smoothing)是一种核心的预处理技术,也被称为图像模糊处理 ,其本质是抑制图像中的噪声、弱化高频细节(如边缘纹理的毛刺),同时保留图像整体结构与主要特征的过程。

下面是常用的一些滤波器:

1、均值滤波(Blur)

2、方框滤波(BoxFilter)

3、高斯滤波(GaussianBlur)

4、中值滤波(MedianBlur)

给图片添加椒盐噪声

准备一个含有噪声点的图像来方便后面的演示,所以我们先来学习给图片添加椒盐噪声

椒盐噪声又称脉冲噪声,是一种常见的图像噪声类型,其本质是图像像素值被随机替换为最大值(255,白色,盐噪声)或最小值(0,黑色,椒噪声)。这种噪声模拟了图像传输、采集过程中产生的信号干扰,会严重破坏图像的视觉连续性。

代码如下:

python 复制代码
import cv2
import numpy as np
def add_peppersalt_noise(image, n=10000):#n: 噪声点的数量,默认值为10000
    result = image.copy() # 复制原始图像,避免直接修改原图
    h, w = image.shape[:2]#获取图片的高和宽
    for i in range(n):#生成n个椒盐噪声
        x = np.random.randint(0, h)
        y = np.random.randint(0, w)
        if np.random.randint(0,2) == 0:
            result[x, y] = 0
        else:
            result[x,y] = 255
    return result

image = cv2.imread(r"C:\Users\LEGION\Desktop\OIP-C.webp",)
cv2.imshow('yntu',image)
cv2.waitKey(0)
noise = add_peppersalt_noise(image)
cv2.imshow('noise',noise)
cv2.waitKey(0)

运行结果:

图像平滑处理

图像平滑处理的本质是通过卷积运算,用邻域像素的统计特征(均值、中值、高斯加权值等)替换当前像素值,从而削弱噪声的影响。以下介绍四种常用的平滑算法:

1、均值滤波(Blur)

均值滤波是最基础的平滑算法,核心逻辑是用卷积核内所有像素的平均值替换中心像素值

代码如下:

python 复制代码
# 3x3卷积核均值滤波(轻度平滑)
blur_1 = cv2.blur(noise,  (3,3))
cv2.imshow( 'blur_1',blur_1)
cv2.waitKey(0)

# 63x63卷积核均值滤波(重度模糊)
blur_2 = cv2.blur(noise,(63,63))
cv2.imshow( 'blur_2',blur_2)
cv2.waitKey(0)

均值滤波能模糊噪声点,但会同时模糊图像的边缘和细节

卷积核越大,模糊效果越明显

对椒盐噪声的去除效果较差 ,因为黑白噪声点会拉高 / 拉低邻域均值,导致噪声扩散。

运行结果:

2、方框滤波(BoxFilter)

方框滤波是均值滤波的变种,通过normalize参数控制是否归一化:

  • normalize=True:等价于均值滤波;

  • normalize=False:直接求和,像素值易溢出(超过 255),表现为大面积白色。

代码如下:

python 复制代码
# 归一化方框滤波(等价于均值滤波)
boxFilter_1 = cv2.boxFilter(noise,-1, (3,3),normalize = True) 
cv2.imshow('boxFilter_1',boxFilter_1)
cv2.waitKey(0)

# 非归一化方框滤波
boxFilter_2 = cv2.boxFilter(noise,-1,(3,3),normalize = False)
cv2.imshow('boxFilter_2',boxFilter_2)
cv2.waitKey(0)

仅归一化模式有实际应用价值,非归一化模式因像素值溢出几乎无实用场景

整体效果与均值滤波一致,无法有效去除椒盐噪声。

运行结果:

3、高斯滤波(GaussianBlur)

高斯滤波是一种加权均值滤波,核心是对邻域像素按高斯分布(正态分布)赋予权重,中心像素权重最高,越远权重越低

代码如下:

python 复制代码
#3x3卷积核,标准差1的高斯滤波
GaussianB = cv2.GaussianBlur(noise,(3,3),1) #标准正太分布
cv2.imshow('GaussianBlur',GaussianB)
cv2.waitKey(0)

高斯滤波能较好保留图像边缘细节,对高斯噪声去除效果优异

对椒盐噪声的处理效果仍不理想 ,因为椒盐噪声的极值像素会影响加权均值,无法完全消除。

运行结果:

4、中值滤波(MedianBlur)

中值滤波是一种非线性滤波,核心逻辑是用卷积核内像素值的中值替换中心像素值。

由于椒盐噪声的像素值为 0 或 255(极值),在排序后会被排除在中值之外,因此对椒盐噪声有特效。

代码如下:

python 复制代码
# 3x3卷积核中值滤波
medianB = cv2.medianBlur(noise, 3)
cv2.imshow( 'medianBlur',medianB)
cv2.waitKey(0)
cv2.destroyAllWindows()

中值滤波能在去除椒盐噪声的同时,最大程度保留图像的边缘和细节,是处理椒盐噪声的最优选择。

运行结果:

5、算法效果对比与选型建议

算法类型 核心原理 椒盐噪声去除效果 细节保留效果 适用场景
均值滤波 邻域均值替换 无噪声场景的轻度模糊
方框滤波 邻域求和 / 均值替换 同均值滤波
高斯滤波 高斯加权均值替换 高斯噪声去除、图像模糊平滑
中值滤波 邻域中值替换 椒盐噪声去除(首选)

给视频添加椒盐噪声

视频本质是连续的帧序列,为保证每帧噪声分布的随机性且不破坏原视频帧,需要对噪声生成函数做优化:限制噪声点数量不超过图像总像素(避免低分辨率视频报错),并将盐、椒噪声数量均分,保证噪声分布均衡

代码如下:

python 复制代码
def add_10000_salt_pepper_noise(image):
    """
    给单帧图像添加固定10000个黑白椒盐噪声点
    :param image: 输入BGR格式单帧图像(OpenCV默认读取格式)
    :return: 添加椒盐噪声后的图像(不修改原图像)
    """
    # 复制原图像,避免破坏原帧数据,保证原视频展示纯净性
    noisy_image = np.copy(image)
    height, width = noisy_image.shape[:2]
    total_pixel_count = height * width

    # 限制噪声点数量不超过图像总像素,防止分辨率过低时报错
    noise_count = min(10000, total_pixel_count)

    # 生成盐噪声(白色点,BGR=(255,255,255)):约5000个
    salt_num = noise_count // 2
    salt_y = np.random.randint(0, height, salt_num)
    salt_x = np.random.randint(0, width, salt_num)
    noisy_image[salt_y, salt_x] = (255, 255, 255)

    # 生成椒噪声(黑色点,BGR=(0,0,0)):剩余约5000个,总计10000个
    pepper_num = noise_count - salt_num
    pepper_y = np.random.randint(0, height, pepper_num)
    pepper_x = np.random.randint(0, width, pepper_num)
    noisy_image[pepper_y, pepper_x] = (0, 0, 0)

    return noisy_image

视频的平滑处理

python 复制代码
def video_processing_pipeline(video_path=r"E:\xwechat_files\wxid_qi43v1w2nqcb12_e432\msg\file\2026-01\test.avi"):
    """
    视频处理主流程:读取帧→加噪声→去噪→多窗口展示
    """
    # 1. 打开视频文件
    video_capture = cv2.VideoCapture(video_path)
    if not video_capture.isOpened():
        raise Exception("无法打开视频文件!请确认test.avi存在于当前目录,且格式有效。")

    # 2. 循环处理每一帧视频
    while True:
        # 读取单帧图像
        ret, original_frame = video_capture.read()

        # 读取失败(视频结束或帧损坏),退出循环
        if not ret:
            break

        # 3. 给当前帧添加10000个椒盐噪声点
        noisy_frame = add_10000_salt_pepper_noise(original_frame)

        # 4. 选择最优平滑方法:中值滤波(针对椒盐噪声,兼顾去噪与清晰度)
        # 5x5滤波核为去噪效果与画面细节的最优平衡
        smoothed_frame = cv2.medianBlur(noisy_frame, ksize=5)

        # 5. 创建并配置三个可调整大小的展示窗口
        cv2.namedWindow("原视频", cv2.WINDOW_NORMAL)
        cv2.namedWindow("含10000个椒盐噪声的视频", cv2.WINDOW_NORMAL)
        cv2.namedWindow("平滑处理后视频", cv2.WINDOW_NORMAL)

        # 6. 同步展示三类视频帧
        cv2.imshow("原视频", original_frame)
        cv2.imshow("含10000个椒盐噪声的视频", noisy_frame)
        cv2.imshow("平滑处理后视频", smoothed_frame)

        # 7. 按键控制:按'q'键退出播放,每帧延迟30ms适配常规视频帧率
        if cv2.waitKey(30) & 0xFF == ord('q'):
            break

    # 8. 释放所有资源,避免内存泄露
    video_capture.release()
    cv2.destroyAllWindows()


# 主程序入口
if __name__ == "__main__":
    video_processing_pipeline()

运行结果:

从左到右依次为原视频,添加噪声的视频,平滑处理后的视频

相关推荐
wanghao6664552 小时前
AI向量:让计算机真正理解人类语言
人工智能
2501_945292172 小时前
AI 证书考试形式是怎样的,机考还是笔试,有没有实操题?
人工智能
星河天欲瞩2 小时前
【深度学习Day4】线性代数基础
人工智能·深度学习·学习·线性代数
Java程序员威哥2 小时前
使用Java自动加载OpenCV来调用YOLO模型检测
java·开发语言·人工智能·python·opencv·yolo·c#
说私域2 小时前
AI智能客服S2B2C商城小程序在客户服务场景中的应用与价值——以顾客反馈处理为例
人工智能·小程序·流量运营·私域运营
无忧智库2 小时前
智慧高速公路运行监测与主动管控云平台:从“传统基建”到“新基建”的全面跃迁(WORD)
大数据·人工智能
KmBase2 小时前
【AI】从Prompt到Skill:AI 如何从玩具进化为工具
大数据·人工智能·prompt