快速高斯模糊

以前写过两篇关于快速高斯滤波的文章,但是代码都没写完整。

算法来源及介绍请参考博主Imageshop的博文http://www.cnblogs.com/Imageshop/archive/2013/01/07/2849782.html

为了避免需要的朋友在看我的文章时过于浪费时间,所以删除前两篇文章,重写此篇目的为需要的朋友提供有用的信息。

下面给出的是功能完整的 c代码,下面代码无论是格式还是速度都可以进一步优化,请自行处理

/****************************************
* src    : 原始图像数据                 *
* dst    : 模糊后图像数据               *
* width  : 图像宽                       *
* height : 图像高                       *
* stride : 图像每一行字节数		        *
* chan   : 图像通道数                   *
* sigma  : 高斯参数                     *
* chan   : 图像通道数                   *
*****************************************/
void IMG_GaussBlur(unsigned char* src, unsigned char* dst, int width, int height, int stride, int chan, float sigma)
{
    int i = 0;
	int h,w;
    int row	= 0;
    int col	= 0;
    int pos	= 0;
    int channel	= 0;
    int n = 0;
    int bufsize = 0;
    int size = 0;
    int rowstride = 0;
    int itemp0 = 0;
    int itemp1 = 0;
    float temp = 0;
	float fTab[256] = {0};
	unsigned char* ps;
	float *pIn;

	int blurH = height+3;
	int blurW = width+3;
	for (i=0; i<256; i++)
	{
		fTab[i] = i+1;
	}

    int    channelsize = width*height+(width+height)*6;

    if (width>height)
    {
        bufsize = width+6;
    }
    else
    {
        bufsize = height+6;
    }    

    float* w1	= (float *) malloc (bufsize * sizeof (float));
    float *w2	= (float *) malloc (bufsize * sizeof (float));
    float *in	= (float *) malloc (channelsize * sizeof (float));
    float *out	= (float *) malloc (channelsize * sizeof (float));

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

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

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

    //加速方法 减少循环多次/b0
    b1 /= b0;
    b2 /= b0;
    b3 /= b0;

//----------------计算高斯核结束---------------------------------------//
    // 处理图像的多个通道
    for (channel = 0; channel < chan; channel++)
    {
		// 获取一个通道的所有像素值
		pIn = in;
		for (h=0; h<height; h++)
		{
			ps = src + h*stride;
			for (w=0;w<width;w++)
			{
				/* 0-255 => 1-256 */
				*pIn++ = fTab[ps[channel]];

				if (w==width-1)
				{
					*pIn++ = fTab[ps[channel]];
					*pIn++ = fTab[ps[channel]];
					*pIn++ = fTab[ps[channel]];
				}
				ps+=chan;
			}
		}
		memcpy(in+(height)*(width+3), in+(height-1)*(width+3), (width+3)*sizeof(float));
		memcpy(in+(height+1)*(width+3), in+(height-1)*(width+3), (width+3)*sizeof(float));
		memcpy(in+(height+2)*(width+3), in+(height-1)*(width+3), (width+3)*sizeof(float));

        //纵向处理
		size        = blurW;
		bufsize     = size+3;
		size        -= 1;
        for (row=0 ;row < blurH; row++)
        {
            pos	  = row * blurW;
			temp  = (in + pos)[0];
            w1[0] = temp;
            w1[1] = temp;
            w1[2] = temp;

            for ( i = 0 , n=3; i <= size ; i++, n++)
            {
                w1[n] = (float)(B*(in + pos)[i] +    ((b1*w1[n-1] +     b2*w1[n-2] + b3*w1[n-3] )));
            }

            temp =  w1[size+3];
            w2[size+1]= temp;
            w2[size+2]= temp;
            w2[size+3]= temp;
            for (i = size, n = i; i >= 0; i--, n--)
            {
                 (out + pos)[i] = w2[n] = (float)(B*w1[n] +    ((b1*w2[n+1] +    b2*w2[n+2] + b3*w2[n+3] )));
            }
        }    

        //横向处理
		size        = blurH;
		rowstride   = blurW;
		bufsize     = size+3;
		size        -= 1;
        for (col=0; col < blurW; col++)
        {
			temp  = (out + col)[0];
            w1[0] = temp;
            w1[1] = temp;
            w1[2] = temp;
            for ( i = 0 , n=3; i <= size ; i++, n++)
            {
                w1[n] = (float)(B*(out + col)[i*rowstride] + ((b1*w1[n-1] + b2*w1[n-2] + b3*w1[n-3] )));
            }

            temp        = w1[size+3];
            w2[size+1]    = temp;
            w2[size+2]    = temp;
            w2[size+3]    = temp;
            for (i = size, n = i; i >= 0; i--, n--)
            {
                (in + col)[i * rowstride] =w2[n]= (float)(B*w1[n] +  ((b1*w2[n+1] + b2*w2[n+2] + b3*w2[n+3] )));
            }
        }

        //修正偏移的拷贝方法
        for(int y=0; y<height; y++)
        {
            ps = dst+ y*stride;
            itemp1 = (y+3)*blurW;                                // +3
            for (int x=0; x<width; x++)
            {
				ps[channel] = in[itemp1+x+3]-1;
				ps+=chan;
            }
        }
    }

    free (w1);
    free (w2);
    free (in);
    free (out);
}

调用参考

IplImage* src = cvLoadImage("./test.jpg", 1);
IplImage* dst = cvLoadImage("./test.jpg", 1);

