专栏首页一心无二用,本人只专注于基础图像算法的实现与优化。从GIMP的Retinex算法里发现了一种高斯模糊的快速实现方法【开发记录】。

从GIMP的Retinex算法里发现了一种高斯模糊的快速实现方法【开发记录】。

这段时间在研究Retinex 技术,看例程代码时翻到了GIMP的源代码,结果却找到了一种简单而又快速的高斯模糊的实现方式。

这种高斯模糊的实现同GIMP内嵌的高斯模糊算法也有所不同,并且速度上还有一定的优势,具体的代码可以参考GIMP下的contrast-retinex.c里面的代码。

GIMP自带的高斯模糊的代码在 blur-gauss里。

不过使用Retinex里的高斯模糊的代码会有一个小问题,就是多次模糊会发现图像像素整体向右下角或某个方向偏移,这个问题的解决很简单,有朋友遇到的时候在来问问,这里先卖个关子。

具体的算法论文可以再百度搜索 : Recursive Implementation of the gaussian filter.

贴一段核心代码:

static void
gausssmooth (gfloat *in, gfloat *out, gint size, gint rowstride, gauss3_coefs *c)
{
  /*
   * Papers:  "Recursive Implementation of the gaussian filter.",
   *          Ian T. Young , Lucas J. Van Vliet, Signal Processing 44, Elsevier 1995.
   * formula: 9a        forward filter
   *          9b        backward filter
   *          fig7      algorithm
   */
  gint i,n, bufsize;
  gfloat *w1,*w2;

  /* forward pass */
  bufsize = size+3;
  size -= 1;
  w1 = (gfloat *) g_try_malloc (bufsize * sizeof (gfloat));
  w2 = (gfloat *) g_try_malloc (bufsize * sizeof (gfloat));
  w1[0] = in[0];
  w1[1] = in[0];
  w1[2] = in[0];
  for ( i = 0 , n=3; i <= size ; i++, n++)
    {
      w1[n] = (gfloat)(c->B*in[i*rowstride] +
                       ((c->b[1]*w1[n-1] +
                         c->b[2]*w1[n-2] +
                         c->b[3]*w1[n-3] ) / c->b[0]));
    }

  /* backward pass */
  w2[size+1]= w1[size+3];
  w2[size+2]= w1[size+3];
  w2[size+3]= w1[size+3];
  for (i = size, n = i; i >= 0; i--, n--)
    {
      w2[n]= out[i * rowstride] = (gfloat)(c->B*w1[n] +
                                           ((c->b[1]*w2[n+1] +
                                             c->b[2]*w2[n+2] +
                                             c->b[3]*w2[n+3] ) / c->b[0]));
    }

  g_free (w1);
  g_free (w2);
}

这段代码的优化还有很大的空间, 并且高斯模糊算法很容易并行化。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SSE图像算法优化系列一:一段BGR2Y的SIMD代码解析。

         一个同事在github上淘到一个基于SIMD的RGB转Y(彩色转灰度或者转明度)的代码,我抽了点时间看了下,顺便学习了一些SIMD指令,这里把学习过程...

    用户1138785
  • 一种具有细节保留功能的磨皮算法。

         算法最近更新时间: 2014.7.19,  效果详见:http://files.cnblogs.com/Imageshop/FaceBeautific...

    用户1138785
  • 实现目前最快的半径相关类算法(附核心源码)

      我在两年前的博客里曾经写过 SSE图像算法优化系列七:基于SSE实现的极速的矩形核腐蚀和膨胀(最大值和最小值)算法 一文,通过SSE的优化把矩形核心的腐蚀...

    用户1138785
  • Viewpager循环滑动的实现

    导语 本文讲述实现ViewPager循环滑动效果的两种方案: 方案1: 复写ViewPager或者Adapter,扩展dataList,左右各加1...

    MelonTeam
  • Python 给下载文件显示进度条和下载时间的实现

    大家在下载文件时能够显示下载进度和时间非常好,其实实现它方法很简单,这里我写了个进度条的模块,其中还附带上了运行时间也就是下载时间了。

    砸漏
  • 自动化运维实践 | Ansible入门

    ssh-keyscan remore_servers >> ~./ssh/known_hosts

    小土豆Yuki
  • Spring Boot(六):如何优雅的使用 Mybatis

    这两天启动了一个新项目因为项目组成员一直都使用的是 Mybatis,虽然个人比较喜欢 Jpa 这种极简的模式,但是为了项目保持统一性技术选型还是定了 Mybat...

    纯洁的微笑
  • 为什么BAT杀不死“慢节奏”的网易? | 拔刺

    镁客网
  • 养猪的网易丁磊,背后的创业史了解下?

    丁磊,英文名William Ding,1971出生于中国浙江省宁波奉化人。丁磊出生在一个高级知识分子家庭,父亲是一名电子工程师。丁磊小时候也非常调皮,但他的调皮...

    张叔叔讲互联网
  • 堆排序

    堆排序是利用堆的特性——堆顶元素一定是这个堆的最大值或者最小值,来使选择排序中每趟选择最值变得更加高效的思路。对于堆的相关内容移步我之前的博客:堆

    AI那点小事

扫码关注云+社区

领取腾讯云代金券