快速高斯滤波函数[修正完善版]

原文地址:http://blog.csdn.net/markl22222/article/details/10313565

进行了修正和变量优化。原来作者的函数只支持2次方图片,这次修正了(windows的bitmap行宽是4字节对齐的)。

基本完善了,但是在某些条件下,Y方向的底边还是会出现偏差,一时找不到原因,暂且发表,希望有人能提醒一下。

函数结构我规整了一下,很清晰,很好阅读。

int gauss_blur(
	byte_t* image,	//位图数据
	int linebytes,	//位图行字节数,BMP数据在windows中是4字节对齐的。否则在处理非二次幂的图像时会有偏差
	int width,		//位图宽度
	int height,		//位图高度
	int cbyte,		//颜色通道数量
	float sigma		//高斯系数
	)
{
	int x = 0, y = 0, n = 0;
	int channel = 0;
	int srcline = 0, dstline = 0;
	int channelsize = width*height;
	int bufsize = width > height ? width + 4 : height + 4;
	float *w1 = NULL, *w2 = NULL, *imgbuf = NULL;
	int time = 0;

	#if defined(_INC_WINDOWS)
		time = GetTickCount();
	#elif defined(_CLOCK_T)
		time  = clock();
	#endif

	w1 = (float*)malloc(bufsize * sizeof(float));
	if(!w1)
	{
		return -1;
	}
	w2 = (float*)malloc(bufsize * sizeof(float));
	if(!w2)
	{
		free(w1);
		return -1;
	}
	imgbuf = (float*)malloc(channelsize * sizeof(float));
	if(!imgbuf)
	{
		free(w1);
		free(w2);
		return -1;
	}

//----------------计算高斯核---------------------------------------//
	float q  = 0;
	float q2 = 0, q3 = 0;
	float b0 = 0, b1 = 0, b2 = 0, b3 = 0;
	float B  = 0;

	if (sigma >= 2.5f)
	{
		q = 0.98711f * sigma - 0.96330f;
	}
	else if ((sigma >= 0.5f) && (sigma < 2.5f))
	{
		q = 3.97156f - 4.14554f * (float) sqrt (1.0f - 0.26891f * sigma);
	}
	else
	{
		q = 0.1147705018520355224609375f;
	}

	q2 = q * q;
	q3 = q * q2;
	b0 = (1.57825+ (2.44413f*q)+(1.4281f *q2)+(0.422205f*q3));
	b1 = (         (2.44413f*q)+(2.85619f*q2)+(1.26661f* q3));
	b2 = (                     -((1.4281f*q2)+(1.26661f* q3)));
	b3 = (                                    (0.422205f*q3));
	B = 1.0-((b1+b2+b3)/b0);

	b1 /= b0;
	b2 /= b0;
	b3 /= b0;
//----------------计算高斯核结束---------------------------------------//

<span style="white-space:pre">	</span>// 处理图像的多个通道
	for (channel = 0; channel < cbyte; ++channel)
	{
		// 获取一个通道的所有像素值,并预处理
		for(y=0; y<height; ++y)
		{
			srcline = y*linebytes;
			dstline = y*width;
			for(x=0, n=channel; x<width; ++x, n+=cbyte)
			{
				(imgbuf+dstline)[x] = float((image+srcline)[n]) + 1.0f;
			}
		}

		for (int x=0; x<width; ++x)
		{//横向处理

			w1[0] = (imgbuf + x)[0];
			w1[1] = (imgbuf + x)[0];
			w1[2] = (imgbuf + x)[0];

			for (y=0; y<height; ++y)
			{
				w1[y+3] = B*(imgbuf + x)[y*width] + (b1*w1[y+2] + b2*w1[y+1] + b3*w1[y+0]);
			}

			w2[width+0]= w1[width+2];
			w2[width+1]= w1[width+1];
			w2[width+2]= w1[width+0];

			for (int y=height-1; y>=0; --y)
			{
				(imgbuf + x)[y*width] = w2[y] = B*w1[y+3] + (b1*w2[y+1] + b2*w2[y+2] + b3*w2[y+3]);
			}
		}//横向处理

		for (y=0 ; y<height; ++y)
		{//纵向处理
			srcline = y * width;
			dstline = y * linebytes;

			//取当前行数据
			w1[0] = (imgbuf + srcline)[0];
			w1[1] = (imgbuf + srcline)[0];
			w1[2] = (imgbuf + srcline)[0];

			//正方向横向处理3个点的数据
			for (x=0; x<width ; ++x)
			{
				w1[x+3] = B*(imgbuf + srcline)[x] + (b1*w1[x+2] + b2*w1[x+1] + b3*w1[x+0]);
			}

			w2[width+0]= w1[width+2];
			w2[width+1]= w1[width+1];
			w2[width+2]= w1[width+0];

			//反方向处理
			for (x=width-1; x>=0; --x)
			{
				//(imgbuf + dstline)[x] = w2[x] = B*w1[x+3] + (b1*w2[x+1] + b2*w2[x+2] + b3*w2[x+3]);
				w2[x] = B*w1[x+3] + (b1*w2[x+1] + b2*w2[x+2] + b3*w2[x+3]);

				//存储返回数据
				(image + dstline)[x * cbyte + channel] = w2[x]-1;
			}

		}//纵向处理

		/*
		//存储处理完毕的通道
		for(int y=0; y<height; y++)
		{
			int dstline = y*linebytes;
			int srcline = y*width;
			for (int x=0; x<width; x++)
			{
				//(image + dstline)[x * cbyte + channel] = (imgbuf + srcline)[x]-1;
					//byte_comp((imgbuf + srcline)[x]-1);

			}
		}//存储循环
		//*/
	}//通道循环

	free (w1);
	free (w2);
	free(imgbuf);

	#if defined(_INC_WINDOWS)
		return GetTickCount() - time;
	#elif defined(_CLOCK_T)
		return clock() - time;
	#else
		return 0;
	#endif
}

