[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)

该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。希望文章对您有所帮助,如果有不足之处,还请海涵~

前面一篇文章介绍了图像分割知识,包括阈值分割、边缘分割、纹理分割、分水岭算法、K-Means分割、漫水填充分割、区域定位等。这篇文章将详细讲解图像平滑知识,包括均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波。万字长文整理,希望对您有所帮助。 同时,该部分知识均为作者查阅资料撰写总结,并且开设成了收费专栏,为小宝赚点奶粉钱,感谢您的抬爱。当然如果您是在读学生或经济拮据,可以私聊我给你每篇文章开白名单,或者转发原文给你,更希望您能进步,一起加油喔~

代码下载地址(如果喜欢记得star,一定喔):

  • https://github.com/eastmountyxz/ImageProcessing-Python

文章目录

  • 一.图像平滑概述
    • 1.图像平滑
    • 2.线性滤波和非线性滤波
    • 3.常见滤波器
  • 二.均值滤波
    • 1.算法原理
    • 2.代码实现
  • 三.方框滤波
  • 四.高斯滤波
  • 五.中值滤波
  • 六.双边滤波
  • 七.总结

前文参考:

  • [Python图像处理] 一.图像处理基础知识及OpenCV入门函数
  • [Python图像处理] 二.OpenCV+Numpy库读取与修改像素
  • [Python图像处理] 三.获取图像属性、兴趣ROI区域及通道处理
  • [Python图像处理] 四.图像平滑之均值滤波、方框滤波、高斯滤波及中值滤波
  • [Python图像处理] 五.图像融合、加法运算及图像类型转换
  • [Python图像处理] 六.图像缩放、图像旋转、图像翻转与图像平移
  • [Python图像处理] 七.图像阈值化处理及算法对比
  • [Python图像处理] 八.图像腐蚀与图像膨胀
  • [Python图像处理] 九.形态学之图像开运算、闭运算、梯度运算
  • [Python图像处理] 十.形态学之图像顶帽运算和黑帽运算
  • [Python图像处理] 十一.灰度直方图概念及OpenCV绘制直方图
  • [Python图像处理] 十二.图像几何变换之图像仿射变换、图像透视变换和图像校正
  • [Python图像处理] 十三.基于灰度三维图的图像顶帽运算和黑帽运算
  • [Python图像处理] 十四.基于OpenCV和像素处理的图像灰度化处理
  • [Python图像处理] 十五.图像的灰度线性变换
  • [Python图像处理] 十六.图像的灰度非线性变换之对数变换、伽马变换
  • [Python图像处理] 十七.图像锐化与边缘检测之Roberts算子、Prewitt算子、Sobel算子和Laplacian算子
  • [Python图像处理] 十八.图像锐化与边缘检测之Scharr算子、Canny算子和LOG算子
  • [Python图像处理] 十九.图像分割之基于K-Means聚类的区域分割
  • [Python图像处理] 二十.图像量化处理和采样处理及局部马赛克特效
  • [Python图像处理] 二十一.图像金字塔之图像向下取样和向上取样
  • [Python图像处理] 二十二.Python图像傅里叶变换原理及实现
  • [Python图像处理] 二十三.傅里叶变换之高通滤波和低通滤波
  • [Python图像处理] 二十四.图像特效处理之毛玻璃、浮雕和油漆特效
  • [Python图像处理] 二十五.图像特效处理之素描、怀旧、光照、流年以及滤镜特效
  • [Python图像处理] 二十六.图像分类原理及基于KNN、朴素贝叶斯算法的图像分类案例
  • [Python图像处理] 二十七.OpenGL入门及绘制基本图形(一)
  • [Python图像处理] 二十八.OpenCV快速实现人脸检测及视频中的人脸
  • [Python图像处理] 二十九.MoviePy视频编辑库实现抖音短视频剪切合并操作
  • [Python图像处理] 三十.图像量化及采样处理万字详细总结(推荐)
  • [Python图像处理] 三十一.图像点运算处理两万字详细总结(灰度化处理、阈值化处理)
  • [Python图像处理] 三十二.傅里叶变换(图像去噪)与霍夫变换(特征识别)万字详细总结
  • [Python图像处理] 三十三.图像各种特效处理及原理万字详解(毛玻璃、浮雕、素描、怀旧、流年、滤镜等)
  • [Python图像处理] 三十四.数字图像处理基础与几何图形绘制万字详解(推荐)
  • [Python图像处理] 三十五.OpenCV图像处理入门、算数逻辑运算与图像融合(推荐)
  • [Python图像处理] 三十六.OpenCV图像几何变换万字详解(平移缩放旋转、镜像仿射透视)
  • [Python图像处理] 三十七.OpenCV和Matplotlib绘制直方图万字详解(掩膜直方图、H-S直方图、黑夜白天判断)
  • [Python图像处理] 三十八.OpenCV图像增强万字详解(直方图均衡化、局部直方图均衡化、自动色彩均衡化)
  • [Python图像处理] 三十九.Python图像分类万字详解(贝叶斯图像分类、KNN图像分类、DNN图像分类)
  • [Python图像处理] 四十.全网首发Python图像分割万字详解(阈值分割、边缘分割、纹理分割、分水岭算法、K-Means分割、漫水填充分割、区域定位)
  • [Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)

