图像指纹比较许多图像的相似性

我需要创build许多图像的指纹(大约100.000现有,每天1000新,RGB,JPEG,最大尺寸800×800),以比较每一个图像与其他图像非常快。 我不能使用二进制比较方法,因为也应该识别几乎相似的图像。

最好是现有的图书馆,但也有一些提示现有的algorithm会帮助我很多。

正常的散列algorithm或CRC计算algorithm对图像数据不适用。 信息的尺寸性质必须考虑在内。

如果您需要非常强大的指纹识别function,例如仿射变换(缩放,旋转,平移,翻转),您可以对图像源使用Radon变换来生成图像数据的规范映射 – 将其与每个图像然后比较指纹。 这是一个复杂的algorithm,不适合心脏不好的人。

一些简单的解决scheme是可能的:

  1. 为图像创build一个光度直方图作为指纹
  2. 创build每个图像的缩小版本作为指纹
  3. 将技术(1)和(2)组合成混合方法以提高比较质量

亮度直方图(特别是被分成RGB分量的亮度直方图)对于图像而言是合理的指纹 – 并且可以相当有效地实施。 从另一个直方图中减去一个直方图将产生一个新的历史图,您可以处理这个历史图以确定两个图像的相似程度。 直方图,因为只有评估光度/颜色信息的分布和发生处理仿射变换相当好。 如果将每个颜色分量的亮度信息量化到8位值,则对于几乎任何合理大小的图像的指纹而言,768个字节的存储空间都足够了。 当图像中的颜色信息被操纵时,亮度直方图会产生误报。 如果应用对比度/亮度,色调,色彩转换等亮度信息变化。 假阳性对于某些types的图像也是可能的,例如风景和图像,其中单一颜色主宰其他图像。

使用缩放图像是另一种将图像的信息密度降低到易于比较的水平的方法。 减less到原始图像大小的10%以下通常会丢失太多的信息 – 所以800×800像素的图像可以缩小到80×80,仍然提供足够的信息来执行体面的指纹识别。 与直方图数据不同,当源分辨率具有不同的纵横比时,您必须执行图像数据的各向异性缩放。 换句话说,将300×800的图像缩小为80×80的缩略图会导致图像变形,从而与300×500的图像(非常相似)相比会造成误报。 当涉及仿射变换时,缩略图指纹也经常产生假阴性。 如果您翻转或旋转图像,其缩略图将与原始图像截然不同,并可能导致误报。

结合这两种技术是对冲你的投注的合理方法,并减less误报和漏报的发生。

有一种比现在提出的缩小的图像变体less得多的临时方法,保留了它们的总体风格,但是为正在发生的事情提供了更严格的math基础。

采取图像的哈尔小波 。 基本上Haar小波是从较低分辨率的图像到每个较高分辨率的图像的差异的连续性,但是由于在mipmap的“树”中的深度而加权。 计算很简单。 然后,一旦你有适当的哈尔小波加权,扔掉除k最大的系数(就绝对值而言),所有的向量归一化并保存。

如果你拿这两个归一化向量的点积,那么它就会给你一个与1几乎相同的度量。 我在这里发布了更多的信息。

你一定要看看phash 。

对于图像比较有这个PHP项目: https : //github.com/kennethrapp/phasher

和我的小javascript的克隆: https : //redaktorcms.com/dev/phasher/demo_js/index.html

不幸的是,这是“bitcount”为基础,但会承认旋转的图像。 javascript中的另一个方法是在canvas的帮助下从图像中构build一个亮度直方图。 你可以在canvas上可视化多边形直方图,并比较数据库中的多边形(例如mySQL空间…)

这是video直方图的演示: https : //redaktorcms.com/dev/globetrottr/testHashVideo.php

