均值滤波
一、目的与原理
(1)目的:去除图像上的尖锐噪声,平滑图像。
(2)原理:均值滤波属于线性滤波,它的实现原理是邻域平均法。其中,公式①的Sxy表示中心点在(x,y)处,M表示大小为m×n的滤波器窗口,M=(2m+1)(2n+1),m和n可以相等。实际上就是用取均值的方式替换原图像中的像素值,即选择一个大小为M模板,该模板由其近邻的若干像素组成,求模板中所有像素的均值,最后填充到输出图像中。g(s , t)表示原始图像, f(x,y)表示均值滤波后得到的图像。
公式①:
其中,M =(2m+1)(2n+1),m和n可以相等;
以3*3卷积核示例,对于均值滤波来讲,虽然每个像素点的权重都为1,但是还是需要用到卷积核,因为3*3的均值滤波核5*5的均值滤波效果是不一样的,所以卷积核还是不能忽略。而且在此引用卷积核的概念还能更加直观的看到我们的取点方式。
3*3的核示例:
二、算法步骤
(1)判断卷积核是否为偶数,如果是偶数就退出;
(2)边缘处理;
(3)判断图片的通道数,单通道和多通道需要分开处理;
(4)通过公式①计算各点的值;
(5)将各点的值存储到Mat对象中
(6)显示Mat对象,查看均值滤波处理后的结果;
三、伪代码
输入:待处理图像src,输出图像dst,卷积核大小wsize
输出:引用的方式输出图像dst
Void AverFilter(Mat& src, Mat& dst, Size wsize)
{
If(卷积核Ksize为偶数)
报异常,退出
边缘处理
If(图片通道数等于1){
单通道的方式求像素点均值
处理结果赋值到输出图像中
}
If(图片通道数大于1){
多通道的方式求像素点均值
处理结果赋值到输出图像中
}
}
四、特点
优点:效率高
缺点:不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。
五、源码
void MeanFilater(Mat& src, Mat& dst, Size wsize) {
//判断矩阵的行列数为奇数
if (wsize.height % 2 == 0 || wsize.width % 2 == 0) {
fprintf(stderr, "Please enter odd size!");
exit(-1);
}
int hh = (wsize.height - 1) / 2;
int hw = (wsize.width - 1) / 2;
//边缘处理
Mat Newsrc;
copyMakeBorder(src, Newsrc, hh, hh, hw, hw, BORDER_REFLECT_101);//以边缘为轴,对称
dst = Mat::zeros(src.size(), src.type());
int sum1 = 0, sum2 = 0, sum3 = 0;
int average1 = 0, average2 = 0, average3 = 0;
for (int i = hh; i < src.rows + hh; i++) {
//Vec3b* src_rows_ptr = Newsrc.ptr<Vec3b>(i);
for (int j = hw; j < src.cols + hw; j++) {
for (int r = i - hh; r <= i + hh; r++) {
Vec3b* new_ptr = Newsrc.ptr<Vec3b>(r);
for (int k = j - hh; k <= j + hh; k++)
{
sum1 += new_ptr[k][0];
sum2 += new_ptr[k][1];
sum3 += new_ptr[k][2] ;
}
}
average1 = sum1 / (wsize.area());
average2 = sum2 / (wsize.area());
average3 = sum3 / (wsize.area());
Vec3b* dst_ptr = dst.ptr<Vec3b>(i - hh);
dst_ptr[j - hw][0] = average1;
dst_ptr[j - hw][1] = average2;
dst_ptr[j - hw][2] = average3;
sum1 = 0, sum2 = 0, sum3 = 0;
average1 = 0, average2 = 0, average3 = 0;
}
}
}
六、结果图
卷积核为3*3
卷积核为5*5