Answers:
常规哈希或CRC计算算法不适用于图像数据。必须考虑信息的维度性质。
如果您需要非常鲁棒的指纹识别,从而考虑了仿射变换(缩放,旋转,平移,翻转),则可以在图像源上使用Radon变换来生成图像数据的规范映射-将其与每个图像存储在一起,然后只比较指纹。这是一个复杂的算法,并不适合胆小的人。
可能有一些简单的解决方案:
亮度直方图(尤其是分成RGB分量的直方图)是图像的合理指纹-可以非常有效地实现。从另一个直方图中减去一个直方图将产生一个新的直方图,您可以对其进行处理以确定两个图像的相似程度。直方图,因为仅评估发光度/颜色信息的分布和发生,可以很好地处理仿射变换。如果将每个颜色分量的亮度信息量化为8位值,则768字节的存储空间足以容纳几乎任何合理大小的图像指纹。当操纵图像中的颜色信息时,亮度直方图会产生假阴性。如果您应用诸如对比度/亮度,后色调,色彩偏移,亮度信息更改之类的变换。
使用缩放图像是将图像的信息密度降低到易于比较的水平的另一种方法。缩小到原始图像尺寸的10%以下通常会丢失太多信息以致无法使用-因此800x800像素的图像可以缩小到80x80,并且仍然提供足够的信息来执行不错的指纹识别。与直方图数据不同,当源分辨率的宽高比变化时,必须对图像数据执行各向异性缩放。换句话说,将300x800的图像缩小为80x80的缩略图会导致图像变形,这样,与300x500的图像(非常相似)相比,会导致假阴性。当涉及仿射变换时,缩略图指纹通常还会产生假阴性。如果您翻转或旋转图像,
结合这两种技术是一种合理的方法来对冲您的赌注并减少误报和误报的发生。
您绝对应该看看phash。
为了进行图像比较,有一个php项目:https : //github.com/kennethrapp/phasher
而我的小JavaScript克隆:https : //redaktor.me/phasher/demo_js/index.html
不幸的是,这是基于“位计数”的,但是可以识别旋转的图像。Javascript中的另一种方法是借助画布来根据图像构建亮度直方图。您可以在画布上可视化多边形直方图,并在数据库中比较该多边形(例如,mySQL空间...)
Compare()
函数,而不必先下载图像。同样,根据我的测试,“非常相似的图像”的阈值应> 90%,而不是> 98%。
很久以前,我在一个具有类似特征的系统上工作,这是我们遵循的算法的近似值:
因此,对于每个图像,您要存储n + 1
整数值,其中n
是要跟踪的区域数。
为了进行比较,您还需要单独查看每个颜色通道。
这样,您可以快速丢弃不匹配的图像。您还可以使用更多区域和/或递归地应用算法以获得更强的匹配置信度。
因此,您要进行与“图像匹配”完全不同的“指纹匹配”。在过去的20年中,对指纹的分析进行了深入研究,并且开发了一些有趣的算法来确保正确的检测率(相对于FAR和FRR措施- 错误接受率和错误拒绝率))。
我建议您更好地使用LFA(本地特征分析)类检测技术,这些技术主要基于细节检查。细节是任何指纹的特定特征,并且已分为几类。实际上,大多数公共机构都会将光栅图像映射到细节图上,以提交犯罪分子或恐怖分子文件。
请参阅此处以获取更多参考
有关iPhone图像比较和图像相似性开发的信息,请访问:http : //sites.google.com/site/imagecomparison/
要查看实际效果,请在iTunes AppStore上查看eyeBuy Visual Search。
截至2015年(回到未来...关于这个2009年的问题,现在在Google中排名很高),可以使用深度学习技术来计算图像相似度。称为自动编码器的算法家族可以创建可搜索相似性的矢量表示。有一个演示这里。
您可以执行此操作的一种方法是调整图像大小并大幅降低分辨率(可能降至200x200?),然后存储较小的(像素平均)版本进行比较。然后定义一个公差阈值并比较每个像素。如果所有像素的RGB都在公差范围内,那么您已经匹配。
最初的运行时间为O(n ^ 2),但如果对所有匹配项进行分类,则每个新图像都只是一个O(n)算法进行比较(您只需将其与每个先前插入的图像进行比较)。但是,随着要比较的图像列表变大,它最终将崩溃,但是我认为您暂时可以安全使用。
运行400天后,您将获得500,000张图像,这意味着(不考虑缩小图像尺寸的时间)200(H)*200(W)*500,000(images)*3(RGB)
= 60,000,000,000比较。如果每个图像都完全匹配,那么您将会落后,但是事实可能并非如此,对吧?请记住,一旦单个比较超出您的阈值,您可以将图像作为匹配项打折。