我需要一种简单快速的方法来比较两个图像的相似性 . 即我希望得到一个很高的值,如果它们包含完全相同的东西,但可能有一些稍微不同的背景,可能会移动/调整几个像素 .
(更具体的是,如果重要的话:一张图片是一个图标,另一张图片是截图的子区域,我想知道该子区域是否恰好是图标 . )
我手边有 OpenCV 但我仍然不习惯它 .
到目前为止我想到的一种可能性:将两张图片分成10x10个单元格,对于这100个单元格中的每一个,比较颜色直方图 . 然后我可以设置一些补偿阈值,如果我得到的值高于该阈值,我认为它们是相似的 .
我还没有尝试过它的效果如何,但我想它会足够好 . 图像已经非常相似(在我的用例中),所以我可以使用相当高的阈值 .
我想有很多其他可能的解决方案可以或多或少地工作(因为任务本身非常简单,因为我只想检测相似性,如果它们非常相似) . 你会建议什么?
关于从图像中获取签名/指纹/哈希,有一些非常相关/类似的问题:
另外,我偶然发现了这些具有获取指纹功能的实现:
-
imgSeek(GitHub repo)(GPL)基于论文Fast Multiresolution Image Querying
-
image-match . 与我的搜索非常相似 . 与pHash相似,基于An image signature for any kind of image, Goldberg et al . 使用Python和Elasticsearch .
-
ImageHash . 支持pHash .
关于感知图像哈希的一些讨论:here
有点offtopic:有很多方法来创建音频指纹 . MusicBrainz,一种为歌曲提供基于指纹的查找的网络服务,有一个good overview in their wiki . 他们现在正在使用AcoustID . 这是为了找到精确(或大部分精确)的匹配 . 要查找类似的匹配(或者如果您只有一些片段或高噪音),请查看Echoprint . 一个相关的SO问题是here . 所以这似乎解决了音频问题 . 所有这些解决方案都非常有效 .
关于模糊搜索的一般性问题通常是here . 例如 . 有locality-sensitive hashing和nearest neighbor search .
7 回答
屏幕截图或图标可以转换(缩放,旋转,倾斜......)吗?我脑子里有很多方法可以帮到你:
@carlosdc提到的
Simple euclidean distance (不适用于转换后的图像,您需要一个阈值) .
(Normalized) Cross Correlation - 一个简单的指标,可用于比较图像区域 . 它's more robust than the simple euclidean distance but doesn' t对变换后的图像进行处理,你将再次需要一个阈值 .
Histogram comparison - 如果使用标准化直方图,此方法效果很好,不受仿射变换的影响 . 问题是确定正确的阈值 . 它对颜色变化(亮度,对比度等)也非常敏感 . 您可以将它与前两个结合使用 .
Detectors of salient points/areas - 例如MSER (Maximally Stable Extremal Regions),SURF或SIFT . 这些是非常强大的算法,它们可能对您的简单任务来说太复杂了 . 好的是,您不必拥有只有一个图标的确切区域,这些探测器足够强大,可以找到正确的匹配 . 本文对这些方法进行了很好的评估:Local invariant feature detectors: a survey .
其中大部分已在OpenCV中实现 - 请参阅例如cvMatchTemplate方法(使用直方图匹配):http://dasl.mem.drexel.edu/~noahKuntz/openCVTut6.html . 突出点/面积探测器也可用 - 见OpenCV Feature Detection .
我最近面临同样的问题,为了解决这个问题(简单快速的算法来比较两个图像)一劳永逸,我为opencv_contrib贡献了一个img_hash module,你可以从this link找到详细信息 .
img_hash模块提供了六种图像哈希算法,非常好用 .
Codes example
原籍莉娜
模糊莉娜
调整莱娜的大小
班纳
在这种情况下,ColorMomentHash会给我们带来最好的结果
高斯模糊攻击:0.567521
轮班攻击:0.229728
调整大小:0.229358
Pros and cons of each algorithm
img_hash的性能也很好
Speed comparison with PHash library(100 images from ukbench)
如果你想知道这些算法的推荐阈值,请查看这篇文章(http://qtandopencv.blogspot.my/2016/06/introduction-to-image-hash-module-of.html) . 如果您对如何衡量img_hash模块的性能(包括速度和不同的攻击)感兴趣,请查看此链接(http://qtandopencv.blogspot.my/2016/06/speed-up-image-hashing-of-opencvimghash.html) .
屏幕截图是否仅包含图标?如果是这样,两个图像的L2距离可能就足够了 . 如果L2距离不起作用,则下一步是尝试简单且完善的内容,例如:Lucas-Kanade . 我确信在OpenCV中可用 .
如果你想获得关于两张图片的相似性的索引,我建议你从SSIM索引的指标 . 它与人眼更加一致 . 这是一篇关于它的文章:Structural Similarity Index
它也是在OpenCV中实现的,可以用GPU加速:OpenCV SSIM with GPU
如果您可以确保模板(图标)与测试区域的精确对齐,那么任何旧的像素差异都将起作用 .
如果对齐只是一点点关闭,那么你可以在找到像素差异之和之前用cv::GaussianBlur低通两个图像 .
如果对齐的质量可能很差,那么我建议使用Histogram of Oriented Gradients或OpenCV方便的关键点检测/描述符算法之一(例如SIFT或SURF) .
如果匹配相同的图像 - L2距离的代码
快速 . 但对照明/视点等的变化不稳健Source
如果你想比较图像的相似性,我建议你使用OpenCV . 在OpenCV中,很少有功能匹配和模板匹配 . 对于特征匹配,有SURF,SIFT,FAST等探测器 . 您可以使用它来检测,描述然后匹配图像 . 之后,您可以使用特定索引查找两个图像之间的匹配数 .