在图像产生、传输和应用过程中,通常会由于一些原因导致图像数据丢失或被噪声干扰的现象,从而降低了图像的质量。这就需要通过图像平滑方法来消除这些噪声并保留图像的边缘轮廓和线条清晰度,本文将详细介绍五种图像平滑的滤波算法,包括均值滤波、方框滤波、高斯滤波、中值滤波和双边滤波。

一.图像平滑概述

1.图像平滑

一幅图像可能存在着各种寄生效应,这些寄生效应可能在传输中产生,也可能在图像处理过程中产生。一个较好的平滑方法是既能消掉这些寄生效应又不使图像的边缘轮廓和线条变模糊,这就是研究图像平滑处理要追求的主要目标。

图像平滑(smoothing)是一项简单且使用频率很高的图像处理方法,可以用来压制、弱化或消除图像中的细节、突变、边缘和噪声,最常见的是用来减少图像上的噪声。

何为图像噪声?噪声是妨碍人的感觉器官所接受信源信息理解的因素,是不可预测只能用概率统计方法认识的随机误差。从图1中,可以观察到噪声的特点:位置随机、大小不规则,将这种噪声称为随机噪声,这是一种常见的噪声类型。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第1张图片

图2是一个图像平滑的示例,图中左半部分是包含噪声的原始输入图像,右半部分是进行图像平滑后的图像。通过对比容易观察到,在平滑后的图像中,物体中的噪声得到了有效地抑制和消除,但花的边缘部分被进行了模糊,这种将图像中的冗余信息进行抑制,即花的噪声进行消除的过程被称为图像平滑。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第2张图片


2.线性滤波和非线性滤波

一幅图像不可避免地要受到各种噪声源的干扰,所以噪声滤除往往是图像处理中的第一步,滤波效果好坏将直接影响后续处理结果,噪声滤除在图像处理中占有相当重要的地位。噪声滤除算法多种多样,可以从设计方法上分为两大类:

  • 线性滤波算法
  • 非线性滤波算法

在图像处理中,对邻域中的像素的计算为线性运算时,如利用窗口函数进行平滑加权求和的运算,或者某种卷积运算,都可以称为线性滤波。在数字信号处理和数字图像处理的早期研究中,线性滤波器是噪声抑制处理的主要手段,如:

  • 均值滤波
  • 方框滤波
  • 高斯滤波

线性滤波算法对高斯型噪声有较好的滤波效果,而当信号频谱与噪声频谱混叠时或者当信号中含有非叠加性噪声时(例如由系统非线性引起的噪声或存在非高斯噪声等),线性滤波器的处理结果就很难令人满意。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第3张图片

非线性滤波利用原始图像跟模版之间的一种逻辑关系得到结果,如:

  • 中值滤波
  • 双边滤波

