zoukankan      html  css  js  c++  java
  • 快速均值模糊算法

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

    源博客:

    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);
    }
    

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

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

  • 相关阅读:
    Java IO(三)
    Java IO(二)
    Java IO(一)
    Java操作属性文件与国际化
    Java集合详解二
    Java集合详解一
    Spring官方文档翻译(转)
    S2SH整合
    NX二次开发-UFUN获取图纸视图最大边界和视图中心点UF_DRAW_ask_view_borders
    已知两点计算直线的向量
  • 原文地址:https://www.cnblogs.com/cpuimage/p/4898578.html
Copyright © 2011-2022 走看看