当前位置:  开发笔记 > 编程语言 > 正文

简单快速的方法来比较图像的相似性

如何解决《简单快速的方法来比较图像的相似性》经验,为你挑选了4个好方法。

我需要一种简单快速的方法来比较两个图像的相似性.即如果它们包含完全相同的东西但是可能有一些稍微不同的背景并且可能被移动/调整大小几个像素,我想获得高值.

(更具体的是,如果重要的话:一张图片是一个图标,另一张图片是截图的子区域,我想知道该子区域是否恰好是图标.)

我手边有OpenCV,但我仍然不习惯它.

到目前为止我想到的一种可能性:将两张图片分成10x10个单元格,对于这100个单元格中的每一个,比较颜色直方图.然后我可以设置一些补偿阈值,如果我得到的值高于该阈值,我认为它们是相似的.

我还没有尝试过它的效果如何,但我想它会足够好.图像已经非常相似(在我的用例中),所以我可以使用相当高的阈值.

我想有很多其他可能的解决方案可以或多或少地工作(因为任务本身非常简单,因为我只想检测相似性,如果它们非常相似).你会建议什么?


关于从图像中获取签名/指纹/哈希,有一些非常相关/类似的问题:

OpenCV/SURF如何从描述符中生成图像哈希/指纹/签名?

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

近似重复图像检测

OpenCV:指纹图像和数据库比较.

更多的,更,更多,更多,更多,更多,更多

另外,我偶然发现了这些具有获取指纹功能的实现:

pHash

imgSeek(GitHub repo)(GPL)基于纸张快速多分辨率图像查询

图像匹配.与我的搜索非常相似.与pHash类似,基于任何类型图像的图像签名,Goldberg等.使用Python和Elasticsearch.

iqdb

ImageHash.支持pHash.

关于感知图像哈希的一些讨论:这里


有点offtopic:有很多方法来创建音频指纹.MusicBrainz是一种为歌曲提供基于指纹的查找的网络服务,在他们的维基中有很好的概述.他们现在正在使用AcoustID.这是为了找到精确(或大部分精确)的匹配.要查找类似的匹配(或者如果您只有一些片段或高噪音),请查看Echoprint.一个相关的SO问题在这里.所以这似乎解决了音频问题.所有这些解决方案都非常有效.

对一般的模糊搜索一个稍微更通用的问题是在这里.例如,存在局部敏感的散列和最近邻搜索.



1> Karel Petran..:

屏幕截图或图标可以转换(缩放,旋转,倾斜......)吗?我脑子里有很多方法可以帮到你:

@carlosdc提到的简单欧几里德距离(不适用于转换后的图像,您需要一个阈值).

(标准化)交叉关联 - 可用于比较图像区域的简单指标.它比简单的欧几里德距离更强大,但不适用于转换后的图像,您将再次需要一个阈值.

直方图比较 - 如果使用标准化直方图,此方法效果很好,不受仿射变换的影响.问题是确定正确的阈值.它对颜色变化(亮度,对比度等)也非常敏感.您可以将它与前两个结合使用.

突出点/区域的探测器 - 例如MSER(最大稳定极值区域),SURF或SIFT.这些是非常强大的算法,它们可能对您的简单任务来说太复杂了.好的是,您不必拥有只有一个图标的确切区域,这些探测器足够强大,可以找到正确的匹配.本文对这些方法进行了很好的评估:局部不变特征检测器:一项调查.

其中大部分已经在OpenCV中实现 - 例如参见cvMatchTemplate方法(使用直方图匹配):http://dasl.mem.drexel.edu/~noahKuntz/openCVTut6.html .突出点/面积检测器也可用 - 请参阅OpenCV特征检测.



2> StereoMatchi..:

我最近面临同样的问题,为了解决这个问题(简单快速的算法比较两个图像)一劳永逸,我将一个img_hash模块贡献给opencv_contrib,你可以从这个链接中找到细节.

img_hash模块提供了六种图像哈希算法,非常好用.

代码示例

来源莱娜来源莱娜

模糊莉娜模糊莉娜

调整莱娜的大小调整莱娜的大小

转移莉娜转移莉娜

#include 
#include 
#include 
#include 
#include 

#include 

void compute(cv::Ptr algo)
{
    auto input = cv::imread("lena.png");
    cv::Mat similar_img;

    //detect similiar image after blur attack
    cv::GaussianBlur(input, similar_img, {7,7}, 2, 2);
    cv::imwrite("lena_blur.png", similar_img);
    cv::Mat hash_input, hash_similar;
    algo->compute(input, hash_input);
    algo->compute(similar_img, hash_similar);
    std::cout<<"gaussian blur attack : "<<
               algo->compare(hash_input, hash_similar)<compute(similar_img, hash_similar);
    std::cout<<"shift attack : "<<
               algo->compare(hash_input, hash_similar)<compute(similar_img, hash_similar);
    std::cout<<"resize attack : "<<
               algo->compare(hash_input, hash_similar)<

在这种情况下,ColorMomentHash会给我们带来最好的结果

高斯模糊攻击:0.567521

轮班攻击:0.229728

调整大小:0.229358

每种算法的优缺点

不同攻击下的表现

img_hash的性能也很好

与PHash库进行速度比较(来自ukbench的100张图片) 计算性能 比较表现

如果您想知道这些算法的推荐阈值,请查看这篇文章(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).



3> carlosdc..:

屏幕截图是否仅包含图标?如果是这样,两个图像的L2距离可能就足够了.如果L2距离不起作用,下一步就是尝试一些简单而完善的东西,例如:Lucas-Kanade.我确信在OpenCV中可用.



4> 小智..:

如果你想获得关于两张图片的相似性的索引,我建议你从SSIM索引的指标.它与人眼更加一致.这是一篇关于它的文章:结构相似性指数

它也是在OpenCV中实现的,它可以通过GPU加速:带GPU的OpenCV SSIM

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有