我需要创建大量图像的指纹(大约有100,000张现有图像,每天新增1,000张,RGB,JPEG,最大尺寸为800x800),以便快速比较每个图像与其他每个图像。我不能使用二进制比较方法,因为还应识别几乎相似的图像。
最好是已有的库,但对现有算法的一些提示也会帮助我很多。
我需要创建大量图像的指纹(大约有100,000张现有图像,每天新增1,000张,RGB,JPEG,最大尺寸为800x800),以便快速比较每个图像与其他每个图像。我不能使用二进制比较方法,因为还应识别几乎相似的图像。
最好是已有的库,但对现有算法的一些提示也会帮助我很多。
普通的哈希或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的方法是通过canvas从图像中构建亮度直方图。可以在画布上可视化多边形直方图,然后将其与数据库(例如mySQL spatial…)中的多边形进行比较。
Compare()
函数,而不是必须先下载图像。另外,根据我的测试,“非常相似图像”的阈值应该是> 90%,而不是> 98%。 - thdoan因此,对于每个图像,您需要存储 n+1
个整数值,其中 n
是您要跟踪的区域数量。
为了进行比较,您还需要单独查看每个颜色通道。
这样可以快速筛选不匹配的图像;您还可以使用更多区域和/或递归应用算法以获取更强的匹配置信度。
截至2015年(回到未来...在谷歌上高排名的2009年问题),可以使用深度学习技术计算图像相似性。被称为自动编码器的算法族可以创建可搜索相似性的向量表示。这里有一个演示链接。
若要进行iPhone图像比较和图像相似度开发,请查看:http://sites.google.com/site/imagecomparison/
欲了解其效果,可前往iTunes AppStore下载eyeBuy Visual Search应用。
您是否真的想将每个图像与其他图像进行比较?这个应用程序是什么?也许您只需要某种基于特定描述符的图像索引和检索?例如,您可以查看多媒体内容描述界面的MPEG-7标准。然后,您可以比较不同的图像描述符,这可能不太精确,但速度更快。