均值,中值,高斯与C++实现代码(附加优化思路,双边滤波,引导滤波, non-local means原理)

消除图像的噪声成分叫作图像的平滑化或滤波操作。信号或图像的能量大部分集中在幅度谱的低频和中频段,而在较高频段,感兴趣的信息经常被噪声淹没。因此一个能降低高频成分幅度的滤波器就能够减弱噪声的影响。
图像滤波的目的有两个:一是抽出对象的特征作为图像识别的特征模式;另一个是为适应图像处理的要求,消除图像数字化时所混入的噪声。图像滤波的要求:一是不能损坏图像的轮廓及边缘等重要信息;二是使图像清晰视觉效果好。

1.本文介绍滤波器的特点

  • 均值滤波适用于随机噪声,高斯噪声不适用于椒盐噪声和爆米花噪声。是一种线性滤波,与中值滤波类似(非线性滤波)都有平滑图像的作用。但是均值滤波不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,使图像变得模糊,不能很好地去除噪声点(噪声幅度减小,但是噪声点的颗粒面积变大污染面积反而增大。)。
  • 高斯滤波器适用于消除高斯噪声,对于抑制服从正态分布的噪声非常有效 。是一种平滑线性滤波器 ,用像素邻域的加权均值来代替该点的像素值,而每一邻域像素点权值是随该点与中心点的距离单调增减的,其效果是降低图像灰度的“尖锐”变化,也就是使图像模糊了。此外其权重完全取决于图像像素之间欧氏距离,与图像的内容没有关系。
  • 中值滤波适用于椒盐噪声,爆米花噪声以及脉冲噪声。是一种非线性的滤波器,对于这类型的随机噪声,它比相同尺寸的线性滤波器引起的模糊更少,能较好的保持边缘,但会使图像中的小目标丢失,对于点、线和尖顶多的图像不宜采用中值滤波。
  • 双边滤波器的可以较好地保护图像的边缘。双边滤波比高斯滤波多了一个高斯方差,它是基于空间分布的高斯滤波函数;在边缘附近,离得较远的像素不会太多的影响到边缘上的像素值,保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,双边滤波器不能够干净的滤掉高频噪声,能够对低频信息进行较好的滤波;双边滤波在一定程度上即平滑了图像,又保持的图像边缘。虽然去噪效果很明显,但很多细节被去除只有整体形状被保留适合美颜相机磨皮
  • 引导滤波在滤波过程中加入了引导图像中(去噪时用的就是图像本身)的信息,其本质上就是通过一张引导图I,对初始图像p(输入图像)进行滤波处理,使得最后的输出图像大体上与初始图像P相似,但是纹理部分与引导图I相似
  • 非局部算法是一种基于快的匹配度来计算滤波权值的,能获得比较好的视觉效果。计算复杂度高。

2.滤波算法的边界问题

(1)不做边界处理
不对图像的边界作任何处理,在对图像进行滤波时,滤波器没有作用到图像的四周,因此图像的四周没有发生改变
(2)填充零
对图像的边界做扩展,在扩展边界中填充0,对于边长为2k+1的方形滤波器,扩展的边界大小为k,若原来的图像为[m, n],则扩展后图像变为[m+2k, n+2k]。进行滤波之后,图像会出现一条黑色的边框
3)填充最近像素值
扩展与填充0 的扩展类似,只不过填充0的扩展是在扩展部分填充0,而这个方法是填充距离最近的像素的值
(4)在边界时缩小窗的大小

3.滤波的算法介绍与代码实现以及优化算法

3.1 中值滤波

图片中一个方块区域(一般为3*3)内,中心点的像素为全部点像素的中值:

中值

c++ 代码实现:

中值滤波
int media_filter(unsigned char* inbuffer, int width, int height, unsigned char* outbuffer)
{
	int mid=0;
	int winsize = 3;//滤波窗口大小
	int* windows = new int[winsize*winsize];
	int pos = (winsize - 1) / 2;
	memcpy(outbuffer, inbuffer, width*height);
	for (int m = pos; m < height - pos; m++)
	{
		for (int n = pos; n < width - pos; n++)//(m,n)是窗口中心位置
		{
			//提取winsize*winsize的数据进入滤波窗
			int winpos = 0;
			for (int i = -pos; i < (winsize - pos); i++)
				for (int j = -pos; j < (winsize - pos); j++)
					windows[winpos++] = inbuffer[(m + i)*width + n + j];
			//对滤波窗中的数据排序取中值
			sort(windows, winsize*winsize);
			mid = windows[(winsize*winsize)/2];
			outbuffer[m*width + n] = mid;
		}
	}
	//对边界进行处理
	//参考边界处理的四种方法,目前就是不做边界处理   
	
	delete[] windows;
	windows = NULL;
	return 0;
}

快速中值滤波:(直方图统计的方法)

 

3.2 均值滤波

图片中一个方块区域(一般为3*3)内,中心点的像素为全部点像素值的平均值。均值滤波就是对于整张图片进行以上操作。

