Java 最快的高斯模糊实现
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/98359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fastest Gaussian blur implementation
提问by Sid Datta
How do you implement the fastest possible Gaussian bluralgorithm?
你如何实现最快的高斯模糊算法?
I am going to implement it in Java, so GPUsolutions are ruled out. My application, planetGenesis, is cross platform, so I don't want JNI.
我打算用 Java 实现它,所以排除了GPU解决方案。我的应用程序PlanetGenesis是跨平台的,所以我不想要JNI。
回答by Steve Hanov
You probably want the box blur, which is much faster. See this linkfor a great tutorial and some copy & paste C code.
您可能想要框模糊,这要快得多。请参阅此链接以获取出色的教程和一些复制和粘贴 C 代码。
回答by Dana the Sane
I would consider using CUDA or some other GPU programming toolkit for this, especially if you want to use a larger kernel. Failing that, there's always hand tweaking your loops in assembly.
我会考虑为此使用 CUDA 或其他一些 GPU 编程工具包,特别是如果您想使用更大的内核。如果做不到这一点,总会在装配中手动调整您的循环。
回答by DarenW
Math jocks are likely to know this, but for anyone else..
数学运动员可能知道这一点,但对于其他任何人..
Due to a nice mathematical propertiy of the Gaussian, you can blur a 2D image quickly by first running a 1D Gaussian blur on each row of the image, then run a 1D blur on each column.
由于高斯的良好数学特性,您可以通过首先在图像的每一行上运行一维高斯模糊,然后在每列上运行一维模糊来快速模糊二维图像。
回答by Dark Shikari
- Step 1: SIMD 1-dimensional Gaussian blur
- Step 2: transpose
- Step 3: Repeat step 1
- 步骤 1:SIMD 一维高斯模糊
- 第 2 步:转置
- 第 3 步:重复第 1 步
It is best done on small blocks, as a full-image transpose is slow, while a small-block transpose can be done extremely fast using a chain of PUNPCKs(PUNPCKHBW, PUNPCKHDQ, PUNPCKHWD, PUNPCKLBW, PUNPCKLDQ, PUNPCKLWD).
最好在小块上完成,因为全图像转置很慢,而使用PUNPCK链(PUNPCKHBW、PUNPCKHDQ、PUNPCKHWD、PUNPCKLBW、PUNPCKLDQ、PUNPCKLWD)可以非常快地完成小块转置。
回答by Dima
You should use the fact that a Gaussian kernel is separable, i. e. you can express a 2D convolution as a combination of two 1D convolutions.
您应该使用高斯核是可分离的这一事实,即您可以将 2D 卷积表示为两个 1D 卷积的组合。
If the filter is large, it may also make sense to use the fact that convolution in the spatial domain is equivalent to multiplication in the frequency (Fourier) domain. This means that you can take the Fourier transform of the image and the filter, multiply the (complex) results, and then take the inverse Fourier transform. The complexity of the FFT (Fast Fourier Transform) is O(n log n), while the complexity of a convolution is O(n^2). Also, if you need to blur many images with the same filter, you would only need to take the FFT of the filter once.
如果滤波器很大,使用空间域中的卷积等效于频(傅立叶)域中的乘法这一事实也可能有意义。这意味着您可以对图像和滤波器进行傅里叶变换,将(复数)结果相乘,然后进行傅里叶逆变换。FFT(快速傅立叶变换)的复杂度为 O(n log n),而卷积的复杂度为 O(n^2)。此外,如果您需要使用相同的过滤器模糊许多图像,您只需要对过滤器进行一次 FFT。
If you decide to go with using an FFT, the FFTW libraryis a good choice.
如果您决定使用 FFT,FFTW 库是一个不错的选择。
回答by Sid Datta
I found Quasimondo : Incubator : Processing : Fast Gaussian Blur. This method contains a lot of approximations like using integers and look up tables instead of floats and floating point divisions. I don't know how much speedup that is in modern Java code.
Fast Shadows on Rectangleshas an approximating algorithm using B-splines.
Fast Gaussian Blur Algorithm in C#claims to have some cool optimizations.
Also, Fast Gaussian Blur(PDF) by David Everly has a fast method for Gaussian blur processing.
我找到了Quasimondo:孵化器:处理:快速高斯模糊。此方法包含许多近似值,例如使用整数和查找表而不是浮点数和浮点数除法。我不知道现代 Java 代码有多少加速。
Fast Shadows on Rectangles有一个使用B-splines的近似算法。
C# 中的快速高斯模糊算法声称有一些很酷的优化。
此外,David Everly 的Fast Gaussian Blur(PDF) 有一种快速的高斯模糊处理方法。
I would try out the various methods, benchmark them and post the results here.
我会尝试各种方法,对它们进行基准测试并在此处发布结果。
For my purposes, I have copied and implemented the basic (process X-Y axis independently) method and David Everly's Fast Gaussian Blurmethod from the Internet. They differ in parameters, so I couldn't compare them directly. However the latter goes through much fewer number of iterations for a large blur radius. Also, the latter is an approximate algorithm.
出于我的目的,我从互联网上复制并实现了基本(独立处理 XY 轴)方法和 David Everly 的快速高斯模糊方法。它们的参数不同,所以我无法直接比较它们。然而,对于大的模糊半径,后者经历的迭代次数要少得多。此外,后者是一种近似算法。
回答by Tom Sirgedas
回答by Paul Harrison
In 1D:
在一维中:
Blurring using almost any kernel repeatedly will tend to a Gaussian kernel. This is what's so cool about the Gaussian distribution, and is why statisticians like it. So choose something that's easy to blur with and apply it several times.
重复使用几乎任何内核进行模糊都会倾向于高斯内核。这就是高斯分布的酷炫之处,也是统计学家喜欢它的原因。所以选择容易模糊的东西并应用它几次。
For example, it's easy to blur with a box shaped kernel. First calculate a cumulative sum:
例如,使用盒形内核很容易模糊。首先计算一个累积和:
y(i) = y(i-1) + x(i)
then:
然后:
blurred(i) = y(i+radius) - y(i-radius)
Repeat several times.
重复几次。
Or you might go back and forth a few times with some variety of an IIRfilter, these are similarly fast.
或者,您可能会使用各种IIR滤波器来回切换几次,它们的速度同样快。
In 2D or higher:
在 2D 或更高版本中:
Blur in each dimension one after the other, as DarenW said.
正如DarenW所说,在每个维度中一个接一个地模糊。
回答by Ben McIntosh
I struggled with this problem for my research and tried and interesting method for a fast Gaussian blur. First, as mentioned, it is best to separate the blur into two 1D blurs, but depending on your hardware for the actual calculation of the pixel values, you can actually pre-compute all possible values and store them in a look-up table.
我在研究中一直在努力解决这个问题,并尝试了快速高斯模糊的有趣方法。首先,如前所述,最好将模糊分离为两个一维模糊,但是根据实际计算像素值的硬件,您实际上可以预先计算所有可能的值并将它们存储在查找表中。
In other words, pre-calculate every combination of Gaussian coefficient
* input pixel value
. Of course you will need to discreetize your coefficients, but I just wanted to add this solution. If you have an IEEEsubscription, you can read more in Fast image blurring using Lookup Table for real time feature extraction.
换句话说,预先计算Gaussian coefficient
* 的每个组合input pixel value
。当然,您需要离散化系数,但我只是想添加此解决方案。如果您订阅了IEEE,则可以阅读使用查找表进行实时特征提取的快速图像模糊中的更多信息。
Ultimately, I ended up using CUDAthough :)
最终,我最终还是使用了CUDA:)
回答by Ivan Kuckir
ULTIMATE SOLUTION
终极解决方案
I was very confused by so much information and implementations, I didn't know which one should I trust. After I figured it out, I decided to write my own article. I hope it will save you hours of time.
我对这么多信息和实现感到非常困惑,我不知道我应该相信哪一个。想通之后,我决定写一篇自己的文章。我希望它可以为您节省数小时的时间。
Fastest Gaussian Blur (in linear time)
It contains the source code, which (I hope) is short, clean and easily rewritable to any other language. Please vote it up, so other people can see it.
它包含源代码,(我希望)它简短、干净且易于重写为任何其他语言。请投票给它,以便其他人可以看到它。