很久以前,我在一个具有类似特征的系统上工作,这是我们遵循的algorithm的近似值:

  1. 将图片分成区域。 在我们的情况下,我们正在处理4:3分辨率的video,所以我们使用了12个区域。 这样做需要源图像的分辨率。
  2. 对于每个区域,计算总体颜色 – 区域中所有像素的平均值
  3. 对于整个图像,计算总体颜色 – 所有区域的平均值

因此,对于每个图像,您存储n + 1整数值,其中n是您正在跟踪的区域的数量。

为了进行比较,您还需要分别查看每个颜色通道。

  1. 对于整体图像,比较整体颜色的颜色通道,看它们是否在一定的阈值内 – 比如10%
  2. 如果图像在阈值范围内,接下来比较每个区域。 如果所有区域都在阈值范围内,则图像足够强壮,您至less可以将其标记为进一步比较。

这使您可以快速丢弃不匹配的图像; 您还可以使用更多的区域和/或recursion地应用algorithm以获得更强的匹配可信度。

类似于IC的答案 – 你可以尝试比较多个分辨率的图像。 所以每个图像保存为1×1,2×2,4×4 .. 800×800。 如果最低分辨率不符合(以阈值为准),您可以立即拒绝。 如果匹配,则可以在下一个更高的分辨率下进行比较,依此类推。

此外,如果图像共享任何类似的结构(如医学图像),则可以将该结构抽取为比较容易/快速的描述。

或者你可以使用http://tineye.com这正是你想要的!; (检查商业API)

但我感兴趣的是他们如何做到这一点,哪些技术等…

所以你想要做的“指纹匹配”,这是不同于“图像匹配”。 指纹分析在过去的20年里已经得到了深入的研究,为了确保正确的检测率(关于FARFRR测量 – 错误接受率错误拒绝率 ),已经开发了一些有趣的algorithm。

我build议你最好看看LFA(局部特征分析)类的检测技术,大多build立在细节检查上。 细节是任何指纹的具体特征,并已被分类为几个类别。 将栅格图像映射到细节图实际上是大多数公共机构为犯罪分子或恐怖分子提供的信息。

请参阅这里进一步的参考

对于iPhone图像比较和图像相似性开发,请查看: http : //sites.google.com/site/imagecomparison/

要看到它的行动,看看iTunes AppStore eyeBuy视觉search。

你可以这样做的一种方法是调整图像大小并将分辨率显着降低(也许是200×200),存储较小的(像素平均)版本以进行比较。 然后定义容差阈值并比较每个像素。 如果所有像素的RGB都在容差范围内,则表示匹配。

你的初始运行是O(n ^ 2),但是如果你把所有匹配的目录,每个新的图像只是一个O(n)algorithm比较(你只需要比较它与每个以前插入的图像)。 但是,随着比较的图像列表变得更大,它最终会崩溃,但是我认为你已经安全了一段时间了。

200(H)*200(W)*500,000(images)*3(RGB) = 60,000,000,000个比较。在运行400天后,您将拥有500,000个图像,这意味着(缩减缩放图像的时间200(H)*200(W)*500,000(images)*3(RGB) 。 如果每一幅图像都完全匹配,那么你将会落后,但这可能不会是这样,对吧? 请记住,只要一次比较超出阈值,您就可以将图片作为匹配打折扣。

你真的想要比较每个图像与其他人吗? 什么是应用程序? 也许你只是需要某种基于某些描述符的图像索引和检索? 然后,例如,您可以查看多媒体内容描述接口的MPEG-7标准。 然后你可以比较不同的图像描述符,这将不是那么准确,但更快。

截至2015年(回到未来…在这个2009年的问题,现在在谷歌高排名)图像相似性可以计算使用深度学习技术。 称为自动编码器的algorithm家族可以创build可search相似度的vector表示。 这里有一个演示。

似乎专门的图像哈希algorithm是一个积极的研究领域,但也许是一个正常的图像字节散列计算将做的伎俩。

你是在寻找字节相同的图像,而不是寻找源自相同源的图像,但可能是一个不同的格式或分辨率(这是一个相当困难的问题)。