使用 Java 的图像比较技术
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4328187/
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
Image Comparison Techniques with Java
提问by Flynn
I'm looking for several methods to compare two images to see how similar they are. Currently I plan to have percentages as the 'similarity index' end-result. My program outline is something like this:
我正在寻找几种方法来比较两个图像以查看它们的相似程度。目前我计划将百分比作为“相似指数”的最终结果。我的程序大纲是这样的:
- User selects 2 images to compare.
- With a button, the images are compared using several different methods.
- At the end, each method will have a percentage next to it indicating how similar the images are based on that method.
- 用户选择 2 张图像进行比较。
- 通过一个按钮,可以使用几种不同的方法比较图像。
- 最后,每种方法旁边都会有一个百分比,指示基于该方法的图像的相似程度。
I've done a lot of reading lately and some of the stuff I've read seems to be incredibly complex and advanced and not for someone like me with only about a year's worth of Java experience. So far I've read about:
我最近读了很多书,我读过的一些东西似乎非常复杂和先进,而不适合像我这样只有大约一年 Java 经验的人。到目前为止,我已经阅读了:
The Fourier Transform- im finding this rather confusing to implement in Java, but apparently the Java Advanced Imaging API has a class for it. Though I'm not sure how to convert the output to an actual result
SIFT algorithm- seems incredibly complex
Histograms- probably the easiest out of all mentioned so far
Pixel grabbing- seems viable but if theres a considerable amount of variation between the two images it doesn't look like it's going to produce any sort of accurate result. I might be wrong?
傅立叶变换- 我发现这在 Java 中实现相当混乱,但显然 Java Advanced Imaging API 有一个类。虽然我不确定如何将输出转换为实际结果
SIFT 算法- 看起来非常复杂
直方图- 可能是迄今为止提到的最简单的
像素抓取- 似乎可行,但如果两个图像之间存在相当大的差异,它看起来不会产生任何准确的结果。我可能错了?
I also have the idea of pre-processing an image using a Sobel filter first, then comparing it. Problem is the actual comparing part.
我也有先使用 Sobel 过滤器预处理图像的想法,然后再进行比较。问题是实际的比较部分。
So yeah I'm looking to see if anyone has ideas for comparing images in Java. Hoping that there are people here that have done similar projects before. I just want to get some input on viable comparison techniques that arent too hard to implement in Java.
所以是的,我想看看是否有人有在 Java 中比较图像的想法。希望这里有做过类似项目的人。我只想就可行的比较技术获得一些输入,这些技术在 Java 中实现起来并不难。
Thanks in advance
提前致谢
回答by bjoernz
- Fourier Transform - This can be used to efficiently can compute the cross-correlation, which will tell you how to align the two images and how similar they are, when they are optimally aligned.
- Sift descriptors - These can be used to compare local features. They are often used for correspondence analysis and object recognition. (See also SURF)
- Histograms - The normalized cross-correlation often yields good results for comparing images on a global level. But since you are just comparing color distributions you could end up declaring an outdoor scene with lots of snow as similar to an indoor scene with lots of white wallpaper...
- Pixel grabbing - No idea what this is...
- 傅立叶变换 - 这可用于有效地计算互相关,这将告诉您如何对齐两个图像以及它们在最佳对齐时的相似程度。
- 筛选描述符 - 这些可用于比较局部特征。它们通常用于对应分析和对象识别。(另见冲浪)
- 直方图 - 归一化互相关通常会在全局级别比较图像时产生良好的结果。但是,由于您只是在比较颜色分布,因此最终可能会将有大量雪的室外场景与具有大量白色壁纸的室内场景相似...
- 像素抓取 - 不知道这是什么......
You can get a good overview from this paper. Another field you might to look into is content based image retrieval (CBIR).
你可以从这篇论文中得到一个很好的概述。您可能要研究的另一个领域是基于内容的图像检索 (CBIR)。
Sorry for not being Java specific. HTH.
很抱歉不是特定于 Java 的。哈。
回答by mpenkov
As a better alternative to simple pixel grabbing, try SSIM. It doesrequire that your images are essentially of the same object from the same angle, however. It's useful if you're comparing images that have been compressed with different algorithms, for example (e.g. JPEG vs JPEG2000). Also, it's a fairly simple approach that you should be able to implement reasonably quickly to see some results.
作为简单像素抓取的更好替代方案,请尝试SSIM。但是,它确实要求您的图像本质上是从同一角度拍摄的同一对象。例如,如果您要比较使用不同算法压缩的图像(例如 JPEG 与 JPEG2000),它会很有用。此外,这是一种相当简单的方法,您应该能够合理快速地实施以查看一些结果。
I don't know of a Java implementation, but there's a C++ implementation using OpenCV. You could try to re-use that (through something like javacv) or just write it from scratch. The algorithm itself isn't that complicated anyway, so you should be able to implement it directly.
我不知道 Java 实现,但有一个使用 OpenCV的C++ 实现。您可以尝试重新使用它(通过诸如javacv 之类的东西)或从头开始编写它。无论如何,算法本身并不复杂,因此您应该能够直接实现它。