当前位置: 首页 > news >正文

计算机视觉(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()

http://www.dtcms.com/a/332658.html

相关文章:

  • vue2生命周期详解
  • Claude Opus 4.1深度解析:抢先GPT5发布,AI编程之王主动出击?
  • 【线上问题】1分钟学会如何定位 Java 应用 CPU 飙升问题
  • Spring中存在两个相同的Bean是否会报错?
  • Amazon Bedrock如何轻松实现复杂的生成式AI模型?
  • 纯C++实现halcon的threshold
  • 【Java EE进阶 --- SpringBoot】初识Spring(创建SpringBoot项目)
  • zynq代办事项
  • Vue 侦听器(watch 与 watchEffect)全解析2
  • 【100页PPT】数字化转型集团信息化总体解决方案(附下载方式)
  • Swift 实战:用最长递增子序列算法解“俄罗斯套娃信封”问题(LeetCode 354)
  • 日本服务器租用选哪个机房国内访问比较快?
  • 【LINUX网络】HTTP协议基本结构、搭建自己的HTTP简单服务器
  • 企微用户部门同步HRS系统
  • 电脑上练打字用什么软件最好:10款打字软件评测
  • 滑窗|贪心
  • Sonatype Nexus Repository Manager docker版本安装
  • [优选算法专题二滑动窗口——无重复字符的最长子串]
  • Linux应用层开发--线程
  • react性能优化之useRef和useState
  • Nginx性能优化与安全配置:打造高性能Web服务器
  • Unity:PlayerPrefs笔记
  • 标准电子邮件地址格式(RFC 5322 里的 mailbox 语法)
  • ABAP : 内表/工作区转JSON
  • Prometheus 监控 Kubernetes Cluster 最新极简教程
  • FreeRTOS多核支持
  • 从根本上解决MAC权限问题(关闭sip)
  • 汽车后雾灯色度难达标?OAS 软件精准解决破瓶颈
  • 图论Day3学习心得
  • Chrome插件开发实战:从架构到发布全流程