数字图像处理----深入理解高斯滤波器

——————————————————————————————————————————————————————


多学习理论,算法,API函数实现都简单!重要的是思想和算法!


——————————————————————————————————————————————————————

高斯滤波器

        前面我们介绍了线性滤波器中的均值滤波器和加权均值滤波器。如果根据高斯函数选择权值的线性平滑滤波器就是高斯滤波器。高斯平滑滤波器对抑制服从正态分布的噪声很有效。

二维高斯函数(期望值是:0,标准差是:sigma)


高斯滤波器系数

如何计算滤波器的系数呢?我们举一个例子:5*5的卷积核中建立一个坐标系:
注意:为了方便的定位卷积核的中心,最好选择奇数卷积核。
每个格子中的值对应高斯函数中的(x ,y),根据高斯函数求出对应点的系数值。

 

高斯滤波器系数C++代码详细解析

根据高斯函数,可以很方便的写出代码,其中一个小小的难点就是:代码中的矩阵都是(0,0),(0,1).....(4,4),怎么转化为表格中的(-2,-2),(-1,2)....(2,-2)呢?我们可以写出 3*3的卷积核并且标出每个格子中的数字,可以发现:我们把程序中的格子中的值减去中心的值就是我们需要的卷积核需要的。

在程序中的 center_x 和 center_y 就是确定卷积核的中心坐标。

完整的程序
#include <stdio.h>
#include <iostream>
#include <windows.h>
#include <math.h>
using namespace std;
#define  PI      3.141592653
#define  sigma   1            //标准差值
#define  n       3            //卷积核(奇数)

void GetGaussianKernal()
{
    double temp = 0;
    double h_sum = 0;  //归一化的总值
    double distance = 0;
    double kernal[n][n];
    int center_x = n/2,center_y = n/2;
    cout<<"未归一化的值:"<<endl;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
            {
                distance = (i-center_x)*(i-center_x)+(j-center_x)*(j-center_x);  
                temp = exp(-(distance)/(2*sigma*sigma))/(2*PI*sigma*sigma);
                kernal[i][j] = temp;
                h_sum += temp;
                printf("%0.10f  ",temp);
            }
       cout<<endl;
    }
    cout<<endl;
    cout<<"h_sum Value:"<<h_sum<<endl;
    cout<<endl;
    cout<<"归一化的值:"<<endl;
    for(int i=0; i<n; i++)
     {
       for(int j=0; j<n; j++)
         {
            kernal[i][j] /= h_sum;
            printf("%0.10f  ",kernal[i][j]);
         }
        cout<<endl;
     }
}

int main()
{
   GetGaussianKernal();
   system("pause");
   return 0;
}

高斯滤波器算法1完整实现

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

using namespace cv;
using namespace std;

#define n	5
#define sigma   1
#define PI      3.14125

void GaussianFilter(Mat &src, Mat &dst,double* ker)
{
	dst = src.clone();
	int row = dst.rows;
	int col = dst.cols;
	int channal = dst.channels();
	int ncol = col * channal;
	int k = n/2;
	double sum ;
	int index;
	   for (int i = k; i < (row-k) ; i++) //n/2保证边缘的像素点不被处理
	  {
		uchar* ptdst = dst.ptr<uchar>(i);
		for (int j = channal*k;j < (ncol-channal*k); j++)  //n/2保证边缘的像素点不被处理
		{
			sum = index = 0;
			for (int kx = (i-k);kx <= i+k; kx++) //内层 kx、ky循环求和
			{
				uchar* ptrsrc = src.ptr<uchar>(kx);
				for (int ky = (j-channal*k);ky <=(j+channal*k); ky = (ky+channal))
						sum += (ptrsrc[ky]*ker[index++]);	
			}

			ptdst[j] =saturate_cast<uchar>(sum);
		}
	 }
}

void GetGaussianKernal(double* nkernal)
{
	double temp = 0;
	double h_sum = 0;
	double distance = 0;
	double kernal[n][n];
	int center_x = n/2,center_y = n/2;
	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			distance = (i-center_x)*(i-center_x)+(j-center_x)*(j-center_x);
			temp = exp(-(distance)/(2*sigma*sigma))/(2*PI*sigma*sigma);
			kernal[i][j] = temp;
			h_sum += temp;
		}
	}
	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			kernal[i][j] /= h_sum;
			nkernal[n*i+j] = kernal[i][j];
		}
	}
}
int main()
{
	Mat src, dst,dst1;
	int index = 0;
	double nkernal[n*n];
	src = imread("D:/Lena.jpg");
	namedWindow("Win1");
	imshow("Win1", src);
	GetGaussianKernal(nkernal);
	for (int i=0;i<n*n;i++)
		printf("%0.10f ",nkernal[index++]);
	GaussianFilter(src,dst1,nkernal);
	namedWindow("Win2");
	imshow("Win2", dst1);
	GaussianBlur(src,dst,Size(5,5),0,0);
	namedWindow("Win3");
	imshow("Win3", dst);
	waitKey(0);
	return 0;
}
彩色图像处理结果


灰度图像处理的结果



高斯滤波器算法2完全实现

降低时间复杂度!


参考:
http://blog.csdn.net/iverain/article/details/42678133
http://lps-683.iteye.com/blog/2251180
http://blog.csdn.net/tianguokaka/article/details/6318136
冈萨雷斯的数字图像处理
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值