您应该使用高斯核是可分离的事实,即您可以将2D卷积表示为两个1D卷积的组合。
如果滤波器很大,那么使用空间域中的卷积等效于频率(傅里叶)域中的乘法这一事实也是有意义的。这意味着您可以对图像和滤镜进行傅立叶变换,将(复杂)结果相乘,然后进行傅立叶逆变换。 FFT(快速傅立叶变换)的复杂度为O(n log n),而卷积的复杂度为O(n ^ 2)。同样,如果您需要使用同一滤镜模糊许多图像,则只需对滤镜进行一次FFT。
如果您决定继续使用FFT,则FFTW库是一个不错的选择。
0
您应该使用高斯核是可分离的事实,即您可以将2D卷积表示为两个1D卷积的组合。
如果滤波器很大,那么使用空间域中的卷积等效于频率(傅里叶)域中的乘法这一事实也是有意义的。这意味着您可以对图像和滤镜进行傅立叶变换,将(复杂)结果相乘,然后进行傅立叶逆变换。 FFT(快速傅立叶变换)的复杂度为O(n log n),而卷积的复杂度为O(n ^ 2)。同样,如果您需要使用同一滤镜模糊许多图像,则只需对滤镜进行一次FFT。
如果您决定继续使用FFT,则FFTW库是一个不错的选择。
0
最好在小块上完成,因为全图像转置比较慢,而小块转置可以使用一连串的PUNPCK ( PUNPCKHBW,PUNPCKHDQ,PUNPCKHWD,PUNPCKLBW,PUNPCKLDQ,PUNPCKLWD )非常快地完成。
0
数学笑话很可能知道这一点,但对于其他人来说。
由于高斯的数学特性很好,您可以通过首先在图像的每一行上运行一维高斯模糊,然后在每一列上运行一维模糊,来快速对2D图像进行模糊处理。
0
在1D中:
反复使用几乎所有内核进行模糊处理都倾向于使用高斯内核。这就是高斯分布的奇妙之处,也是统计学家喜欢它的原因。因此,请选择易于模糊的内容并将其应用多次。
例如,使用盒形内核很容易模糊。首先计算一个累计和:
y(i) = y(i-1) + x(i)
然后:
blurred(i) = y(i+radius) - y(i-radius)
重复几次。
或者您可能会使用各种IIR滤波器来回移动几次,这些速度同样快。
在2D或更高版本中:
正如DarenW所说,每个维度都一个接一个地模糊。
0
我在研究过程中为这个问题而苦苦挣扎,并尝试了一种有趣且有趣的方法来实现快速高斯模糊。首先,如前所述,最好将模糊分为两个一维模糊,但是根据实际用于像素值计算的硬件,您实际上可以预先计算所有可能的值并将它们存储在查找表中。
换句话说,预先计算Gaussian coefficient
* input pixel value
每个组合。当然,您需要谨慎考虑系数,但是我只想添加此解决方案。如果您拥有IEEE订阅,则可以使用查阅表进行实时特征提取,以获取快速图像模糊中的更多内容。
最终,我最终还是使用了CUDA :)
0
最终解决方案
我对如此多的信息和实现感到非常困惑,我不知道应该信任哪一个。弄清楚之后,我决定写自己的文章。我希望它可以节省您的时间。
它包含源代码,(希望如此)源代码简短,干净并且可以轻易重写为任何其他语言。请投票,以便其他人可以看到。
0
我找到了Quasimondo:孵化器:处理:快速高斯模糊 。此方法包含许多近似值,例如使用整数和查找表,而不是浮点数和浮点除法。我不知道现代Java代码中有多少加速。
C#中的快速高斯模糊算法声称具有一些很酷的优化。
而且,David Everly的Fast Gaussian Blur (PDF)具有用于Gaussian模糊处理的快速方法。
我将尝试各种方法,对其进行基准测试,然后将结果发布在此处。
出于我的目的,我从Internet复制并实现了基本(独立处理XY轴)方法和David Everly的Fast Gaussian Blur方法。它们的参数不同,所以我无法直接比较它们。但是,对于较大的模糊半径,后者经过的迭代次数要少得多。同样,后者是一种近似算法。
0
我会考虑为此使用CUDA或其他一些GPU编程工具包,特别是如果您想使用更大的内核。否则,总会在组装中手动调整循环。
0
如何实现最快的高斯模糊算法?
我将用Java实现它,因此排除了GPU解决方案。我的应用程序planetGenesis是跨平台的,所以我不需要JNI 。