快速高斯滤波函数[修正完善版]

时间: 2024-10-13 12:02:43

快速高斯滤波函数[修正完善版]的相关文章

快速高斯滤波

高斯滤波器是图像处理中经常用到的滤波器,其滤波核函数为: 为简单起见,这里省略了归一化因子. 由的可分离特性: 得: 其中为输入图像,为输出图像,为滤波模板半径.根据准则,通常使. 由上式可见,我们可以将二维高斯滤波分解为两次一维高斯滤波. 对于二维高斯滤波,设图像大小,高斯模板大小,处理每个像素点需要次操作,则算法复杂度.若使用一维高斯核先对图像逐行滤波,再对中间结果逐列滤波,则处理每个像素需要次操作,算法复杂度,随着滤波模板尺寸的增大,算法优势越明显. 程序: #include "stdaf

Opencv学习(1):高斯滤波

快乐虾@http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 本文适用于opencv3.0.0, vs2013 Opencv中提供了高斯滤波函数: /** @brief Blurs an image using a Gaussian filter. The function convolves the source image with the specified Gaussian kernel. In-place filtering is support

数学之路-python计算实战(18)-机器视觉-滤波去噪(双边滤波与高斯滤波 )

高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到.高斯滤波的具体操作是:用一个模板(或称卷积.掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值. #滤波去噪 lbimg=cv2.GaussianBlur(newimg,(3,3),1.8) cv2.imshow('src',newimg) cv2.imshow('dst',lbimg) cv2.waitKey() cv2.destroyAllW

图像滤波之高斯滤波介绍

1 高斯滤波简介 了解高斯滤波之前,我们首先熟悉一下高斯噪声.高斯噪声是指它的概率密度函数服从高斯分布(即正态分布)的一类噪声.如果一个噪声,它的幅度分布服从高斯分布,而它的功率谱密度又是均匀分布的,则称它为高斯白噪声.高斯白噪声的二阶矩不相关,一阶矩为常数,是指先后信号在时间上的相关性,高斯白噪声包括热噪声和散粒噪声. 高斯滤波器是一类根据高斯函数的形状来选择权值的线性平滑滤波器.高斯平滑滤波器对于抑制服从正态分布的噪声非常有效.一维零均值高斯函数为: g(x)=exp( -x^2/(2 si

图像平滑技术之盒滤波、均值滤波、中值滤波、高斯滤波、双边滤波的原理概要及OpenCV代码实现

图像平滑是指直接对源图像的每个像素数据做邻域运算以达到平滑图像的目的.实质上主要就是通达卷积核算子实现的,卷积核算子的相关知识大家可以参考我写的博文http://blog.csdn.net/wenhao_ir/article/details/51691410 图像平滑也称为模糊或滤波,是图像处理中常用的技术之一,进行平滑处理时需要用到滤波器核(其实就是卷积核算子),根据滤波器核函数来实现不同的滤波技术.下面介绍几种 常用的图像平滑方法的大概原理及OpenCV下的实现代码. 一.盒滤波(均值滤波)

【3.15】matlab 高斯滤波,快速滤波

Gauss滤波快速实现方法(转) 二维高斯函数具有旋转对称性,处理后不会对哪一个方向上的边缘进行了过多的滤波,因此相对其他滤波器,具有无法比拟的优越性.但是传统Gauss滤波随着图像尺寸的增加,运算复杂度呈平方上涨,因此需要对其优化改进.下面,分别介绍传统型,分解型和递归迭代型三种实现方法. 1 传统型 Gauss滤波首先需要构建一个Gauss滤波核,公式为: Matlab实现代码: dSigma =0.8; fK1=1.0/(2*dSigma*dSigma); fK2=fK1/pi; iSiz

学习 opencv---(7) 线性邻域滤波专场:方框滤波,均值滤波,高斯滤波

本篇文章中,我们一起仔细探讨了OpenCV图像处理技术中比较热门的图像滤波操作.图像滤波系列文章浅墨准备花两次更新的时间来讲,此为上篇,为大家剖析了"方框滤波","均值滤波","高斯滤波"三种常见的邻域滤波操作.而作为非线性滤波的"中值滤波"和"双边滤波",我们下次再分析. 因为文章很长,如果详细啃的话,或许会消化不良.在这里给大家一个指引,如果是单单想要掌握这篇文章中讲解的OpenCV线性滤波相关的三个函

SIFT四部曲之——高斯滤波

本文为原创作品,未经本人同意,禁止转载 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和http://www.cnblogs.com/xujianqing/ 或许网络上有各位牛人已经对sift算法进行各种的详解和说明,我(小菜鸟)在翻阅各种资料和对opencv中的代码进行反推之后,终于理解该算法.并记录之,供大家一起交流学习!这个博文主要记录了我的学习历程,或许对你有帮助,或许可以启发你,或许你只是一笑而过!没关系,至少自己总结过. 这篇文章主要是对sif

灰度图像--图像增强 平滑之均值滤波、高斯滤波

学习DIP第30天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些论坛转载后,图像无法正常显示,无法正常表达本人观点,对此表示很不满意.有些网站转载了我的博文,很开心的是自己写的东西被更多人看到了,但不开心的是这段话被去掉了,也没标明转载来源,虽然这并没有版权保护,但感觉还是不太好,出于尊重文章作者的劳动,转载请标明出处!!!! 文章代码已托管,欢迎共同开发:https://github.com/Tony-Tan/DIPpro