前言
如果从某种角度考虑,可以把图像(Image)看成一种波(Wave)。
假设有一张 n × m n\times m n×m 的灰度图,每个像素点的取值范围是 [ 0.0 , 1.0 ] [0.0,1.0] [0.0,1.0] ,如果我们把图像展开成一幅波形图,横轴表示像素点的坐标(由二维坐标按照一定规律映射成一维坐标),纵轴表示像素点的取值,那么就可以把图像变成的波提取出两种信号:
- 高频信号:波形变化剧烈的地方,这在图像中体现为边缘、噪声点等色彩变化剧烈的地方;
- 低频信号:其它地方
基于这种思想,对图像的预处理可以看成是滤波的过程。高通滤波(High-Pass Filters, HPF)可以用于保留图像的边缘信息;低通滤波(Low-Pass Filters, LPF)可以用于降噪、图像平滑等。
二维滤波其实就是一种卷积运算,定义一个核(Kernel)
K
r
×
r
K_{r\times r}
Kr×r(
r
r
r 一般是奇数),对图像
A
A
A 进行滤波就等价于如下运算:
A
′
(
x
,
y
)
=
∑
1
≤
i
≤
r
,
1
≤
j
≤
r
K
(
i
,
j
)
A
(
x
−
r
+
1
2
+
i
,
y
−
r
+
1
2
+
j
)
A'(x,y)=\sum\limits_{1\le i\le r, 1\le j\le r}{K(i,j)A(x-\frac{r+1}{2}+i,y-\frac{r+1}{2}+j)}
A′(x,y)=1≤i≤r,1≤j≤r∑K(i,j)A(x−2r+1+i,y−2r+1+j)
在 OpenCV 中,定义好卷积核之后,滤波可以调用 cv.filter2D()
实现,例如对于均值滤波核,滤波代码如下:
import random
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = plt.imread("data/test.png")
kernel = np.ones((5, 5), np.float32) / 25
out = cv.filter2D(img, -1, kernel)
cv.filter2D()
的参数可以参考定义文档。
图像模糊的类别
图像模糊 **(Image Smoothing/Blurring)**技术的实现方式是低通滤波,用于过滤噪声点。其包含但不限于以下几种类别:
- 均值模糊(Averaging Blurring)
- 高斯模糊(Gaussian Blurring)
- 中值模糊(Median Blurring)
下面分别讨论:
均值模糊

均值模糊示意图
kernel 为归一化均值,比如滤波核为 K r × r K_{r\times r} Kr×r,那么该核的每一个位置的取值都是 1 r 2 \frac{1}{r^2} r21 。均值模糊处理图像就是把每一个像素点变为其周围若干个像素点的均值,在 OpenCV 中的实现方式如下:
out = cv.blur(img, (5, 5))
第一个参数为原图像,第二个参数为核的大小。
高斯模糊

高斯模糊示意图
高斯模糊的关键在于构造高斯核。二维高斯函数表示为
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πσ21e2σ2−(x2+y2)
然后对于核
K
r
×
r
K_{r\times r}
Kr×r,最中间的位置定为原点
(
0
,
0
)
(0,0)
(0,0),最左上角的位置定为
(
−
r
−
1
2
,
−
r
−
1
2
)
(-\frac{r-1}{2},-\frac{r-1}{2})
(−2r−1,−2r−1),于是核
K
K
K 的每个位置都可以通过高斯函数计算得到。最后对
K
K
K 归一化处理(每个位置除以
K
K
K 的求和),保证核的求和为
1
1
1 ,这样就得到了高斯核。
在 OpenCV 中,构造高斯核可以调用 cv.getGaussianKernel()
,而进行高斯模糊的实现方式则是:
out = cv.GaussianBlur(img, (5, 5), 0)
其中第一个参数为原图像,第二个参数为核的大小,第三个参数为
σ
\sigma
σ 取值(0 表示自动计算取值)。高斯模糊对于去除高斯噪声非常有效,因此在高斯模糊示意图
中在原图添加高斯噪声之后,再进行模糊处理。
中值模糊

中值模糊示意图
中值模糊就是就是对每一个像素点,把它变为其周围若干个像素点的中值。这种模糊方法对椒盐噪声的去除特别有效。
在 OpenCV 中,进行中值模糊的实现方式是:
out = cv.medianBlur(img, 5)
其中第一个参数为原图像,第二个参数为核的大小(边长)。
其它说明
图像模糊其实就是滤波的一种应用,因此诸如“高斯模糊”也可以说成是“高斯滤波”,两者表示的是同一个意思。