最快的高斯模糊实现
image-processing
java
6
0

如何实现最快的高斯模糊算法?

我将用Java实现它,因此排除了GPU解决方案。我的应用程序planetGenesis是跨平台的,所以我不需要JNI

参考资料:
Stack Overflow
收藏
评论
共 10 个回答
高赞 时间 活跃

您应该使用高斯核是可分离的事实,即您可以将2D卷积表示为两个1D卷积的组合。

如果滤波器很大,那么使用空间域中的卷积等效于频率(傅里叶)域中的乘法这一事实也是有意义的。这意味着您可以对图像和滤镜进行傅立叶变换,将(复杂)结果相乘,然后进行傅立叶逆变换。 FFT(快速傅立叶变换)的复杂度为O(n log n),而卷积的复杂度为O(n ^ 2)。同样,如果您需要使用同一滤镜模糊许多图像,则只需对滤镜进行一次FFT。

如果您决定继续使用FFT,则FFTW库是一个不错的选择。

收藏
评论
  • 步骤1:SIMD一维高斯模糊
  • 步骤2:移调
  • 步骤3:重复步骤1

最好在小块上完成,因为全图像转置比较慢,而小块转置可以使用一连串的PUNPCKPUNPCKHBW,PUNPCKHDQ,PUNPCKHWD,PUNPCKLBW,PUNPCKLDQ,PUNPCKLWD )非常快地完成。

收藏
评论

数学笑话很可能知道这一点,但对于其他人来说。

由于高斯的数学特性很好,您可以通过首先在图像的每一行上运行一维高斯模糊,然后在每一列上运行一维模糊,来快速对2D图像进行模糊处理。

收藏
评论

在1D中:

反复使用几乎所有内核进行模糊处理都倾向于使用高斯内核。这就是高斯分布的奇妙之处,也是统计学家喜欢它的原因。因此,请选择易于模糊的内容并将其应用多次。

例如,使用盒形内核很容易模糊。首先计算一个累计和:

y(i) = y(i-1) + x(i)

然后:

blurred(i) = y(i+radius) - y(i-radius)

重复几次。

或者您可能会使用各种IIR滤波器来回移动几次,这些速度同样快。

在2D或更高版本中:

正如DarenW所说,每个维度都一个接一个地模糊。

收藏
评论

我在研究过程中为这个问题而苦苦挣扎,并尝试了一种有趣且有趣的方法来实现快速高斯模糊。首先,如前所述,最好将模糊分为两个一维模糊,但是根据实际用于像素值计算的硬件,您实际上可以预先计算所有可能的值并将它们存储在查找表中。

换句话说,预先计算Gaussian coefficient * input pixel value每个组合。当然,您需要谨慎考虑系数,但是我只想添加此解决方案。如果您拥有IEEE订阅,则可以使用查阅表进行实时特征提取,以获取快速图像模糊中的更多内容。

最终,我最终还是使用了CUDA :)

收藏
评论

最终解决方案

我对如此多的信息和实现感到非常困惑,我不知道应该信任哪一个。弄清楚之后,我决定写自己的文章。我希望它可以节省您的时间。

最快的高斯模糊(线性时间)

它包含源代码,(希望如此)源代码简短,干净并且可以轻易重写为任何其他语言。请投票,以便其他人可以看到。

收藏
评论

对于较大的模糊半径,请尝试应用三次框模糊 。这将很好地近似高斯模糊,并且比真正的高斯模糊快得多。

收藏
评论
  1. 我找到了Quasimondo:孵化器:处理:快速高斯模糊 。此方法包含许多近似值,例如使用整数和查找表,而不是浮点数和浮点除法。我不知道现代Java代码中有多少加速。

  2. 矩形上的快速阴影具有使用B样条的近似算法。

  3. C#中的快速高斯模糊算法声称具有一些很酷的优化。

  4. 而且,David Everly的Fast Gaussian Blur (PDF)具有用于Gaussian模糊处理的快速方法。

我将尝试各种方法,对其进行基准测试,然后将结果发布在此处。

出于我的目的,我从Internet复制并实现了基本(独立处理XY轴)方法和David Everly的Fast Gaussian Blur方法。它们的参数不同,所以我无法直接比较它们。但是,对于较大的模糊半径,后者经过的迭代次数要少得多。同样,后者是一种近似算法。

收藏
评论

您可能希望框模糊,这要快得多。请参阅此链接,获取出色的教程以及一些复制和粘贴C代码的信息

收藏
评论

我会考虑为此使用CUDA或其他一些GPU编程工具包,特别是如果您想使用更大的内核。否则,总会在组装中手动调整循环。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号