快速模糊算法

前段时间在网上看到一个快速模糊算法,性能很不错。

源博客:

http://www.lellansin.com/super-fast-blur-%E6%A8%A1%E7%B3%8A%E7%AE%97%E6%B3%95.html

博主对其进行了简单的bug修正以及性能优化。

在博主机子上使用该算法对一张5000x3000的图片进行模糊处理,仅需500-600毫秒,速度非常快。

代码如下:

/*

* Super Fast Blur v1.1+

* Original author: Mario Klingemann (C++ version)
* Original address: http://incubator.quasimondo.com/processing/superfastblur.pde

* C version updated by Lellansin (http://www.lellansin.com)
* C version bugfix and performance optimization by tntmonks (http://tntmonks.cnblogs.com)
*/

void superFastBlur(unsigned char *pix, unsigned int w, unsigned int h, unsigned int comp, int radius)
{
	unsigned int div;
	unsigned int wm, hm, wh;
	unsigned int *vMIN, *vMAX;
	unsigned char *r, *g, *b, *dv;
	unsigned int rsum, gsum, bsum;
	unsigned int p, p1, p2, yi, yw;

	int x, y, i, yp;
	if (radius < 1)
		return;
	wm = w - 1;
	hm = h - 1;
	wh = w * h;
	div = radius + radius + 1;
	vMIN = (unsigned int *)malloc(sizeof(unsigned int) * max(w, h));
	vMAX = (unsigned int *)malloc(sizeof(unsigned int) * max(w, h));
	r = (unsigned char *)malloc(sizeof(unsigned char) * wh);
	g = (unsigned char *)malloc(sizeof(unsigned char) * wh);
	b = (unsigned char *)malloc(sizeof(unsigned char) * wh);
	dv = (unsigned char *)malloc(sizeof(unsigned char) * 256 * div);

	for (i = 0; i < 256 * div; i++)

		dv[i] = (i / div);

	yw = yi = 0;
	for (y = 0; y < h; y++)
	{
		rsum = gsum = bsum = 0;
		for (i = -radius; i <= radius; i++)
		{
			p = (yi + min(wm, max(i, 0))) * comp;
			bsum += pix[p];
			gsum += pix[p + 1];
			rsum += pix[p + 2];
		}

		for (x = 0; x < w; x++)
		{
			r[yi] = dv[rsum];
			g[yi] = dv[gsum];
			b[yi] = dv[bsum];

			if (y == 0)
			{
				vMIN[x] = min(x + radius + 1, wm);
				vMAX[x] = max(x - radius, 0);
			}
			p1 = (yw + vMIN[x]) * comp;
			p2 = (yw + vMAX[x]) * comp;
			bsum += pix[p1] - pix[p2];
			gsum += pix[p1 + 1] - pix[p2 + 1];
			rsum += pix[p1 + 2] - pix[p2 + 2];
			yi++;
		}
		yw += w;
	}

	for (x = 0; x < w; x++)
	{
		rsum = gsum = bsum = 0;
		yp = -radius * w;
		for (i = -radius; i <= radius; i++)
		{
			yi = max(0, yp) + x;
			rsum += r[yi];
			gsum += g[yi];
			bsum += b[yi];
			yp += w;
		}

		yi = x;
		for (y = 0; y < h; y++)
		{
			pix[yi * comp] = (dv[bsum]);
			pix[yi * comp + 1] = (dv[gsum]);
			pix[yi * comp + 2] = (dv[rsum]);

			if (x == 0)
			{
				vMIN[y] = min(y + radius + 1, hm) * w;
				vMAX[y] = max(y - radius, 0) * w;
			}
			p1 = x + vMIN[y];
			p2 = x + vMAX[y];

			rsum += r[p1] - r[p2];
			gsum += g[p1] - g[p2];
			bsum += b[p1] - b[p2];
			yi += w;
		}
	} 

	free(r);
	free(g);
	free(b);
	free(vMIN);
	free(vMAX);
	free(dv);
}

  该算法进行简单的修改可作图像增强之用。

该算法还可以进一步优化,这个任务就交给各位看官咯。

时间: 2024-10-23 14:18:01

快速模糊算法的相关文章

快速堆栈模糊算法

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

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

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