非线性滤波技术从某种程度上弥补了线性滤波方法的不足,由于它能够在滤除噪声的同时较好地保持图像信号的高频细节,从而得到广泛的应用。著名学者 Tukey于 1971 年首次提出了一种非线性滤波器——中值滤波器,从此揭开了非线性滤波方法研究的序幕。非线性滤波技术发展到现在,基于中值滤波的改进算法层出不穷,在非线性滤波算法中占有重要的地位。

另外很多新的非线性滤波算法也相继涌现,如基于数学形态学的滤波方法、基于模糊理论的滤波方法、基于神经网络的滤波方法和基于小波分析的滤波方法等等,这些都为图像滤波技术的发展提供了新的思路。


3.常见滤波器

后文将详细介绍以下常用的一些滤波器,包括均值滤波、方框滤波、高斯吕波、中值滤波等,如表1所示。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第4张图片

图3为这五种滤波的效果对比,从滤波的结果可以看出各种滤波算法对图像的作用非常不同,有些变化非常大,有些甚至跟原图一样。在实际应用时,应根据噪声的特点、期望的图像和边缘特征等来选择合适的滤波器,这样才能发挥图像滤波的最大优点。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第5张图片

在图像产生、传输和复制过程中,常常会因为多方面原因而被噪声干扰或出现数据丢失,降低了图像的质量。这就需要对图像进行一定的增强处理以减小这些缺陷带来的影响。


二.均值滤波

1.算法原理

均值滤波是最简单的一种线性滤波算法,它是指在原始图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标像素为中心的周围8个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的平均值来代替原来的像素值。换句话说,均值滤波输出图像的每一个像素值是其周围M×M个像素值的加权平均值

图4表示均值滤波处理的过程,中心红色点的像素值为蓝色背景区域像素值求和的均值。5×5的矩阵称之为模糊内核,针对原始图像内的像素点,均值滤波采用核对其像素逐个进行均值处理,并得到最终的效果图。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第6张图片

其中红色区域的像素值均值滤波处理过程为:

在这里插入图片描述

算法特点:

  • 均值滤波算法比较简单,计算速度较快,对周期性的干扰噪声有很好的抑制作用,但是它不能很好地保护图像的细节,在图像去噪的同时,也破坏了图像的细节部分,从而使图像变得模糊。

2.代码实现

Python调用OpenCV中的cv2.blur()函数实现均值滤波处理,其函数原型如下所示,输出的dst图像与输入图像src具有相同的大小和类型。

  • dst = blur(src, ksize[, dst[, anchor[, borderType]]])
    – src表示输入图像,它可以有任意数量的通道,但深度应为CV_8U、CV_16U、CV_16S、CV_32F或CV_64F
    – ksize表示模糊内核大小,以(宽度,高度)的形式呈现
    – anchor表示锚点,即被平滑的那个点,其默认值Point(-1,-1)表示位于内核的中央,可省略
    – borderType表示边框模式,用于推断图像外部像素的某种边界模式,默认值为BORDER_DEFAULT,可省略

常见的模糊内核包括(3,3)和(5,5),如公式所示:

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第7张图片

图像均值滤波的Python实现代码如下所示,需要注意的是,代码中使用的是3×3的模板,plt.rcParams是用于设置中文汉字正常显示。

