比较两个图像的算法


158

给定两个不同的图像文件(以我选择的任何格式),我需要编写一个程序来预测如果一个文件是另一个文件的非法复制的机会。副本的作者可能会做诸如旋转,制作负片或添加琐碎细节(以及更改图像尺寸)之类的事情。

您知道执行这种工作的算法吗?


12
您如何确定哪一个是原件?
jfs

1
我猜他有原始文件,需要验证外部文件是否是转换后的副本或与原始文件无关。
unfa

Answers:


303

这些只是我一直在思考问题的想法,从未尝试过,但我喜欢思考这样的问题!

在你开始之前

考虑对图片进行归一化,如果一个图片的分辨率高于另一张图片,请考虑选择其中一个为另一张图片的压缩版本,因此缩小分辨率可能会提供更准确的结果。

考虑扫描图像的各个预期区域,这些区域可能代表图像的缩放部分以及各种位置和旋转。如果其中一幅图像是另一幅图像的歪斜版本,它将变得很棘手,这些是您应该确定并妥协的限制。

Matlab是用于测试和评估图像的出色工具。

测试算法

您应该(至少)测试一组大型的人工分析的测试数据,这些数据必须事先已知。例如,如果在测试数据中有1,000张图像,其中有5%匹配,则您现在有了一个相当可靠的基准。在我们的测试数据中,找到10%阳性的算法不如发现4%阳性的算法。但是,一种算法可能会找到所有匹配项,但误报率也高达20%,因此有几种方法可以对算法进行评分。

应将测试数据设计为涵盖您希望在现实世界中找到的尽可能多的动态类型。

重要的是要注意,每个有用的算法都必须比随机猜测更好地执行,否则对我们没有用!

然后,您可以以受控方式将软件应用于现实世界,并开始分析其产生的结果。这是可以无限进行的软件项目,您总是可以进行调整和改进,在设计它时要牢记这一点,因为很容易陷入永无止境的项目陷阱,这一点很重要。

色桶

用两张图片扫描每个像素并计算颜色。例如,您可能拥有“存储桶”:

white
red
blue
green
black

(显然,您将拥有更高的计数器分辨率)。每次找到“红色”像素,就增加红色计数器。每个存储桶都可以代表各种颜色,分辨率越高,精度越高,但是您应该以可接受的差异率进行试验。

获得总计后,将其与第二张图像的总计进行比较。您可能会发现每个图像都有一个相当独特的足迹,足以识别匹配项。

边缘检测

