平滑(低通)滤波处理
平滑滤波处理用于降低灰度的急剧过渡,主要作用如下:
- 降噪
- 模糊
3x3的线性空间滤波的原理如下式所示:
g
(
x
,
y
)
=
(
w
(
−
1
,
−
1
)
f
(
x
−
1
,
y
−
1
)
+
w
(
−
1
,
0
)
f
(
x
−
1
,
y
)
+
.
.
.
+
w
(
0
,
0
)
f
(
x
,
y
)
+
.
.
.
+
w
(
1
,
1
)
f
(
x
+
1
,
y
+
1
)
)
g(x,y)=(w(-1,-1)f(x-1,y-1)+w(-1,0)f(x-1,y)+...+w(0,0)f(x,y)+...+w(1,1)f(x+1,y+1))
g(x,y)=(w(−1,−1)f(x−1,y−1)+w(−1,0)f(x−1,y)+...+w(0,0)f(x,y)+...+w(1,1)f(x+1,y+1))
核的中心系数 w(0,0)对齐于(x,y)处的像素。对于大小为𝑚×𝑛的核,假设m=2a+1 和 n=2b+1,其中 a 和 b 是非负整数,均值滤波可表示为:
g
(
x
,
y
)
=
1
m
n
∑
s
=
−
a
a
∑
t
=
−
b
b
w
(
s
,
t
)
f
(
x
+
s
,
y
+
t
)
g(x,y)=\frac{1}{mn}\sum_{s=-a}^a\sum_{t=-b}^bw(s,t)f(x+s,y+t)
g(x,y)=mn1s=−a∑at=−b∑bw(s,t)f(x+s,y+t)
注:该图中x和y方向与OpenCV中的坐标相反
由图可知,滤波器核与图像做卷积运算产生的新图像,其图像尺寸比原图像尺寸要小,要使新图像与原图像尺寸一致,需要在滤波处理前进行边缘填充。
零填充的效果如下所示:
OpenCV中使用BorderTypes进行填充,常用的信息如下:
BorderTypes | 解释 |
---|---|
BORDER_CONSTANT | iiiiii|abcdefgh|iiiiiii,指定了i值(常值填充) |
BORDER_REPLICATE | aaaaaa|abcdefgh|hhhhhhh(复制填充) |
BORDER_REFLECT | fedcba|abcdefgh|hgfedcb (镜像填充) |
BORDER_WRAP | cdefgh|abcdefgh|abcdefg |
BORDER_REFLECT_101 | gfedcb|abcdefgh|gfedcba(与镜像填充类似) |
均值滤波
平滑边缘一般使用均值滤波器,其原理是求邻近像素点的灰度值,降低灰度的急剧过渡,邻域的大小与平滑的效果直接相关,邻域越大平滑的效果越好,但邻域过大,平滑会使边缘信息损失的过大,从而使输出的图像变得模糊。
3x3的均值滤波器(也称为核)权重如下:
任意大小的滤波器权重如下:
均值滤波使用blur
函数,信息如下:
参数1:src,输入的图像
参数2:dst,输出的图像
参数3:ksize,均值滤波核的大小
参数4:anchor,锚点,表示核的中心,不常使用
参数5:borderType,图像外部像素边框,不常使用
代码示例如下:
blur(src,dst,Size(3,3));
高斯滤波
均值滤波器的方向性存在着沿垂直方向模糊图像等限制问题,因此需要核为圆对称的高斯滤波。
高斯滤波器核的权重如下:
w
(
s
,
t
)
=
G
(
s
,
t
)
=
K
e
−
s
2
+
t
2
2
σ
2
w(s,t)=G(s,t)=Ke^{-\frac{s^2+t^2}{2\sigma^2}}
w(s,t)=G(s,t)=Ke−2σ2s2+t2
高斯滤波使用GaussianBlur
函数,信息如下:
参数1:src,输入的图像
参数2:dst,输出的图像
参数3:ksize,均值滤波核的大小
参数4:sigmaX,X方向的标准差
参数5:sigmaY,Y方向的标准差
参数6:borderType,图像外部像素边框,不常使用
代码示例如下:
GaussianBlur(src,dst,Size(3,3),0);
中值滤波
中值滤波是排序统计滤波器,也是非线性的空间滤波器,基于滤波器所包含区域内的像素排序。将中心像素的值代替为排序结果的中值。
能有效去除冲击噪声(白点和黑点叠加,即椒盐噪声)。
中值滤波使用medianBlur
函数,信息如下:
参数1:src,输入图像
参数2:dst,输出图像
参数3:ksize,核的大小
代码示例如下:
medianBlur(src,dst,3);
测试
下面将使用图片队上述三种滤波依次进行测试。
均值滤波
测试原图命名为blur.png,如下所示:
均值滤总代码如下:
#include<iostream>
#include<opencv.hpp>
using namespace std;
using namespace cv;
int main() {
Mat dst,src = imread("blur.png");
blur(src, dst, Size(5, 5));
imshow("src", src);
imshow("dst", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
结果如下图所示:
可以看到相较原图已产生模糊效果。
高斯滤波测试
高斯滤波总代码如下:
#include<iostream>
#include<opencv.hpp>
using namespace std;
using namespace cv;
int main() {
Mat dst,src = imread("blur.png");
GaussianBlur(src, dst, Size(3, 3),0);
imshow("src", src);
imshow("dst", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
结果如下图所示:
相较原图已产生模糊处理,虽然看上去与均值滤波效果类似,但在特定图像上效果比均值滤波效果要好。
中值滤波测试
中值滤波总代码如下:
#include<iostream>
#include<opencv.hpp>
using namespace std;
using namespace cv;
int main() {
Mat dst,src = imread("blur.png");
medianBlur(src, dst, 3);
imshow("src", src);
imshow("dst", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
测试结果如下所示:
相较原图右侧的椒盐噪点已被消除了许多,且其他部分与图片大致上一致。