IMG_GaussBlur((unsigned char*)src->imageData,
              (unsigned char*)dst->imageData,
              src->width, src->height,
              src->widthStep,
              src->nChannels, 2);
时间: 2024-10-10 16:06:56

快速高斯模糊的相关文章

快速高斯模糊[剪裁版]

高斯模糊函数的升级版本,带剪裁区域. 函数check_rect()是处理剪裁区域矩形.如果不打算剪裁,只需要设置left, top, right, bottom都为0就可以了:另外位图的存储格式是上下反转的,如果正常剪裁的话,只需要设置bottom为 -bottom即可. bool check_rect(int width, int height, int& left, int& top, int& right, int& bottom) { if(!left &&

快速堆栈模糊算法

上一篇快速高斯模糊的原作者也有另一个比较快速的模糊算法Stack Blur,字面意思为堆栈模糊. 源地址为:http://incubator.quasimondo.com/processing/fast_blur_deluxe.php 这个算法在多个平台上都有实现,安卓以及IOS,JS等. processing源码:http://incubator.quasimondo.com/processing/stackblur.pde 效果图: 转为C语言实现版本. 代码如下: // Stack Blu

传统高斯模糊与优化算法(附完整C++代码)

高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次.这种模糊技术生成的图像,其视觉效果就像是经过一个半透明屏幕在观察图像,这与镜头焦外成像效果散景以及普通照明阴影中的效果都明显不同.高斯平滑也用于计算机视觉算法中的预先处理阶段,以增强图像在不同比例大小下的图像效果(参见尺度空间表示以及尺度空间实现). 从数学的角度来看,图像的高斯模糊过程就是图像与

最快速的“高斯”模糊算法(附Android源码)

? 这是一个外国人的算法,本人是搬运工.参考:http://blog.ivank.net/fastest-gaussian-blur.html ? 1:高斯模糊算法(参考:http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html) 所谓的模糊算法就是当前像素点和周围像素点进行加权均值之后的结果替换当前像素值.因此均值模糊是最简单的,只要将周围的像素点相加取平均值即可. ????而高斯模糊则是将周围的像素点的权值按照高斯分布进行取值,即根据

移动端UI设计越来越流行的高斯模糊(Gaussian blur)和毛玻璃效果(磨砂效果),如何使用Android RenderScript简单实现?

高斯模糊(Gaussian blur)和毛玻璃效果(亦称磨砂效果),近两年在移动端的UI设计上越来越流行,特别是iOS手机上出现的较多,iOS系统也提供了相应的API帮助开发人员分分钟实现这两个效果.而Android系统则经历了一个漫长的探索过程,对图片的处理,从Java算法到NDK方式实现等,各种摸索层出不穷. 值得欣慰的是,Google终于在API 11中引入了 RenderScript ,一个强大的图片处理框架,帮助Android开发人员专注于图片处理算法而不是API的调度工作.使用Ren

图像处理之卷积---任意卷积核的快速实现

卷积其实是图像处理中最基本的操作,我们常见的一些算法比如:均值模糊.高斯模糊.锐化.Sobel.拉普拉斯.prewitt边缘检测等等一些和领域相关的算法,都可以通过卷积算法实现.只不过由于这些算法的卷积矩阵的特殊性,一般不会直接实现它,而是通过一些优化的手段让计算量变小.但是有些情况下卷积矩阵的元素值无甚规律或者有特殊要求,无法通过常规手段优化,这个时候只能通过原始的方式实现.因此,如何快速的实现图像的任意卷积矩阵操作也有必要做适当的研究. 目前,通过友人共享或自己搜索找到的一片关于任意核算法优

iOS开发探索-高斯模糊&amp;毛玻璃效果

iOS开发中有的时候需要将图片设置模糊,来实现特定的效果获取更好的用户体验, iOS7之后半透明模糊效果得到大范围使用的比较大,现在也可以看到很多应用局部用到了图片模糊效果,可以通过高斯模糊和毛玻璃效果达到图片模糊效果. 左边玻璃右边模糊 高斯模糊效果 1. CoreImage: iOS5.0之后就出现了Core Image的API,Core Image的API被放在CoreImage.framework库中, 在iOS和OS X平台上,Core Image都提供了大量的滤镜(Filter),在

Photoshop新手攻略:26步快速掌握ps应用的基础工具

[新手干货教程]很多初学者面对Photoshop这个庞然大物,第一直观感受是不知道从何下手.那么多工具,学完这个忘那个,有木有什么教程可以一次性学完呢?因此,今天E学堂给大家分享这个教程,只要童鞋们打起精神来,两个小时就可以搞懂基础的工具使用!绝对是新手速成Photoshop的一个好机会!赶紧来学习! 教程很有意思,从A——Z 依次讲解每个工具的使用,精辟彻底,不拖泥带水呦. ? 3D面板:作为Adobe Photoshop Extended的一部分,你可以在Adobe Photoshop CC

【如何快速的开发一个完整的 iOS 直播 app】(美颜篇)

来源:袁峥Seemygo 链接:http://www.jianshu.com/p/4646894245ba 前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,美颜功能是很重要的,如果没有美颜功能,可能分分钟钟掉粉千万,本篇主要讲解直播中美颜功能的实现原理,并且实现美颜功能. 利用GPUImage处理直播过程中美颜的流程 采集视频 => 获取每一帧图片 => 滤镜处理 => GPUImageView展示 美颜原