高斯滤波——数字图像处理学习五(C++版)

一、高斯滤波简介

        高斯滤波是一种线性平滑滤波,运用于图像的平滑处理,适用于消除高斯噪声。高斯噪声的概率密度函数服从高斯分布(正态分布),它是一类噪声。

        高斯滤波广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均。每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

二、高斯滤波函数

1、一维高斯分布

\LARGE G\left ( x \right )=\frac{1\frac{}{}}{ \sqrt{2\pi }\sigma }e^{\frac{-x^{2}\frac{}{}}{2\sigma ^{2}}

                     

2、二维高斯分布

\LARGE G\left ( x \right )=\frac{1\frac{}{}}{2\pi \sigma^{2} }e^{-\frac{x^{2}+y^{2}\frac{}{}}{2\sigma ^{2}}

           

三、高斯滤波性质

(1)二维高斯函数具有旋转对称性,即滤波器在各个方向上的平滑程度是相同的.一般来说,一幅图像的边缘方向是事先不知道的,因此,在滤波前是无法确定一个方向上比另一方向上需要更多的平滑.旋转对称性意味着高斯平滑滤波器在后续边缘检测中不会偏向任一方向。

(2)高斯函数是单值函数.这表明,高斯滤波器用像素邻域的加权均值来代替该点的像素值,而每一邻域像素点权值是随该点与中心点的距离单调增减的.这一性质是很重要的,因为边缘是一种图像局部特征,如果平滑运算对离算子中心很远的像素点仍然有很大作用,则平滑运算会使图像失真。

(3)高斯函数的傅立叶变换频谱是单瓣的.正如下面所示,这一性质是高斯函数付立叶变换等于高斯函数本身这一事实的直接推论.图像常被不希望的高频信号所污染(噪声和细纹理).而所希望的图像特征(如边缘),既含有低频分量,又含有高频分量.高斯函数付立叶变换的单瓣意味着平滑图像不会被不需要的高频信号所污染,同时保留了大部分所需信号。

(4)高斯滤波器宽度(决定着平滑程度)是由参数σ表征的,而且σ和平滑程度的关系是非常简单的.σ越大,高斯滤波器的频带就越宽,平滑程度就越好.通过调节平滑程度参数σ,可在图像特征过分模糊(过平滑)与平滑图像中由于噪声和细纹理所引起的过多的不希望突变量(欠平滑)之间取得折衷。

(5)由于高斯函数的可分离性,较大尺寸的高斯滤波器可以得以有效地实现.二维高斯函数卷积可以分两步来进行,首先将图像与一维高斯函数进行卷积,然后将卷积结果与方向垂直的相同一维高斯函数卷积.因此,二维高斯滤波的计算量随滤波模板宽度成线性增长而不是成平方增长。

四、高斯滤波计算

例:3*3,\large \sigma = 0.8时的高斯滤波器计算过程如下,

3*3滤波器,九个格子位置分别为(0,0)(0,1)(0,2)(1,0)(1,1)(1,2)(2,0)(2,1)(2,2),(1,1)为中心点

        然后,我们还要确保这九个点加起来为1(这个是高斯模板的特性),这9个点的权重总和等于0.9125992,因此上面9个值还要分别除以0.9125992,得到最终的高斯模板。

0.057

0.125

0.057

0.125

0.272

0.125
0.0570.1250.057

五、代码实现

1、高斯滤波器的生成

#include <iostream>
#include <cmath>
using namespace std;
double pi = 3.1415926;
void gauss(int size, double sigma, double *f)
{
	int x = size / 2;
	double sum = 0.0;
	//代入公式
	for (int i = 0; i < size; i++)
		for (int j = 0; j < size; j++)
		{
			f[i*size + j] = 1 / (2 * pi*sigma*sigma)*exp((-1) * ((i - x)*(i - x) + (j - x)*(j - x)) / (2 * sigma*sigma));
			sum = sum + f[i*size + j];//权重总和
		}
	//归一化
	for (int i = 0; i < size; i++)
	{
		for (int j = 0; j < size; j++)
		{
			f[i*size + j] = f[i*size + j] / sum;
			cout << f[i*size + j] << "    ";
		}
		cout << endl;
	}
}
int main()
{
	int size;
	cout << "请输入滤波器大小:" << endl;
	cin >> size;
	double sigma;
	cout << "请输入sigma:" << endl;
	cin >> sigma;
	double *filter = new double(size*size);
	gauss(size, sigma, filter);
	delete[]filter;
	return 0;
}

结果: 

2、利用高斯滤波器进行图像处理

如下图所示,假设有九个像素点 

11245
398
134954

 将每一个像素点乘以上3*3滤波器的权值

0.057*11=0.627

0.125*24=3

0.057*5=0.285

0.125*3=0.375

0.272*9=2.511

0.125*8=1
0.057*13=0.7410.125*49=6.1250.057*54=3.078

最后,将九个点的值都加起来就是中心点高斯模糊后的值:0.627+3+0.285+0.375+2.511+1+0.741+6.125+3.078≈18

那么,像素值为9的中心点经高斯滤波后像素值为18。

代码如下:

将1.bmp图片进行3*3,sigma=0.8的高斯滤波

void MyFrame::OnPaint()
{

	CPaintDC dc(this);

	FILE* fp;
	if (fopen_s(&fp, "C:\\Users\\Administrator\\Desktop\\BMP1\\BMP1\\1.bmp", "rb") != 0) {
		return;
	}
	bmpFileHeader bfHead;
	bmpInfoHeader biHead;
	fread_s(&bfHead, 14, 14, 1, fp);
	fread_s(&biHead, 40, 40, 1, fp);

	uchar* p1 = (uchar*)malloc(biHead.biSizeImage * sizeof(uchar));
	fseek(fp, bfHead.bfOffBits, SEEK_SET);
	fread_s(p1, biHead.biSizeImage * sizeof(uchar), biHead.biSizeImage * sizeof(uchar), 1, fp);
	
	int size = 3;
	double sigma = 0.8;
	double *f=new double(size*size);
	gauss(size, sigma, f);
	unsigned long x = 0;
	double bsum = 0;
	double gsum = 0;
    double rsum = 0;
	for (int i = 0; i < biHead.biHeight - size + 1; i++)
	{
		for(int j = 0; j < biHead.biWidth - size+1; j++)
		{
			bsum = p1[x] * f[6] + p1[x + 3] * f[7] + p1[x + 6] * f[8] + p1[3 * biHead.biWidth + x] * f[3] + p1[3 * biHead.biWidth + x + 3] * f[4] + p1[3 * biHead.biWidth + x + 6] * f[5] + p1[6 * biHead.biWidth + x] * f[0] + p1[6 * biHead.biWidth + x + 3] * f[1] + p1[6 * biHead.biWidth + x + 6] * f[2];
			x++;
			gsum = p1[x] * f[6] + p1[x + 3] * f[7] + p1[x + 6] * f[8] + p1[3 * biHead.biWidth + x] * f[3] + p1[3 * biHead.biWidth + x + 3] * f[4] + p1[3 * biHead.biWidth + x + 6] * f[5] + p1[6 * biHead.biWidth + x] * f[0] + p1[6 * biHead.biWidth + x + 3] * f[1] + p1[6 * biHead.biWidth + x + 6] * f[2];
			x++;
			rsum = p1[x] * f[6] + p1[x + 3] * f[7] + p1[x + 6] * f[8] + p1[3 * biHead.biWidth + x] * f[3] + p1[3 * biHead.biWidth + x + 3] * f[4] + p1[3 * biHead.biWidth + x + 6] * f[5] + p1[6 * biHead.biWidth + x] * f[0] + p1[6 * biHead.biWidth + x + 3] * f[1] + p1[6 * biHead.biWidth + x + 6] * f[2];
			dc.SetPixel((j + 1)/time, (biHead.biHeight - i - 1)/time, RGB(rsum, gsum, bsum));
			x++;
		}
		x = x + 3*(size-1);
	}
	delete [] f;
}

结果:

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值