1. 程式人生 > >均值濾波器的原理及實現

均值濾波器的原理及實現

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)   右側為標準均值處理結果