【问题标题】:How can I measure the similarity between two images? [closed]如何测量两张图像之间的相似度? [关闭]
【发布时间】:2010-09-06 18:14:51
【问题描述】:

我想将一个应用程序(可能是网页)的屏幕截图与之前截取的屏幕截图进行比较,以确定该应用程序是否正确显示自身。我不想要完全匹配比较,因为方面可能略有不同(对于 Web 应用程序,取决于浏览器,某些元素可能位于稍微不同的位置)。它应该衡量屏幕截图的相似程度。

是否有已经这样做的库/工具?你将如何实现它?

【问题讨论】:

标签: algorithm language-agnostic image image-processing


【解决方案1】:

这完全取决于您希望算法有多聪明。

例如,这里有一些问题:

  • 裁剪后的图像与未裁剪的图像
  • 添加文本的图像与未添加文本的图像
  • 镜像图像

我见过的最简单的算法就是对每个图像执行以下步骤:

  1. 缩放到较小的尺寸,例如 64x64 或 32x32,忽略纵横比,使用组合缩放算法而不是最近像素
  2. 缩放颜色范围,使最暗为黑色,最亮为白色
  3. 旋转和翻转图像,使最亮的颜色在左上角,然后右上角的颜色次之,左下角的颜色次之(当然尽可能远​​)

编辑组合缩放算法是一种当将 10 个像素缩小到 1 个时,会使用一个函数来获取所有这 10 个像素的颜色并将它们组合起来合而为一。可以使用平均、平均值或更复杂的算法(例如双三次样条)来完成。

然后逐像素计算两幅图像之间的平均距离。

要在数据库中查找可能的匹配项,请将像素颜色作为单独的列存储在数据库中,索引其中的一堆(但不是全部,除非您使用非常小的图像),然后执行使用每个像素值的范围,即。小图像中的像素在您要查找的图像的 -5 到 +5 之间的每张图像。

这很容易实现,运行起来也相当快,但当然不能处理最高级的差异。为此,您需要更高级的算法。

【讨论】:

  • 什么是“组合缩放算法”?
  • “组合缩放算法”是否类似于TensorFlow的Pooling?
【解决方案2】:

衡量这一点的“经典”方法是将图像分解为一些规范数量的部分(例如 10x10 网格),然后计算每个单元格内的 RGB 值直方图并比较相应的直方图。这种类型的算法是首选,因为它既简单又对缩放和(小!)平移具有不变性。

【讨论】:

  • 这不是类似于为整个图像制作单个直方图,但增加了无法镜像和旋转的缺点吗?
  • 图像 2 半的 2 个直方图将比整体的 1 个直方图具有更好的匹配精度。虽然它有你提到的缺点,但这取决于你要解决什么问题。
【解决方案3】:

使用标准化颜色直方图。 (阅读应用程序部分here),它们通常用于图像检索/匹配系统,是一种非常可靠、相对快速且易于实现的图像匹配标准方法。

本质上,颜色直方图将捕获图像的颜色分布。然后可以将其与另一张图像进行比较,以查看颜色分布是否匹配。

这种类型的匹配对缩放(一旦直方图标准化)和旋转/移动/移动等非常有弹性。

避免逐像素比较,因为如果图像稍微旋转/移动,可能会导致报告的差异很大。

直方图很容易自己生成(假设您可以访问像素值),但如果您不喜欢它,OpenCV 库是做这类事情的绝佳资源。 Here 是一个演示文稿,向您展示如何使用 OpenCV 创建直方图。