# -*- coding: utf-8 -*-
# By:Eastmount CSDN 2021-06-07
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('lena.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#均值滤波
result = cv2.blur(source, (10,10))

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', '均值滤波']  
images = [source, result]  
for i in range(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

“lena”图输出结果如图5所示,左边表示含有噪声的待处理原图,右边是均值滤波处理后的图像,图像中的椒盐噪声被去除了。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第8张图片

如果图像中的噪声仍然存在,可以增加模糊内核的大小,比如使用5×5、10×10,甚至20×20的模板。图6就是使用10×10的内核,但是处理后的图像会逐渐变得更模糊。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第9张图片

图像均值滤波是通过模糊内核对图像进行平滑处理,由于模糊内核中的每个权重值都相同,故称为均值。该方法在一定程度上消除了原始图像中的噪声,降低了原始图像的对比度,但也存在一定缺陷,它在降低噪声的同时使图像变得模糊,尤其是边缘和细节处,而且模糊内核越大,模糊程度越严重。


三.方框滤波

图像平滑利用卷积模板逐一处理图像中每个像素,这一过程可以形象地比作对原始图像的像素进行过滤整理,把邻域像素逐一处理的算法过程称为滤波器。常见的线性滤波器包括均值滤波和方框滤波。

方框滤波又称为盒式滤波,它利用卷积运算对图像邻域的像素值进行平均处理,从而实现消除图像中的噪声。方框滤波和和均值滤波的模糊内核基本一样,区别为是否需要进行均一化处理。

Python调用OpenCV中的cv2.boxFilter()函数实现方框滤波处理,其函数原型如下所示:

  • dst = boxFilter(src, depth, ksize[, dst[, anchor[, normalize[, borderType]]]])
    – src表示输入图像
    – dst表示输出图像,其大小和类型与输入图像相同
    – depth表示输出图像深度,通常设置为“-1”,表示与原图深度一致
    – ksize表示模糊内核大小,以(宽度,高度)的形式呈现
    – normalize表示是否对目标图像进行归一化处理,默认值为true
    – anchor表示锚点,即被平滑的那个点,其默认值Point(-1,-1)表示位于内核的中央,可省略
    – borderType表示边框模式,用于推断图像外部像素的某种边界模式,默认值为BORDER_DEFAULT,可省略

常见的模糊内核ksize包括(3,3)和(5,5),如下所示:

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第10张图片

参数normalize表示是否对目标图像进行归一化处理。

  • 当normalize为true时,需要执行归一化处理,方框滤波就变成了均值滤波。其中,归一化就是把要处理的像素值都缩放到一个范围内,以便统一处理和直观量化。
  • 当normalize为false时,表示非归一化的方框滤波,不进行均值化处理,实际上就是求周围各像素的和。但此时很容易发生溢出,多个像素值相加后的像素值大于255,溢出后的像素值均设置为255,即白色。

参数normalize的定义如公式所示。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第11张图片

图像方框滤波的Python实现代码如下所示,代码中使用3×3的核,normalize=0表示不进行图像归一化处理。

# -*- coding: utf-8 -*-
# By:Eastmount CSDN 2021-06-07
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('lena.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#方框滤波
result = cv2.boxFilter(source, -1, (3,3), normalize=0)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', '方框滤波']  
images = [source, result]  
for i in range(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()

方框滤波非归一化处理的输出结果如图11-7所示,处理后的效果图中包含很多白色的像素点,这是因为图像像素求和结果发生溢出(超过255)。由此可见,进行非归一化的处理时,得到的图像包含白色过多,对源图像的毁坏太大。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第12张图片

如果设置2×2的模糊内核,其非归一化的方框滤波处理效果更好一些,如图11-8所示。核心代码为:

  • cv2.boxFilter(source, -1, (2,2), normalize=0)

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第13张图片

下面是使用3×3内核,进行归一化方框滤波处理的代码,其输出结果与3×3内核均值滤波完全相同。

# -*- coding: utf-8 -*-
# By:Eastmount CSDN 2021-06-07
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('lena.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#方框滤波
result = cv2.boxFilter(source, -1, (3,3), normalize=1)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', '方框滤波']  
images = [source, result]  
for i in range(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()

图像3×3核的归一化方框滤波处理的输出结果如图9所示:

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第14张图片


四.高斯滤波

为了克服局部平均法造成图像模糊的弊端,又提出了一些保持边缘细节的局部平滑算法,图像高斯滤波(高斯平滑)就是这样一种算法。它是应用邻域平均思想对图像进行平滑的一种线性平滑滤波,对于抑制服从正态分布的噪声非常有效,适用于消除高斯噪声,被广泛应用于图像处理的减噪过程。

图像高斯滤波为图像不同位置的像素值赋予了不同的权重,距离越近的点权重越大,距离越远的点权重越小。它与方框滤波和均值滤波不同,它对邻域内的像素进行平均时,为不同位置的像素赋予不同的权值。通俗地讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值(权重不同)经过加权平均后得到。

下面是常用的3×3和5×5内核的高斯滤波模板。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第15张图片

高斯滤波引入了数学中的高斯函数(正态分布函数),一个二维高斯函数如下公式所示,其中σ为标准差。高斯加权平均中,最重要是σ的选取,标准差代表数据离散程度,如果σ较小,则高斯分布中心区域将更加聚集,平滑效果更差;反之,如果σ较大,高斯分布中心区域将更离散,平滑效果更明显。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第16张图片

高斯滤波的核心思想是对高斯函数进行离散化,以离散点上的高斯函数值为权值,对图像中的每个像素点做一定范围邻域内的加权平均,从而有效地消除高斯噪声。高斯滤波让临近中心的像素点具有更高的重要度,对周围像素计算加权平均值,如图10所示,其中心位置权重最高为0.4。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第17张图片

Python中OpenCV主要调用GaussianBlur()函数实现高斯平滑处理,函数原型如下所示:

  • dst = GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]])
    – src表示待处理的输入图像
    – dst表示输出图像,其大小和类型与输入图像相同
    – ksize表示高斯滤波器模板大小,ksize.width和ksize.height可以不同,但它们都必须是正数和奇数,它们也可以是零,即(0, 0)
    – sigmaX表示高斯核函数在X方向的高斯内核标准差
    – sigmaY表示高斯核函数在Y方向的高斯内核标准差。如果sigmaY为零,则设置为等于sigmaX,如果两个sigma均为零,则分别从ksize.width和ksize.height计算得到
    – borderType表示边框模式,用于推断图像外部像素的某种边界模式,默认值为BORDER_DEFAULT,可省略

下面代码是使用7×7核模板进行高斯滤波处理。

# -*- coding: utf-8 -*-
# By:Eastmount CSDN 2021-06-07
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('lena.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#高斯滤波
result = cv2.GaussianBlur(source, (7,7), 1.8)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', '高斯滤波']  
images = [source, result]  
for i in range(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

输出结果如图11所示,左边为待处理图像,右边为高斯滤波处理后的图像。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第18张图片

图12是使用15×15高斯核模板进行高斯滤波处理的效果图,由图可知,图像在去除噪声的同时也变得更加模糊。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第19张图片

总之,高斯滤波作为最有效的滤波器之一,它对于抑制服从正态分布的噪声非常有效。


五.中值滤波

前面讲述的都是线性平滑滤波,它们的中间像素值都是由邻域像素值线性加权得到的,接下来将讲解一种非线性平滑滤波——中值滤波。中值滤波通过计算每一个像素点某邻域范围内所有像素点灰度值的中值,来替换该像素点的灰度值,从而让周围的像素值更接近真实情况,消除孤立的噪声。

中值滤波对脉冲噪声有良好的滤除作用,特别是在滤除噪声的同时,能够保护图像的边缘和细节,使之不被模糊处理,这些优良特性是线性滤波方法所不具有的,从而使其常常被应用于消除图像中的椒盐噪声。

中值滤波算法的计算过程如图13所示。选择含有五个点的窗口,依次扫描该窗口中的像素,每个像素点所对应的灰度值按照升序或降序排列,然后获取最中间的值来替换该点的灰度值。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第20张图片

上图展示的是矩形窗口,常用的窗口还包括正方形、十字形、环形和圆形等,不同形状的窗口会带来不同的过滤效果,其中正方形和圆形窗口适合于外轮廓边缘较长的图像,十字形窗口适合于带尖角形状的图像。

OpenCV将中值滤波封装在medianBlur()函数中,其函数原型如下所示:

  • dst = medianBlur(src, ksize[, dst])
    – src表示待处理的输入图像
    – dst表示输出图像,其大小和类型与输入图像相同
    – ksize表示内核大小,其值必须是大于1的奇数,如3、5、7等

下面是调用medianBlur()函数实现中值滤波的代码。

# -*- coding: utf-8 -*-
# By:Eastmount CSDN 2021-06-07
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('lena.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#中值滤波
result = cv2.medianBlur(source, 3)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', '中值滤波']  
images = [source, result]  
for i in range(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

其运行结果如图14所示,它有效地过滤掉了“lena”图中的噪声,并且很好地保护了图像的边缘信息,使之不被模糊处理。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第21张图片


六.双边滤波

双边滤波(Bilateral filter)是由Tomasi和Manduchi在1998年发明的一种各向异性滤波,它一种非线性的图像平滑方法,结合了图像的空间邻近度和像素值相似度(即空间域和值域)的一种折中处理,从而达到保边去噪的目的。双边滤波的优势是能够做到边缘的保护,其他的均值滤波、方框滤波和高斯滤波在去除噪声的同时,都会有较明显的边缘模糊,对于图像高频细节的保护效果并不好。

双边滤波比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数。所以在图像边缘附近,离的较远的像素点不会过于影响到图像边缘上的像素点,从而保证了图像边缘附近的像素值得以保存。但是双边滤波也存在一定的缺陷,由于它保存了过多的高频信息,双边滤波不能有效地过滤掉彩色图像中的高频噪声,只能够对低频信息进行较好地去噪。

在双边滤波器中,输出的像素值依赖于邻域像素值的加权值组合,对输入图像进行局部加权平均得到输出图像 的像素值,其公式如下所示:

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第22张图片

式中表示中心点(x,y)的(2N+1)×(2N+1)的领域像素,值依赖于领域像素值的加权平均。权重系数取决于空间域核(domain)和值域核(range)的乘积。

空间域核的定义如公式所示。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第23张图片

值域核的定义如公式所示。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第24张图片

两者相乘之后,就会产生依赖于数据的双边滤波权重函数,如下所示:

在这里插入图片描述

从式子可以看出,双边滤波器的加权系数是空间邻近度因子和像素亮度相似因子的非线性组合。前者随着像素点与中心点之间欧几里德距离的增加而减小,后者随着像素亮度之差的增大而减小。

在图像变化平缓的区域,邻域内亮度值相差不大,双边滤波器转化为高斯低通滤波器;在图像变化剧烈的区域,邻域内像素亮度值相差较大,滤波器利用边缘点附近亮度值相近的像素点的亮度平均值替代原亮度值。因此,双边滤波器既平滑了图像,又保持了图像边缘,其原理图如图15所示。

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第25张图片

OpenCV将中值滤波封装在bilateralFilter()函数中,其函数原型如下所示:

  • dst = bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])
    – src表示待处理的输入图像
    – dst表示输出图像,其大小和类型与输入图像相同
    – d表示在过滤期间使用的每个像素邻域的直径。如果这个值我们设其为非正数,则它会由sigmaSpace计算得出
    – sigmaColor表示颜色空间的标准方差。该值越大,表明像素邻域内较远的颜色会混合在一起,从而产生更大面积的半相等颜色区域
    – sigmaSpace表示坐标空间的标准方差。该值越大,表明像素的颜色足够接近,从而使得越远的像素会相互影响,更大的区域中相似的颜色获取相同的颜色,当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace
    – borderType表示边框模式,用于推断图像外部像素的某种边界模式,默认值为BORDER_DEFAULT,可省略

下面是调用bilateralFilter()函数实现双边滤波的代码,其中d为15,sigmaColor设置为150,sigmaSpace设置为150。

# -*- coding: utf-8 -*-
# By:Eastmount CSDN 2021-06-07
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('te.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#双边滤波
result = cv2.bilateralFilter(source, 15, 150, 150)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', '双边滤波']  
images = [source, result]  
for i in range(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

其运行结果如图16所示:

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第26张图片


七.总结

写到这里,本文就介绍完毕。本文主要讲解了常用于消除噪声的图像平滑方法,包括三种线性滤波(均值滤波、方框滤波、高斯滤波)和两种非线性滤波(中值滤波、双边滤波)。本文通过原理和代码进行对比,分别讲述了各种滤波方法的优缺点,有效地消除了图像的噪声,并保留图像的边缘轮廓。

最后补充所有图像平滑算法的对比代码和结果。

# -*- coding: utf-8 -*-
# By:Eastmount CSDN 2021-06-07
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('te.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#均值滤波
result1 = cv2.blur(source, (5,5))
result2 = cv2.blur(source, (10,10))

#方框滤波
result3 = cv2.boxFilter(source, -1, (5,5), normalize=1)
result4 = cv2.boxFilter(source, -1, (2,2), normalize=0)

#高斯滤波
result5 = cv2.GaussianBlur(source, (3,3), 0)
result6 = cv2.GaussianBlur(source, (15,15), 0)

#中值滤波
result7 = cv2.medianBlur(source, 3)

#高斯双边滤波
result8 =cv2.bilateralFilter(source, 15, 150, 150)

#显示图形
titles = ['Source', 'Blur 5*5', 'Blur 10*10', 'BoxFilter 5*5',
          'BoxFilter 2*2', 'GaussianBlur 3*3', 'GaussianBlur 15*15',
          'medianBlur', 'bilateralFilter']  
images = [source, result1, result2, result3,
          result4, result5, result6, result7, result8]  
for i in range(9):  
   plt.subplot(3,3,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

运行结果如下图所示:

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第27张图片

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第28张图片

同样我增加了前文的均值迁移,进行简单的对比,代码如下:

# -*- coding: utf-8 -*-
# By:Eastmount CSDN 2021-06-07
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图片
img = cv2.imread('test01_yn.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 
#中值滤波
result1 = cv2.medianBlur(source, 3)

#高斯双边滤波
result2 =cv2.bilateralFilter(source, 15, 150, 150)

#均值迁移
result3 = cv2.pyrMeanShiftFiltering(source, 20, 50)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像',  '中值滤波', '双边滤波', '均值迁移']  
images = [source, result1, result2, result3]  
for i in range(4):  
   plt.subplot(2,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

女神的运行结果如下图所示:

[Python图像处理] 四十一.Python图像平滑万字详解(均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波)_第29张图片

  • 一.图像平滑概述
    1.图像平滑
    2.线性滤波和非线性滤波
    3.常见滤波器
  • 二.均值滤波
    1.算法原理
    2.代码实现
  • 三.方框滤波
  • 四.高斯滤波
  • 五.中值滤波
  • 六.双边滤波

源代码下载地址,记得帮忙点star和关注喔。

  • https://github.com/eastmountyxz/ImageProcessing-Python

大学之道在明明德,
在亲民,在止于至善。
这周又回答了很多博友的问题,有大一学生的困惑,有论文的咨询,也有老乡和考博的疑问,还有无数博友奋斗路上的相互勉励。虽然自己早已忙成狗,但总忍不住去解答别人的问题。最后那一句感谢和祝福,永远是我最大的满足。虽然会花费我一些时间,但也挺好的,无所谓了,跟着心走。不负遇见,感恩同行。莫愁前路无知己,继续加油。晚安娜和珞。

在这里插入图片描述

(By:Eastmount 2021-06-07 晚上10点 http://blog.csdn.net/eastmount/ )


参考文献:

  • [1] 罗子江. Python中的图像处理[M]. 科学出版社 2020.
  • [2]冈萨雷斯著. 数字图像处理(第3版)[M]. 北京:电子工业出版社,2013.
  • [3]阮秋琦. 数字图像处理学(第3版)[M]. 北京:电子工业出版社,2008.
  • [4]毛星云,冷雪飞. OpenCV3编程入门[M]. 北京:电子工业出版社,2015.
  • [5]张铮,王艳平,薛桂香等. 数字图像处理与机器视觉——Visual C++与Matlab实现[M]. 北京:人民邮电出版社,2014.
  • [6]杨秀璋. Python网络数据爬取及分析从入门到精通(分析篇)[M]. 北京:北京航天航空大学出版社, 2018.
  • [7]石振刚. 基于模糊逻辑的图像处理算法研究[D]. 东北大学, 2009.
  • [8]马光豪. 基于稀疏高频梯度和联合双边滤波的图像平滑算法研究[D].山东大学, 2018.
  • [9]陈初侠. 图像滤波及边缘检测与增强技术研究[D].合肥工业大学, 2009.
  • [10]C. Tomasi, R Manduchi. Bilateral Filtering for Gray and Color images[C]. Proceedings of the IEEE International Conference on Computer Vision, Bombay, India. 1998:839-846.

你可能感兴趣的:(Python图像处理及图像识别,Python图像处理,图像平滑,均值滤波,高斯滤波,OpenCV)