前段時間在網上看到一個快速均值模糊算法,性能很不錯。
源博客:
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); }
該算法進行簡單的修改可作圖像增強之用。
該算法還可以進一步優化,這個任務就交給各位看官咯。