【讨论】:

    【解决方案4】:

    MPEG 等视频编码算法不计算视频每帧之间的差异,以便仅对增量进行编码吗?您可能会研究视频编码算法如何计算这些帧差异。

    看看这个开源图像搜索应用程序http://www.semanticmetadata.net/lire/。它描述了几种图像相似度算法,其中三种来自 MPEG-7 标准:ScalableColor、ColorLayout、EdgeHistogram 和 Auto Color Correlogram。

    【讨论】:

    • 这不会回答这里的问题。问题不在于每个像素的比较。
    • @Kousha 没错,但仍然是一个有趣的思考方向。
    【解决方案5】:

    您可以使用O(n^2) 的纯数学方法,但只有当您确定没有偏移或类似的东西时它才会有用。 (虽然如果你有一些颜色均匀的物体,它仍然可以很好地工作。)

    无论如何,这个想法是计算两个矩阵的归一化点积。 C = sum(Pij*Qij)^2/(sum(Pij^2)*sum(Qij^2)).

    这个公式实际上是矩阵之间角度的“余弦”(奇怪)。 相似度越大(假设Pij=Qij),C 将为1,如果它们完全不同,假设每个i,j Qij = 1(避免零除),Pij = 255,然后对于大小nxnn 越大,我们就越接近于零。 (粗略计算:C=1/n^2)。

    【讨论】:

      【解决方案6】:

      为此,您需要pattern recognition。为了确定两个图像之间的微小差异,Hopfield nets 工作得很好并且很容易实现。不过,我不知道任何可用的实现。

      【讨论】:

        【解决方案7】:

        红宝石解决方案可以是found here

        来自自述文件:

        Phashion 是 pHash 库“感知哈希”的 Ruby 包装器,可检测重复和接近重复的多媒体文件

        【讨论】:

          【解决方案8】:

          如何测量两张图像之间的相似度完全取决于您要测量的内容,例如:对比度、亮度、模态、噪声......然后选择最适合您的相似度度量。您可以选择适合测量亮度的MAD(平均绝对差)、MSD(均方差)...还有CR strong>(相关系数),可以很好地表示两幅图像之间的相关性。您还可以选择基于直方图的相似性度量,例如 SDH(差异图像直方图的标准差)或多模态相似性度量,例如 MI(互信息)或 NMI(归一化互信息)。

          由于这种相似性测量需要花费大量时间,因此建议在对图像应用这些测量之前先缩小图像。

          【讨论】:

            【解决方案9】:

            我想知道(我真的只是把这个想法扔在那里被击落)是否可以通过从另一个图像中减去一个图像,然后将生成的图像压缩为 gif 的 jpeg 并获取文件大小作为相似度的度量。

            如果您有两个相同的图像,您会得到一个白色的盒子,它可以很好地压缩。图像差异越大,表示就越复杂,因此可压缩性也就越小。

            可能不是一个理想的测试,并且可能比必要的要慢得多,但它可能会作为一个快速而肮脏的实现。

            【讨论】:

            • 想想旋转90度;图像仍然相似。
            【解决方案10】:

            您可能会查看开源工具 findimagedupes 的代码,虽然它似乎是用 perl 编写的,所以我不能说它是多么容易解析...

            阅读我喜欢的 findimagedupes 页面,我看到有一个C++ implementation of the same algorithm。想必这会更容易理解。

            看来你也可以使用gqview

            【讨论】:

              【解决方案11】:

              好吧,不要直接回答你的问题,但我已经看到了这种情况。微软最近推出了一个名为PhotoSynth 的工具,它的作用与确定大量图片(可能具有不同的纵横比)中的重叠区域非常相似。

              我想知道他们的博客上是否有任何可用的库或代码 sn-ps。

              【讨论】:

              • 这项技术。已停产。
              【解决方案12】:

              扩展 Vaibhav 的说明,hugin 是一个开源“自动缝合器”,应该对这个问题有一些见解。

              【讨论】:

                【解决方案13】:

                有用于基于内容的图像检索的软件,可以(部分)满足您的需求。所有参考资料和解释都链接自项目网站,还有一本简短的教科书(Kindle):LIRE

                【讨论】:

                  【解决方案14】:

                  您可以在tutorial 之后使用 Siamese Network 查看两张图片是否相似。本教程对相似图像进行聚类,而您可以使用L2 距离来测量两个图像的相似性。

                  【讨论】:

                    【解决方案15】:

                    Beyond Compare 对图像进行逐像素比较,例如,

                    【讨论】:

                    • @xilpex,OP 询问:是否有已经这样做的库/工具?我的回答包括指向此类库/工具的链接。
                    【解决方案16】:

                    如果这是您偶尔会做的事情并且不需要自动化,您可以在支持图层的图像编辑器中完成,例如 Photoshop 或 Paint Shop Pro(也可能是 GIMP 或 Paint.Net,但我不确定这些)。打开两个屏幕截图,并将一个作为图层放在另一个之上。将图层混合模式更改为Difference,两者之间相同的所有内容都将变为黑色。您可以移动顶层以尽量减少对齐差异。

                    【讨论】:

                    • 另一个使这种类型的差异变得非常简单的工具是 kaleidoscopeapp.com
                    【解决方案17】:

                    一个真正的基础级方法可以检查每个像素颜色并将其与第二张图像上的相应像素颜色进行比较 - 但这可能是一个非常非常缓慢的解决方案。

                    【讨论】:

                      猜你喜欢
                      • 2014-04-21
                      • 2014-10-06
                      • 2015-09-13
                      • 2023-04-03
                      • 2020-07-20
                      • 2020-01-14
                      • 2011-05-09
                      • 1970-01-01
                      • 2017-09-07
                      相关资源
                      最近更新 更多