Java中Map相关的快速查找算法与唯一性(转载)

原文地址:http://blog.csdn.net/chuyuqing/article/details/19629229 在对<Set和hashCode()>的一篇原创文章写完后,由于对自己的一些论断产生了模糊和怀疑,因此又对Set进行了一些研究,形成本篇. 在Set的使用场景中,我们不外乎看中了她存储数据的唯一性,即不能存储重复值,这在某些应用场合下是很必要的一个特性.那么从更深一层来考虑,Set究竟如何使数据不重复的呢?从另一个层面来考虑,她又如何确保在验证数据是否重复过程中的快速性呢?假

JAVA算法4——连通性问题之路径压缩的加权快速合并算法

能否找到一个保证线性时间性能的算法,这个问题非常难.还有一些改进加权快速合并算法的简单方法.理想情况下,我们希望每个结点直接连到其树根,但又不想像快速合并算法那样改变大量连线.我们可以简单地把所检查的所有结点连到根上,从而接近理想情况.我们可以很容易地实现此方法,方法名为压缩路径,在合并操作时,经过每条路径就加一条连线,也就是把一路上遇到的对应于每个顶点的id数组值都设为连到树根上.净结果就是几乎完全把树变平坦了,逼近快速查找法所获得的理想状态. 还有其他许多方法来实现路径压缩下面程序实现路径压

移植StackBlur模糊算法至SDL

StackBlur是Android标配的模糊算法,这也在当时引起了一股毛玻璃热潮.IOS7就采用了此算法(这有抄袭Android之嫌,因为Android1.5就在标库中加入了此函数).算法效率很高,这也是能流畅运行在移动设备上的原因.但其只在Andorid上是标准库函数,移植版也只出现在Java上.本文带来一个在SDL上移植的StackBlur算法.运行效果基本如下图. 一眼就可以看出,毛玻璃效果与Radius有直接的关系.Radius在5时,效果与动态模糊相似,在10时,会有点马赛克的感觉,在

高维数据的快速最近邻算法FLANN

1.     简介 在计算机视觉和机器学习中,对于一个高维特征,找到训练数据中的最近邻计算代价是昂贵的.对于高维特征,目前来说最有效的方法是 the randomized k-d forest和the priority search k-means tree,而对于二值特征的匹配 multiple hierarchical clusteringtrees则比LSH方法更加有效. 目前来说,fast library for approximate nearest neighbors (FLANN)

[转]快速平方根算法

在3D图形编程中,经常要求平方根或平方根的倒数,例如:求向量的长度或将向量归一化.C数学函数库中的sqrt具有理想的精度,但对于3D游戏程式来说速度太慢.我们希望能够在保证足够的精度的同时,进一步提高速度. Carmack在QUAKE3中使用了下面的算法,它第一次在公众场合出现的时候,几乎震住了所有的人.据说该算法其实并不是Carmack发明的,它真正的作者是Nvidia的Gary Tarolli(未经证实). // // 计算参数x的平方根的倒数 // float InvSqrt (float

稀疏矩阵的普通转置与快速转置算法

稀疏矩阵的普通转置与快速转置算法 一般来说,对于系数矩阵,我们使用三元组来存储.即就是将矩阵的所有非零元素的三元组存放在一个顺序表中,如图所示: 注意一个转置的前提:该顺序表是排好序的,即行优先,列其次. 一.普通转置 这种算法比较简单,也很容易想到: 算法思想: 对M.data从头至尾扫描: ?第一次扫描时,将M.data中列号为1的三元组赋值到T.data中 ?第二次扫描时,将M.data中列号为2的三元组赋值到T.data中 ?依此类推,直至将M.data所有三元组赋值到T.data中 代

hdu oj 1061 Rightmost Digit (快速幂算法)

这里首先要讲解一下快速幂算法: 快速幂取模算法 在网站上一直没有找到有关于快速幂算法的一个详细的描述和解释,这里,我给出快速幂算法的完整解释,用的是C语言,不同语言的读者只好换个位啦,毕竟读C的人较多~ 所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余).在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快.计算范围更大的算法,产生了快速幂取模算法.[有读者反映在讲快速幂部分时有点含糊,所以在这里对本文进行了修改,作了更详细的补充,争取让更多的读者一目