均值滤波

均值滤波

 

一、目的与原理

(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

 

 

 

 

posted @ 2021-04-28 10:31  will-z  阅读(797)  评论(0编辑  收藏  举报