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

时间:2009-02-27 19:30:53

标签: image image-processing fingerprint

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

最好是现有的库,但对现有算法的一些提示对我有很大帮助。

11 个答案:

答案 0 :(得分:55)

正常散列或CRC计算算法不适用于图像数据。必须考虑信息的维度性质。

如果您需要非常强大的指纹识别,以便考虑仿射变换(缩放,旋转,平移,翻转),您可以使用Radon transformation on the image source来生成图像数据的规范映射 - 将其存储在每个图像,然后比较指纹。这是一个复杂的算法,不适合胆小的人。

一些简单的解决方案是可能的:

  1. 为图像创建光度直方图作为指纹
  2. 创建每个图像的缩小版本作为指纹
  3. 将技术(1)和(2)结合成混合方法以提高比较质量
  4. 亮度直方图(尤其是分成RGB分量的直方图)是图像的合理指纹 - 并且可以非常有效地实现。从另一个直方图中减去一个直方图将产生一个新的历史图,您可以处理该历史图以确定两个图像的相似程度。直方图,因为只评估光度/颜色信息的分布和出现处理仿射变换相当好。如果将每个颜色分量的亮度信息量化为8位值,则768字节的存储空间足以满足几乎任何合理大小的图像的指纹。当操纵图像中的颜色信息时,亮度直方图产生假阴性。如果应用对比度/亮度,海报,色移,光度信息变化等变换。某些类型的图像也可能出现误报,例如风景和图像,其中单一颜色支配其他图像。

    使用缩放图像是将图像的信息密度降低到更容易比较的另一种方法。降低到原始图像大小的10%以下通常会丢失太多的信息 - 因此800x800像素图像可以缩小到80x80,并且仍然提供足够的信息来执行适当的指纹识别。与直方图数据不同,当源分辨率具有不同的宽高比时,您必须执行图像数据的各向异性缩放。换句话说,将300x800图像缩小为80x80缩略图会导致图像变形,这样当与300x500图像(非常相似)相比时,会导致漏报。当涉及仿射变换时,缩略图指纹通常也会产生假阴性。如果您翻转或旋转图像,其缩略图将与原始图像完全不同,可能会导致误报。

    结合这两种技巧是一种合理的方式来对冲你的赌注并减少误报和漏报的出现。

答案 1 :(得分:33)

与此处提出的缩小图像变体相比,它的特殊方法要少得多,这种变体保留了它们的一般风格,但它为正在发生的事情提供了更严格的数学基础。

拍摄Haar wavelet图片。基本上,Haar小波是从较低分辨率图像到每个较高分辨率图像的差异的连续性,但是根据您在mipmap的“树”中的深度加权。计算很简单。然后,一旦你对Haar小波进行了适当的加权,就扔掉除k个最大系数之外的所有系数(就绝对值而言),对矢量进行标准化并保存。

如果你取两个标准化向量的点积,它给你一个相似度量,1几乎相同。我在here上发布了更多信息。

答案 2 :(得分:18)

你一定要看看phash

对于图像比较,有 php 项目: https://github.com/kennethrapp/phasher

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

不幸的是,这是基于“bitcount”的,但会识别旋转的图像。 javascript中的另一种方法是通过画布的帮助从图像构建光度直方图。您可以在画布上可视化多边形直方图,并比较数据库中的多边形(例如mySQL空间...)

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

答案 3 :(得分:11)

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

  1. 将图片划分为多个区域。在我们的例子中,我们处理的是4:3分辨率视频,因此我们使用了12个区域。这样做可以将图像的分辨率从图像中分离出来。
  2. 对于每个区域,计算整体颜色 - 区域中所有像素的平均值
  3. 对于整个图像,计算整体颜色 - 所有区域的平均值
  4. 因此,对于每张图片,您都要存储n + 1个整数值,其中n是您要跟踪的区域数。

    对于比较,您还需要单独查看每个颜色通道。

    1. 对于整体图像,比较整体颜色的颜色通道,看它们是否在某个阈值范围内 - 比方说,10%
    2. 如果图像在阈值范围内,则接下来比较每个区域。如果所有区域都在阈值范围内,则图像足够匹配,您至少可以标记它们以进行进一步比较。
    3. 这可让您快速丢弃不匹配的图像;您还可以使用更多区域和/或递归应用算法以获得更强的匹配信心。

答案 4 :(得分:6)

与Ic的答案类似 - 您可以尝试以多种分辨率比较图像。因此每个图像保存为1x1,2x2,4x4 .. 800x800。如果最低分辨率不匹配(受阈值限制),您可以立即拒绝它。如果它匹配,您可以在下一个更高的分辨率下比较它们,依此类推..

此外 - 如果图像共享任何类似的结构,例如医学图像,您可以将该结构提取到更容易/更快比较的描述中。

答案 5 :(得分:3)

所以你想做“指纹匹配”,这与“图像匹配”完全不同。指纹分析在过去的20年中得到了深入研究,并且已经开发了几种有趣的算法来确保正确的检测率(关于 FAR FRR 措施 - < strong>错误接受率和错误拒绝率)。

我建议您更好地了解 LFA(局部特征分析)类检测技术,主要基于细节检查。细节是任何指纹的特定特征,并且已经分为几类。将光栅图像映射到细节图是大多数公共机构为犯罪分子或恐怖分子所做的事情。

有关详细参考,请参阅here

答案 6 :(得分:3)

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

要查看它的实际效果,请查看iTunes AppStore上的eyeBuy Visual Search。

答案 7 :(得分:2)

你可以这样做的一种方法是调整图像大小并显着降低分辨率(可能是200x200?),存储较小的(像素平均)版本进行比较。然后定义容差阈值并比较每个像素。如果所有像素的RGB都在公差范围内,那么你就得到了匹配。

您的初始运行是O(n ^ 2),但如果您对所有匹配进行编目,则每个新图像只是要比较的O(n)算法(您只需将其与每个先前插入的图像进行比较)。然而,随着要比较的图像列表变大,它最终会崩溃,但我认为你有一段时间是安全的。

运行400天后,您将拥有500,000张图片,这意味着(扣除缩小图片大小的时间)200(H)*200(W)*500,000(images)*3(RGB) = 60,000,000,000次比较。如果每张图片完全匹配,那么你将落后,但情况可能并非如此,对吧?请记住,只要单个比较超出阈值,您就可以将图像折扣为匹配。

答案 8 :(得分:2)

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

答案 9 :(得分:2)

截至2015年(回到未来......在2009年的问题上,现在谷歌排名很高),可以使用深度学习技术计算图像相似度。称为自动编码器的算法族可以创建可搜索相似性的矢量表示。有一个演示here

答案 10 :(得分:0)

似乎专门的图像哈希算法是一个活跃的研究领域,但是对图像字节的正常哈希计算可能会起作用。

您是在寻找与字节完全相同的图像,而不是寻找源自相同来源但可能是不同格式或分辨率的图像(这让我感到非常困难)。