滤波操作
1、线性滤波和非线性滤波简介
线性滤波:这里用卷积神经网络中卷积操作的形式来理解线性滤波,即通过模板与对应区域的的加减乘除来获得 新的像素值,二者之间具有确定的数学关系,如下图所示
线性滤波通常用来剔除诸多信号中的某一个频率或者从众多频率中选择出某一个。常用的线性滤波有均值滤波和高斯滤波等。
非线性滤波使用的是逻辑关系,比较模板区域内数值的大小关系来进行滤波。常用的主要有中值滤波和双边滤波等。
2、均值滤波和高斯滤波
均值滤波会破坏图像细节是均值滤波的固有缺陷,会让图像变得‘模糊’也无法去除噪音。
高斯滤波是最常用的一种滤波方式,对服从正态分布的噪音效果尤为明显。在图像处理中使用的是二维零均值离散高斯函数作为平滑滤波器。但是高斯滤波只考虑像素空间分布,并未考虑像素值差异,因此容易造成边缘模糊。
G
(
x
,
y
)
=
1
2
π
σ
2
e
−
x
2
+
y
2
2
σ
2
G(x,y)=\frac{1}{2\pi\sigma^2}e^{-\frac{x^2+y^2}{2\sigma^2}}
G(x,y)=2πσ21e−2σ2x2+y2其中
σ
\sigma
σ 是带宽,控制径向作用范围, 控制着高斯核函数的局部作用范围
基本的高斯核:
import numpy as np
import cv2 as cv
#均值滤波
def blur_demo(image):
#kernel size 5*5
dst=cv.blur(image,(5,5))
cv.imshow('blur_demo',dst)
def gaussian_demo(image):
#kernel size 5*5
dst=cv.GaussianBlur(image,(5,5),0)
cv.imshow('gaussian',dst)
#防止溢出
def guizheng(values):
if values>255:
return 255
if values<0:
return 0
else:
return
#添加高斯噪音
def gaussian_noise(image):
h,w,ch=image.shape
for row in range(h):
for col in range(w):
s=np.random.normal(0,20,3)
b=image[row,col,0]
g=image[row,col,1]
r=image[row,col,2]
image[row,col,0]=guizheng(b+s[0])
image[row,col,1]=guizheng(g+s[1])
image[row,col,2]=guizheng(r+s[2])
cv.imshow('noise',image)
src=cv.imread('lena.png')
cv.imshow('input',src)
gaussian_noise(src)
blur_demo(src)
gaussian_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果如下:图1为原图,图2添加高斯噪声,图3为均值滤波,图4为高斯滤波
3、中值滤波和双边滤波
中值滤波就是取邻域内像素值的中位数。相比均值滤波,在保留边缘和去除椒盐噪声方面表现良好,但是中值滤波的计算量大致是均值滤波的5倍以上。
双边滤波是基于Gauss 滤波方法提出的一种优化方法,将滤波权系数优化成Gauss 函数和图像亮度信息的乘积,优化后的权系数再与图像信息作卷积运算。
f
^
(
x
,
y
)
=
∑
(
i
,
j
)
∈
S
x
,
y
w
(
i
,
j
)
g
(
i
,
j
)
∑
(
i
,
j
)
∈
S
x
,
y
w
(
i
,
j
)
\hat{f}(x,y)=\frac{\sum_{(i,j)\in S_{x,y} } w(i,j)g(i,j)}{\sum_{(i,j)\in S_{x,y} } w(i,j)}
f^(x,y)=∑(i,j)∈Sx,yw(i,j)∑(i,j)∈Sx,yw(i,j)g(i,j)
其中
S
x
,
y
S_{x,y}
Sx,y表示中心点(x,y)的邻域。
权重w由两部分组成
w
s
w_s
ws 和
w
e
w_e
we相乘得到。
w
s
(
i
,
j
)
=
e
∣
i
−
x
∣
2
+
∣
j
−
y
∣
2
2
σ
s
2
w_s(i,j)=e^{\frac{|i-x|^2+|j-y|^2}{2\sigma_s^2}}
ws(i,j)=e2σs2∣i−x∣2+∣j−y∣2
w
e
(
)
i
,
j
=
e
∣
g
(
i
,
j
)
−
g
(
x
,
y
)
∣
2
2
σ
r
2
w_e()i,j=e^{\frac{|g(i,j)-g(x,y)|^2}{2\sigma_r^2}}
we()i,j=e2σr2∣g(i,j)−g(x,y)∣2
前者随着像素点与中心点之间欧几里德距离的增加而减小,后者随着两像素亮度值之差的增大而减小。在图像变化平缓的区域,邻域内像素亮度值相差不大,双边滤波转化为高斯低通滤波器;在图像变化剧烈的区域,滤波器利用边缘点附近亮度值相近的像素点的亮度值平均代替原亮度值。
import cv2 as cv
#中值滤波
def median_blur_demo(image):
dst=cv.medianBlur(image,5)
cv.imshow('median_blur',dst)
#双边滤波
def shuangbian_demo(image):
dst=cv.bilateralFilter(image,0,100,15)#100指的是像素值差超过100就保留,15选小一点
cv.imshow('shuangbian_demo',dst)
src=cv.imread('lena.png')
cv.imshow('input',src)
median_blur_demo(src)
shuangbian_demo(src)
cv.waitKey(0)
效果如下:
参考资料
双边滤波器、高斯滤波