图像滤波,可以对图像进行增强(提取图像特征),或对图像进行平滑(降噪、模糊)。
滤波器分类
-
低通滤波器:允许低频率像素通过(去噪、模糊)
-
高通滤波器:允许高频率像素通过(边缘检测、锐化)
线性滤波器:每个像素的输出值是一些输入像素的加权和,易于从频率响应角度来进行分析,如:
-
方框滤波:cv2.boxblur函数
-
均值滤波:cv2.blur函数
-
高斯滤波:cv2.GaussianBlur函数
非线性滤波,滤波速度相对较慢,有时可以达到更好的实现效果,如:
-
中值滤波:cv2.medianBlur函数
-
双边滤波:cv2.bilateralFilter函数
boxblur 方框滤波
用于计算每个像素邻域内的积分特性。方框滤波所用到的核:
h = α [ 1 1 . . . 1 1 1 . . . 1 . . . . . . . . 1 1 . . . 1 ] h = \alpha \begin{bmatrix} 1 & 1 & ... & 1\\ 1 & 1 & ... & 1\\ ..& .. & .. & ..\\ 1 & 1 & ... & 1 \end{bmatrix} h=α⎣⎢⎢⎡11..111..1...........11..1⎦⎥⎥⎤
其中:
α = { 1 k S i z e . w i d t h × k S i z e . h e i g h t n o r m a l i z e = T r u e 1 o t h e r w i s e } \alpha = \begin{Bmatrix} \frac{1}{kSize.width \times kSize.height} & normalize = True\\ 1 & otherwise \end{Bmatrix} α={kSize.width×kSize.height11normalize=Trueotherwise}
当normalize(归一化)为true时,方框滤波也就成了均值滤波。
函数原型如下:
def boxFilter(src, ddepth, ksize, dst=None, anchor=None, normalize=None, borderType=None)
参数:
-
src:输入图像,即源图像,函数对通道是独立处理的,且可以处理任意通道数的图片
-
ddepth:出图像的深度,-1代表使用原图深度
-
ksize:卷积核的大小,Size( w,h )
-
dst:输出目标图像
-
anchor:锚点(即被平滑的那个点),默认值Point(-1,-1),负值表示取核的中心为锚点
-
normalize:是否归一化(normalized),默认值为true
-
borderType:用于推断图像外部像素的某种边界模式,默认值BORDER_DEFAULT
返回:输出目标图像
blur 均值滤波
使用邻域像素均值进行滤波,在图像去噪的同时也破坏了图像的细节部分,使图像变得模糊。
函数原型如下:
def blur(src, ksize, dst=None, anchor=None, borderType=None)
参数:
-
src:输入图像,即源图像,函数对通道是独立处理的,且可以处理任意通道数的图片
-
ksize:卷积核的大小,Size( w,h )
-
dst:输出目标图像
-
anchor:锚点(即被平滑的那个点),默认值Point(-1,-1),负值表示取核的中心为锚点
-
borderType:用于推断图像外部像素的某种边界模式,默认值BORDER_DEFAULT
返回:输出目标图像
GaussianBlur 高斯滤波
采用离散化的高斯函数产生归一化的高斯核,基于高斯核函数对图像灰度矩阵的每一点进行加权求和,对于抑制服从正态分布的噪声非常有效。
函数原型如下:
def GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
参数:
-
src:输入图像,即源图像,函数对通道是独立处理的,且可以处理任意通道数的图片
-
ksize:卷积核的大小,Size( w,h ),w,h为正奇数,可以不同
-
sigmaX:表示高斯核函数在X方向的的标准偏差,double类型
-
dst:输出目标图像
-
sigmaY:表示高斯核函数在Y方向的的标准偏差,double类型
-
borderType:用于推断图像外部像素的某种边界模式,默认值BORDER_DEFAULT
返回:输出目标图像
若sigmaY为零,则sigmaY=sigmaX,若sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来
正态分布:
![](https://img-blog.csdnimg.cn/20181116190219306.png)
正态分布的密度函数叫做"高斯函数"(Gaussian function)。它的一维形式是:
f ( x ) = 1 σ 2 π e − ( x − μ ) 2 2 σ 2 f(x)=\frac{1}{\sigma \sqrt{2\pi}}e^{-\frac{(x-\mu )^2}{2\sigma^2}} f(x)=σ2π1e−2σ2(x−μ)2
其中, μ μ μ是 x x x的均值, σ σ σ是 x x x的方差。计算平均值的时候,中心点为原点时, μ μ μ等于0:
f ( x ) = 1 σ 2 π e − x 2 2 σ 2 f(x)=\frac{1}{\sigma \sqrt{2\pi}}e^{-\frac{x^2}{2\sigma^2}} f(x)=σ2π1e−2σ2x2
根据一维高斯函数,可以推导得到二维高斯函数:
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
有了这个函数 ,就可以计算每个点的权重了。
medianBlur 中值滤波
用邻域灰度的中值进行滤波,在去除脉冲/椒盐噪声的同时还能保留图像的细节部分,花费时间是均值滤波的5倍以上,但其在噪声的消除能力上更强。对一些细节多,特别是线、尖顶等细节多的图像不宜采用中值滤波。
函数原型如下:
def medianBlur(src, ksize, dst=None)
参数:
-
src:输入 1、3或者4通道的图像
-
ksize:孔径的线性尺寸,值为大于1的正奇数
-
dst:输出目标图像
返回:输出目标图像
bilateralFilter 双边滤波
使用空间邻近度和灰度相似度进行滤波,比高斯滤波多了一个高斯方差sigma-d,是基于空间分布的高斯滤波函数,达到保留边缘且去除噪声的目的。具有简单、非迭代、局部的特点。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。
函数原型如下:
def bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None)
参数:
-
src:输入图像,即源图像,函数对通道是独立处理的,且可以处理任意通道数的图片
-
d:表示在过滤过程中每个像素邻域的直径
-
sigmaColor:颜色空间滤波器的sigma值。值越大,表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
-
sigmaSpace:坐标空间中滤波器的sigma方差值,数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。
-
dst:输出目标图像
-
borderType:用于推断图像外部像素的某种边界模式,默认值BORDER_DEFAULT
返回:输出目标图像
使用openCV进行图像滤波
import cv2
def smoothing(k):
if k % 2 == 0:
return
box = cv2.boxFilter(gray, -1, (k, k))
blur = cv2.blur(gray, (k, k))
gaussian = cv2.GaussianBlur(gray, (k, k), 0)
median = cv2.medianBlur(gray, k, 0)
bilateral = cv2.bilateralFilter(gray, k, k*2, k/2)
cv2.imshow('box', box)
cv2.moveWindow('box', 650, 40)
cv2.imshow('blur', blur)
cv2.moveWindow('blur', 1200, 40)
cv2.imshow('gaussian', gaussian)
cv2.moveWindow('gaussian', 20, 400)
cv2.imshow('median', median)
cv2.moveWindow('median', 650, 400)
cv2.imshow('bilateral', bilateral)
cv2.moveWindow('bilateral', 1200, 400)
cv2.namedWindow('filter demo')
cv2.moveWindow('filter demo',20,20)
img = cv2.imread("/home/blue/Ivy/data/haar/VehicleDataset/train/91_frame.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('filter demo', img)
ksize = 3
cv2.createTrackbar('ksize', 'filter demo', ksize, 25, smoothing)
smoothing(ksize)
if cv2.waitKey(0) == 27:
cv2.destroyAllWindows()
滤波器 k S i z e = 5 kSize=5 kSize=5 时:
![](https://img-blog.csdnimg.cn/20181116192345684.png)
滤波器 k S i z e = 9 kSize=9 kSize=9 时:
![](https://img-blog.csdnimg.cn/20181116192448172.png)
滤波器 k S i z e = 25 kSize=25 kSize=25 时:
![](https://img-blog.csdnimg.cn/2018111619252399.png)
滤波后,进行边缘检测,滤波器 k S i z e = 5 kSize=5 kSize=5 时:
![](https://img-blog.csdnimg.cn/20181116192711701.png)
滤波器 k S i z e = 9 kSize=9 kSize=9 时:
![](https://img-blog.csdnimg.cn/20181116192747460.png)