我们可以看下图进行理解:

c++ 代码:

均值滤波
int mean_filter(unsigned char* inbuffer, int width, int height, unsigned char* outbuffer)
{
	int mid=0;
	int winsize = 3;//滤波窗口大小
	int* windows = new int[winsize*winsize];
	int pos = (winsize - 1) / 2;
	memcpy(outbuffer, inbuffer, width*height);
	for (int m = pos; m < height - pos; m++)
	{
		for (int n = pos; n < width - pos; n++)//(m,n)是窗口中心位置
		{
			//提取winsize*winsize的数据进入滤波窗
			int winpos = 0;
			for (int i = -pos; i < (winsize - pos); i++)
				for (int j = -pos; j < (winsize - pos); j++)
					windows[winpos++] = inbuffer[(m + i)*width + n + j];
			mid=getaverage(windows, winsize*winsize);//对滤波窗中的数据取平均值
			outbuffer[m*width + n] = mid;
		}
	}
	//对边界进行处理
	//参考边界处理的四种方法,目前就是不做边界处理

	
	delete[] windows;
	windows = NULL;
	return 0;
}

快速均值滤波:(采用一个数组代替滑动窗口 参考博客:https://blog.csdn.net/xumengfan/article/details/80812704,也可以类似中值滤波直方图思想,更优的方法是采用积分的方法)

类似中值滤波直方图思想(https://blog.csdn.net/Kena_M/article/details/47860411):

积分图方法:

 

3.3高斯滤波

一维高斯函数:

二维高斯函数:

均值u影响正态分布的位置,在实际的图像处理中一般取0

标准差σ在图形或滤波效果上表现为:σ越大,曲线越扁平,高斯滤波器的频带就越宽,平滑程度就越好,σ越小,曲线越瘦高,高斯滤波的频带就越窄,平滑程度也越弱;

二维高斯函数具有旋转对称性,即滤波器在各个方向上的平滑程度是相同的,旋转对称性意味着高斯平滑滤波器在后续边缘检测中不会偏向任一方向;

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

高斯卷积核的尺寸越大,图像的平滑效果越好,表现为图像越模糊,同时图像细节丢失的越多;尺寸越小,平滑效果越弱,图像细节丢失越少。

C++代码:

//******************高斯卷积核生成函数*************************
void GetGaussianKernel(double **gaus, const int size,const double sigma)
{
	const double PI=4.0*atan(1.0); //圆周率π赋值
	int center=size/2;
	double sum=0;
	for(int i=0;i<size;i++)
	{
		for(int j=0;j<size;j++)
		{
			gaus[i][j]=(1/(2*PI*sigma*sigma))*exp(-((i-center)*(i-center)+(j-center)*(j-center))/(2*sigma*sigma));
			sum+=gaus[i][j];
		}
	}

	for(int i=0;i<size;i++)
	{
		for(int j=0;j<size;j++)
		{
			gaus[i][j]/=sum;
		}
	}
	return ;
}

快速度高斯滤波:将二维高斯滤波分解为两次一维高斯滤波。

高斯函数的分离特性:

(二维分解为一维,分解过程e前面的系数有问题,这不是重点)

对于二维高斯滤波,设图像大小,高斯模板大小,处理每个像素点需要次操作,则算法复杂度。若使用一维高斯核先对图像逐行滤波,再对中间结果逐列滤波,则处理每个像素需要次操作,算法复杂度,随着滤波模板尺寸的增大,算法优势越明显。

4.另外常见滤波算法的介绍

4.1 双边滤波

一种非线性的保边滤波方法,是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。双边滤波器由两个函数构成:一个函数是由几何空间距离决定滤波器系数,另一个由像素差值决定滤波器系数。双边滤波器中,输出像素的值g(i,j)依赖于邻域像素的值的加权组合:

权重系数w(i,j)取决于空域核和值域核的乘积。其中空域滤波器对空间上邻近的点进行加权平均,加权系数随着距离的增加而减少。值域滤波器则是对像素值相近的点进行加权平均,加权系数随着值差的增大而减少。

4.2 引导滤波器

引导滤波就是在滤波过程中加入引导图像中的信息,这里的引导图可以是单独的图像也可以是输入图像,当引导图为输入图像时,引导滤波就成为了一个可以保持边缘的去噪滤波操作。

4.2  NLM(Non-Local means)算法

该算法使用自然图像中普遍存在的冗余信息来去噪声。与常用的双线性滤波、中值滤波等利用图像局部信息来滤波不同的是,它利用了整幅图像来进行去噪,以图像块为单位在图像中寻找相似区域,再对这些区域求平均,能够比较好地去掉图像中存在的高斯噪声。

这个块邻域在整幅图像中移动,计算图像中其他区域跟这个块的相似度,相似度越高,得到的权重越大。最后将这些相似的像素值根据归一化之后的权重加权求和,得到的就是去噪之后的图像。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值