如何使用边缘检测(来源:wikimedia.org替代文字

对于两张相似的图片,边缘检测将为您提供可用且相当可靠的独特足迹。

拍摄两张照片,然后应用边缘检测。也许测量边缘的平均厚度,然后计算图像可以缩放的可能性,并在必要时重新缩放。以下是在各种旋转情况下应用的Gabor滤波器(一种边缘检测)的示例。

替代文字

比较图片像素与像素,计算匹配和不匹配。如果它们在一定的错误阈值内,则您具有匹配项。否则,您可以尝试将分辨率降低到某个点,然后查看匹配概率是否提高。

名胜古迹

一些图像可能具有独特的感兴趣的片段/区域。这些区域可能与图像的其余部分形成强烈对比,并且是在其他图像中进行搜索以找到匹配项的好项目。以这张图片为例:

替代文字
(来源:meetthegimp.org

蓝色的建筑工人是关注的区域,可以用作搜索对象。您可能有几种方法可以从感兴趣的区域提取属性/数据,然后使用它们来搜索数据集。

如果您有两个以上的兴趣区域,则可以测量它们之间的距离。举这个简化的例子:

替代文字
(来源:per2000.eu

我们有3个清晰的兴趣区域。区域1和2之间的距离可以是200像素,1和3 400像素之间以及2和3 200像素。

在其他图像中搜索感兴趣的相似区域,对距离值进行归一化,然后查看是否存在潜在的匹配项。该技术可以很好地用于旋转和缩放的图像。您拥有的兴趣区域越多,匹配的可能性就随每次距离测量值的匹配而增加。

考虑数据集的上下文非常重要。例如,如果您的数据集是现代艺术,那么感兴趣的区域就可以很好地工作,因为感兴趣的区域可能被设计为最终图像的基本部分。但是,如果您要处理的是建筑工地的图像,则非法复印机可能会将感兴趣的区域解释为丑陋的,并且可能会对其进行随意裁剪/编辑。请记住数据集的共同特征,并尝试利用这些知识。

变形

变形两个图像是通过一组步骤将一个图像转换为另一个图像的过程:

替代文字

注意,这与将一个图像淡入另一个图像不同!

有许多可以使图像变形的软件包。传统上,它是用作过渡效果的,通常,两张图像通常不会变半,最终的结果是一个极端变到另一个极端。

为什么这会有用?取决于您使用的变形算法,图像的相似性与变形算法的某些参数之间可能存在关系。

在完全简化的示例中,当要进行的更改较少时,一种算法的执行速度可能会更快。然后我们知道这两个图像彼此共享属性的可能性更高。

对于旋转,扭曲,倾斜,缩放的所有类型的复制图像,此技术都可以很好工作。再说一次,这只是我的一个主意,据我所知,它并不是基于任何研究过的学术界(虽然我看起来并不难),所以对您来说可能是很多工作,但结果有限/没有结果。

压缩

Ow在这个问题上的回答非常好,我记得读过有关学习AI的这类技术的文章。它在比较语料库词典方面非常有效。

比较语料库时,一个有趣的优化是可以删除被认为太常见的词,例如“ The”,“ A”,“ And”等。这些词淡化了我们的结果,我们想弄清楚两个语料库有何不同因此可以在处理之前将其删除。也许图像中存在类似的常见信号,可以在压缩之前将其剥离?可能值得研究。

压缩率是一种非常快速且合理有效的方法,用于确定两组数据的相似程度。阅读有关压缩如何工作的知识,将使您很好地理解为何如此有效。对于快速发布的算法,这可能是一个很好的起点。

透明度

再次,我不确定如何为某些图像类型(gif png等)存储透明度数据,但这将是可提取的,并且可以作为与您的数据集透明度进行比较的有效简化方法。

反相信号

图像只是一个信号。如果您从某个扬声器播放噪声,并且以完全相同的音量在另一个扬声器中以完全同步的方式播放相反的噪声,则它们会相互抵消。

替代文字
(来源:themotorreport.com.au

反转图像,然后将其添加到其他图像上。重复缩放它/循环的位置,直到找到结果图像,其中足够多的像素为白色(或黑色?我将其称为中性画布)以为您提供正匹配或部分匹配。

但是,请考虑两个相等的图像,只是其中一个图像具有加亮效果:

替代文字
(来源:mcburrz.com

反转其中一个,然后将其添加到另一个中,将不会生成我们想要的中性画布。但是,当比较两个原始图像的像素时,我们可以清楚地看到两者之间的明确关系。

我已经好几年没有研究色彩了,不确定色谱是否在线性范围内,但是如果您确定了两张图片之间色差的平均因子,则可以使用该值对数据进行归一化处理这种技术。

树数据结构

起初,这些似乎并不适合这个问题,但我认为它们可以工作。

您可以考虑提取图像的某些属性(例如颜色容器)并生成霍夫曼树或类似的数据结构。您可能可以比较两棵树的相似性。例如,对于大范围的彩色图像,这不适用于摄影数据,但是对于卡通或其他缩小的彩色设置图像,这可能会起作用。

这可能行不通,但这是一个主意。在特里数据结构是存储词库很大,例如dictionarty。这是一个前缀树。也许可以构建与词典等效的图像(同样我只能想到颜色)来构建特里。如果将300x300的图像缩小为5x5的正方形,然后将每个5x5的正方形分解为一系列颜色,则可以根据结果数据构造特里。如果2x2正方形包含:

FFFFFF|000000|FDFD44|FFFFFF

我们有一个相当独特的Trie代码,它扩展了24个级别,增加/减少级别(IE减小/增加子正方形的大小)可能会产生更准确的结果。

比较特里树应该相当容易,并且有可能提供有效的结果。

更多想法

我偶然发现了一篇有趣的关于卫星图像分类的论文,它概述了:

考虑的纹理量度包括:共现矩阵,灰度差异,纹理色调分析,从傅立叶光谱派生的特征以及Gabor滤波器。发现某些傅里叶特征和一些Gabor滤波器是不错的选择,尤其是在使用单个频带进行分类时。

尽管其中一些可能与您的数据集无关,但是可能值得更详细地研究这些度量。

其他要考虑的事情

可能有很多关于这种事情的论文,因此尽管其中一些技术性很强,但阅读其中的一些内容应该会有所帮助。这是计算领域中极为困难的领域,许多人试图做类似的事情花费了很多无用的时间。保持简单并以这些想法为基础将是最好的方法。创建一个比随机匹配率更好的算法,并开始对其进行改进,确实确实变得非常困难,这是一个相当困难的挑战。

每种方法可能都需要进行彻底的测试和调整,如果您还具有要检查的图片类型的任何信息,这将很有用。例如,广告中很多都包含文本,因此进行文本识别将是一种简单且可能非常可靠的查找匹配项的方法,尤其是与其他解决方案结合使用时。如前所述,尝试利用数据集的通用属性。

将可衡量的投票和替代技术(取决于其有效性)相结合,将是您创建可产生更准确结果的系统的一种方式。

如果采用多种算法(如在此答案开头提到的那样),则可能会发现所有阳性,但假阳性率仅为20%,因此研究另一种算法的特性/强度/弱点将是有趣的,因为另一种算法可能有效地消除从其他人返回的误报。

小心不要陷入试图完成永无止境的项目的过程中,祝您好运!


21
很棒的回应。经过深思熟虑和启发性回答的荣誉。
Andrew Hubbs 2010年

谢谢!我希望在明天进一步扩展它,我还有更多的想法想思考和查找。
汤姆·古伦

嗨,汤姆(Tom)-您知道Java中的任何开源边缘检测库吗?
理查德H

1
嗨,理查德,对不起,但是我确定那里有一些。在Google上搜索“ Java Gabor过滤器”或“ Java边缘检测”,我敢肯定您会遇到一两个。
汤姆·古伦

图片的链接(blog.meetthegimp.orgwp-content / uploads / 2009/04 / 97.jpg)损坏了。请注意,stackoverflow现在具有图像托管服务。
ThomasW 2011年

36

阅读本文:Porikli,Fatih,Afterl Tuzel和Peter Meer。“使用基于黎曼流形的模型更新进行协方差跟踪”。(2006)IEEE计算机视觉和模式识别。

使用本文介绍的技术,我成功地检测到从相邻网络摄像头捕获的图像中的重叠区域。我的协方差矩阵由Sobel,Canny和SUSAN高宽/边缘检测输出以及原始灰度像素组成。


1
@Satoru Logic:谷歌搜索显示纸上命中:google.com/…
尼克2010年

34

一个想法:

  1. 使用关键点检测器查找图像中某些点(例如,SIFT,SURF,GLOH或LESH)的比例不变和变换不变的描述符。
  2. 尝试将两个图像的关键点与相似的描述符对齐(例如在全景拼接中),并在必要时进行一些图像变换(例如缩放和旋转或弹性拉伸)。
  3. 如果许多关键点对准得很好(存在这样的变换,则关键点对准误差很低;或者变换“能量”很低,等等),您可能拥有相似的图像。

第2步并非易事。特别是,您可能需要使用智能算法在其他图像上找到最相似的关键点。点描述符通常是非常高维的(例如一百个参数),并且有很多点需要浏览。kd-trees在这里可能很有用,哈希查找无法正常工作。

变体:

  • 检测边缘或其他特征而不是点。

2
我认为这也是正确的方法。只是一个细节:SIFT,SURF,GLOH并不是重点探测器。它们是关键点描述符。常见的关键点检测器是(尺度不变)DoG,Harris或特征值检测器。
Niki 2010年

对于步骤2,您可以使用最近的邻居,这些邻居使用描述符之间的欧式距离
MobileCushion

15

这确实比看起来简单得多:-)尼克的建议是一个好建议。

首先,请记住,任何有价值的比较方法实际上都可以通过将图像转换为其他形式来工作,这种形式可以更轻松地挑选出相似的特征。通常,这些东西并不能使阅读变得很轻松。


我能想到的最简单的例子之一就是简单地使用每个图像的色彩空间。如果两个图像具有非常相似的颜色分布,则可以合理地确定它们显示的是相同的东西。至少,您可以有足够的把握来对其进行标记,或者进行更多的测试。在色彩空间中比较图像还可以抵抗旋转,缩放和某些裁切等操作。当然,它不会抵抗图像的大量修改或强烈的重新着色(甚至简单的色相偏移都会有些棘手)。

http://zh.wikipedia.org/wiki/RGB_color_space
http://upvector.com/index.php?section=tutorials&subsection=tutorials/colorspace


另一个示例涉及称为霍夫变换的东西。这种变换本质上将图像分解为一组线。然后,您可以在每张图像中画一些“最强”的线,看看它们是否对齐。您还可以做一些额外的工作来尝试补偿旋转和缩放-在这种情况下,由于比较几行比在整个图像上进行的计算工作要少得多-不会太糟糕。

http://homepages.inf.ed.ac.uk/amos/hough.html
http://rkb.home.cern.ch/rkb/AN16pp/node122.html
http://en.wikipedia.org/wiki/ Hough_transform


8

按照您描述的形式,问题很棘手。您是否考虑将图像的一部分复制,粘贴到另一个较大的图像中作为副本?等等

如果您退后一步,则在对主图像进行水印处理时更容易解决。您将需要使用水印方案将代码嵌入图像中。与某些人建议的一些低级方法(边缘检测等)相比,退后一步,加水印方法是优越的,因为:

它可以抵抗信号处理攻击►信号增强–锐化,对比度等。►滤波–中值,低通,高通等。►加性噪声–高斯,均匀等。►有损压缩– JPEG,MPEG等。

它可以抵抗几何攻击►仿射变换►数据缩减–裁剪,裁剪等。►局部局部失真►扭曲

对水印算法进行一些研究,您将找到解决问题的正确方法。(注意:您可以使用STIRMARK数据集对方法进行基准测试。这是此类应用程序的公认标准。


5

这只是一个建议,可能不起作用,我准备就此提出建议。

这将产生误报,但希望不会产生误报。

  1. 调整两个图像的大小,以使它们具有相同的大小(我假设两个图像的宽度与长度之比相同)。

  2. 使用无损压缩算法(例如gzip)压缩两个图像的位图。

  3. 查找具有相似文件大小的文件对。例如,您可以按照文件大小的相似程度对每对文件进行排序,然后检索前X个。

正如我所说,这肯定会产生误报,但希望不会产生误报。您可以在五分钟内实现,而Porikil等 等 可能需要大量工作。


我非常喜欢这种解决方案,易于实现,并且相信它会产生比随机识别率更好的效果
Tom Gullen 2010年

这是一个问题:如果以不同的分辨率保存了副本,是否可行?
belisarius博士10年

4

我相信,如果您愿意将该方法应用于所有可能的方向和否定版本,则使用特征脸可以很好地开始图像识别(具有良好的可靠性):http : //en.wikipedia.org/wiki/Eigenface

另一个想法是将两个图像都转换成其分量的矢量。做到这一点的一个好方法是创建一个以x * y尺寸(x是图像的宽度,y是高度)运行的矢量,每个尺寸的值都将应用于(x,y)像素值。然后运行具有两个类别的K最近邻居的变体:匹配和不匹配。如果图像与原始图像足够接近,则将其归入匹配类别,否则将不适合。

可以在这里找到K最近邻居(KNN),也可以在网上找到有关它的其他很好的解释:http : //en.wikipedia.org/wiki/K-nearest_neighbor_algorithm

KNN的好处在于,与原始图像相比,变体越多,算法就越准确。不利的一面是您需要图像目录以首先训练系统​​。


1
一个好主意,但前提是数据中存在面孔。它还可以识别人员,而不是情况。因此,在多个出版物中都有发言的专业演员会产生很多误报。
汤姆·古伦

除非我误解了您的使用意图
汤姆·古伦

实际上,我认为该算法不管主题如何都可以工作,因此,如果您比较树木,它也将很有用。它恰好被称为特征脸,因为它与面部识别有着经典的联系。只要要搜索的项目具有与要比较的项目相同的整体功能,就应该仍然有效。
尼克·乌德尔

太长了,无法添加到以前的评论中:同样:特征脸会比较整个图像,而不仅仅是屏幕上的脸。Wikipedia上的示例仅使用裁剪的面孔,因为传统的应用是面部识别,只有面部识别才有用。如果您的演员出现在不同的位置,它将被标记为不同的位置。
尼克·乌德尔

1
我怀疑直接在原始像素值上应用KNN 是否会有所帮助。较小的平移/旋转通常会导致原始像素值产生巨大差异,尤其是在图片包含鲜明的对比度或细线的情况下。因此,同一张图片的任意转换版本在该空间中彼此之间并没有真正靠近(它们不会分成簇),并且KNN不能很好地工作。我猜想它可以很好地用于图像直方图或图像的其他变换不变表示。
Niki 2010年

1

如果您愿意考虑使用另一种方法来检测图像的非法副本,则可以考虑加水印。(从1.4开始)

...将版权信息插入数字对象,而不会损失质量。每当对数字对象的版权提出疑问时,都会提取此信息以标识合法所有者。还可以对原始购买者的身份以及版权持有者的身份进行编码,从而可以跟踪任何未经授权的副本。

尽管它也是一个复杂的领域,但是有一些技术可以使水印信息通过总体图像更改而得以保留:(从1.9开始)

...任何强度适当的信号转换都不能去除水印。因此,除非愿意将水印降级到不具有商业利益,否则愿意删除水印的海盗将不会成功。

当然,常见问题解答要求实施这种方法:“ ...非常具有挑战性”,但是,如果成功实现,您将非常有信心确定图像是否是副本,而不是百分比可能性。


关于经过大量编辑后水印如何持续存在的更多信息?听起来很有趣。
汤姆·古伦

0

如果您正在运行Linux,则建议使用以下两种工具:

来自hugin-tools软件包的align_image_stack-是一个命令行程序,可以自动纠正旋转,缩放和其他变形(主要用于合成HDR摄影,但也适用于视频帧和其他文档)。详细信息:http : //hugin.sourceforge.net/docs/manual/Align_image_stack.html

从imagemagick包中进行比较 -该程序可以查找和计算两个图像中不同像素的数量。这是一个简洁的教程:http: //www.imagemagick.org/Usage/compare/使用-fuzz N%可以提高容错能力。N越高,将两个像素视为相同的容错性也越高。

align_image_stack应该更正任何偏移量,以便compare命令实际上有机会检测相同的像素。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.