均值滤波器的原理及实现

时间:2024-03-12 11:56:44

1.均值滤波器

平滑线性空间滤波器的输出是包含在滤波器模板邻域内的像素的简单平均值,也就是均值滤波器。均值滤波器也是低通滤波器,均值滤波器很容易理解,即把邻域内的平均值赋给中心元素。

均值滤波器用来降低噪声,均值滤波器的主要应用是去除图像中的不相关细节,不相关是指与滤波器的模板相比较小的像素区域。模糊图片以便得到感兴趣物体的粗略描述,因此那些较小的物体的灰度就会与背景混合在一起,较大的物体则变的像斑点而易于检测。模板的大小由那些即将融入背景中的物体尺寸决定。

均值滤波器的缺点是存在着边缘模糊的问题。

均值滤波器的模板由标准像素平均和加权平均之分。如下图所示

2 C++实现均值滤波器

#include <iostream>
#include<opencv2/opencv.hpp>

void getCount(double *count,int dim)
{
	int mn=dim*dim;
	for(int i=0;i<dim*dim;i++){
		count[i]=1.0/mn;
	}
}

void getCountWeight(double *count,int dim)
{
    int mn=dim*dim;
    for(int i=0;i<mn;i++){
        if(i==mn/2)
            count[i]=1./2;
        else
            count[i]=(1/2.)*(1./(mn-1));
    }
}

void meanFilter(cv::Mat &dst,cv::Mat &img,int dim){
    int channels=img.channels();
    dst=cv::Mat::zeros(img.size(),img.type());
	double count[dim*dim]={0};
	getCountWeight(count,dim);
    for(int row=0;row<img.rows;row++){
        for(int col=0;col<img.cols;col++){
            if(row>=dim/2&&row<img.rows-dim/2&&col>=dim/2&&col<img.cols-dim/2){
            int c=0;
            double sum1=0;
            double sum2=0;
            double sum3=0;
            for(int i=row-dim/2;i<=row+dim/2;i++){
                for(int j=col-dim/2;j<=col+dim/2;j++){
                    if(channels==1){
                        sum1+=count[c]*img.at<uchar>(i,j);
                    }
                    else if(channels==3){
                        sum1+=count[c]*img.at<cv::Vec3b>(i,j)[0];
                        sum2+=count[c]*img.at<cv::Vec3b>(i,j)[1];
                        sum3+=count[c]*img.at<cv::Vec3b>(i,j)[2];
                    }
                    c++;
                }
            }
            if(channels==1){
                dst.at<uchar>(row,col)=(int)sum1;
            }
            else if(channels==3){
                dst.at<cv::Vec3b>(row,col)[0]=(int)sum1;
                dst.at<cv::Vec3b>(row,col)[1]=(int)sum2;
                dst.at<cv::Vec3b>(row,col)[2]=(int)sum3;
            }
            }
            else {
                if(channels==1)
                    dst.at<uchar>(row, col) = img.at<uchar>(row, col);
                else if(channels==3){
                    dst.at<cv::Vec3b>(row,col)[0]=img.at<cv::Vec3b>(row,col)[0];
                    dst.at<cv::Vec3b>(row,col)[1]=img.at<cv::Vec3b>(row,col)[1];
                    dst.at<cv::Vec3b>(row,col)[2]=img.at<cv::Vec3b>(row,col)[2];
                }
            }
        }
    }
}

int main() {
	cv::Mat src=cv::imread("/home/dyf/Documents/数字图像/空间滤波器/Mean-filter/3.png",0);
	cv::Mat dst,dst1;
	cv::imshow("src",src);
	meanFilter(dst,src,3);
	cv::imshow("dst",dst);
	cv::blur(src,dst1,cv::Size(3,3));
	cv::imshow("dst1",dst1);
	cv::waitKey(0);
    return 0;
}

3 均值滤波器处理效果

原图像

下图左侧为使用标准均值方法处理的结果,右侧为opencv所带的均值滤波器处理结果

 

原图像:

左侧为带权重均值处理结果(中心位置为0.5,其他的邻域平分0.5)   右侧为标准均值处理结果