0.综述
图像的滤波本质上就是图像的卷积操作,而图像卷积可以看成是一个滑动的窗口在一个比它大的图像上有规则(从左向右,从上往下)地滑动,对每一次窗口覆盖到的图像子区域都会进行点乘操作,然后就得到的值作为原图中被窗口覆盖区域的中心像素点的新值。
与CNN
里的卷积不同,经典的卷积算子(即卷积核)往往是人们根据研究和经验事先设定好的特征提取算子,而CNN
卷积核中的参数是通过训练不断调整最终得到合适的权值参数。
1.图像均值滤波
均值滤波:卷积核内的参数如下都是一样的。
[
1
1
1
1
1
1
1
1
1
]
\left[ \begin{matrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1& 1 \end{matrix} \right]
⎣⎡111111111⎦⎤
但是由于图像像素应当介于0到255之间,全部为1的卷积核可能会使产生的像素值远大于255,所以应当使用归一化后的卷积核:
[
1
/
9
1
/
9
1
/
9
1
/
9
1
/
9
1
/
9
1
/
9
1
/
9
1
/
9
]
\left[ \begin{matrix} 1/9 & 1/9 & 1/9 \\ 1/9 & 1/9 & 1/9 \\ 1/9 & 1/9& 1/9 \end{matrix} \right]
⎣⎡1/91/91/91/91/91/91/91/91/9⎦⎤
C++
接口的函数原型:
void blur( InputArray src, OutputArray dst,
Size ksize, Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT );
其中src
是输入图像,dst
是输出图像,ksize
是滑动窗口的大小,剩余两个参数一般使用默认值,默认值Point(-1,-1)
表示这个锚点在核的中心,bodertype
是边缘插值方法。
举个栗子:
Mat input_image = imread("./whisper.jpg", 1);
if (input_image.empty())
{
cout << "read input error!" << endl;
return -1;
}
imshow("input", input_image);
Mat result;
blur(input_image, result, Size(5, 5), Point(-1, -1), 4);
imshow("result", result);
结果:
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σ2)−(x2+y2)
对于一个3x3的卷积核来说,分别取
x
,
y
x,y
x,y 为
−
1
,
0
,
1
-1,0 ,1
−1,0,1,则当
σ
\sigma
σ=1时,得到的3x3卷积核如下:
[
0.058
0.096
0.058
0.096
0.159
0.096
0.058
0.096
0.058
]
\left[ \begin{matrix} 0.058 & 0.096 & 0.058 \\ 0.096 & 0.159 & 0.096 \\ 0.058 & 0.096& 0.058 \end{matrix} \right]
⎣⎡0.0580.0960.0580.0960.1590.0960.0580.0960.058⎦⎤
该结果同样需要进行归一化:
[
0.075
0.124
0.075
0.124
0.204
0.124
0.075
0.124
0.075
]
\left[ \begin{matrix} 0.075 & 0.124 & 0.075 \\ 0.124 & 0.204 & 0.124 \\ 0.075 & 0.124& 0.075 \end{matrix} \right]
⎣⎡0.0750.1240.0750.1240.2040.1240.0750.1240.075⎦⎤
C++
接口的函数原型:
void GaussianBlur( InputArray src,
OutputArray dst, Size ksize,
double sigmaX, double sigmaY = 0,
int borderType = BORDER_DEFAULT );
其中sigmaX
是x方向滤波系数,sigmaY
(默认为0)是y方向滤波系数。
举个栗子:
GaussianBlur(input_image, result, Size(15,15),15,0, 4);
结果:
3.图像中值滤波
中值滤波是对窗口覆盖区域内所有原图的像素值进行排序后取中值作为中心像素点的值,对去椒盐噪声的效果比较好。
C++
接口的函数原型:
void medianBlur( InputArray src,
OutputArray dst,
int ksize );
其中ksize
必须是大于1的奇数。
举个栗子:
Mat input_image = imread("./flower.jpg", 1);
if (input_image.empty())
{
cout << "read input error!" << endl;
return -1;
}
imshow("input", input_image);
Mat result;
medianBlur(input_image, result, 3);
imshow("result", result);
结果:
4.完整代码
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char**argv)
{
Mat input_image = imread("./flower.jpg", 1);
if (input_image.empty())
{
cout << "read input error!" << endl;
return -1;
}
imshow("input", input_image);
Mat result;
//blur(input_image, result, Size(5, 5), Point(-1, -1), 4);
//GaussianBlur(input_image, result, Size(15,15),15,0, 4);
medianBlur(input_image, result, 3);
imshow("result", result);
waitKey(0);
destroyAllWindows();
return 0;
}