algorithm来比较两个图像

给定两个不同的图像文件(以我select的任何格式),我需要编写一个程序来预测这个机会是否是另一个机器的非法拷贝。 副本的作者可能会做旋转,做负面的东西,或者添加微不足道的细节(以及改变图像的尺寸)。

你知道任何algorithm来做这种工作吗?

这些只是我一直在想这个问题的想法,从来没有尝试过,但我喜欢考虑这样的问题!

在你开始之前

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

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

Matlab是testing和评估图像的绝佳工具。

testingalgorithm

您应该testing(至less)一个大的人类分析的testing数据集,事先知道匹配。 例如,如果您的testing数据中有1000个图像,其中5%匹配,则您现在拥有相当可靠的基准。 发现10%肯定的algorithm不如在我们的testing数据中find4%肯定的algorithm。 然而,一个algorithm可能会find所有的匹配,但也有20%的误报率,所以有几种方法来评估你的algorithm。

testing数据应该试图devise成涵盖您希望在现实世界中find的尽可能多的dynamictypes。

注意每个algorithm的有用性必须比随机猜测更好,否则对我们来说是无用的!

然后,您可以以受控的方式将您的软件应用到真实世界中,并开始分析其生成的结果。 这是一种可以永无止境的软件项目,总是可以做出调整和改进,在devise时要考虑到这一点很重要,因为容易陷入永无止境的项目陷阱。

颜色桶

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

white red blue green black 

(显然你会有更高的计数器分辨率)。 每当你find一个“红”像素,你增加红色计数器。 每个桶可以代表色谱,分辨率越高越精确,但是您应该尝试一个可接受的差异率。

一旦你有你的总数,比较它的第二个图像的总数。 您可能会发现每个图像都有相当独特的足迹,足以识别匹配。

边缘检测

如何使用边缘检测 。 替代文字http://upload.wikimedia.org/wikipedia/en/thumb/8/8e/EdgeDetectionMathematica.png/500px-EdgeDetectionMathematica.png

有了两个相似的图片边缘检测应该为您提供一个可用和相当可靠的独特的足迹。

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

替代文字

比较像素的像素像素,计数匹配和不匹配。 如果他们在一定的误差范围内,你就有一场比赛。 否则,您可以尝试将分辨率降低到某一点,并查看匹配的概率是否提高。

感兴趣的地区

一些图像可能有不同的细分/感兴趣区域。 这些区域可能与图像的其他部分形成高度对比,并且是在其他图像中search匹配的好项目。 以此图像为例:

替代文字http://meetthegimp.org/wp-content/uploads/2009/04/97.jpg

蓝色build筑工人是一个感兴趣的领域,可以作为一个search对象。 可能有几种方法可以从这个感兴趣的区域提取属性/数据,并使用它们来search数据集。

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

替代文字http://www.per2000.eu/assetshttp://img.dovov.com3_dots_black_03.jpg

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

search其他图像的相似的感兴趣的区域,规范化的距离值,看看你是否有潜在的匹配。 这种技术可以适用于旋转和缩放图像。 你有更多的兴趣区域,匹配的概率随着每个距离测量的匹配而增加。

考虑数据集的上下文很重要。 例如,如果你的数据是现代艺术,那么感兴趣的区域就可以工作得很好,因为感兴趣的区域可能被devise成最终形象的基本部分。 如果你正在处理build筑工地的图像,感兴趣的地区可能会被非法复印机解读为丑陋,并且可能会被自由裁剪/编辑。 记住数据集的共同特征,并尝试利用这些知识。

变形

变形两个图像是通过一系列步骤将一个图像变成另一个图像的过程:

替代文字

请注意,这是不同的淡入一个图像到另一个!

有许多可以变形图像的软件包。 传统上被用作过渡效果,两幅图像通常不会中途变形,一个极端变成另一个极端,作为最后的结果。

为什么这可能是有用的? 根据您使用的变形algorithm,图像的相似性和变形algorithm的一些参数之间可能存在关系。

在一个非常简单的例子中,一个algorithm可能会执行得更快,当有更less的变化。 然后我们知道这两个图像彼此共享属性的可能性较高。

这种技术可以适用于旋转,扭曲,倾斜,缩放,所有types的复制图像。 再次,这只是我的一个想法,根据我所知,这不是基于任何研究的学术界(尽pipe我还没有看清楚),所以对于有限的/没有结果的人来说,这可能是很多工作。

荏苒

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

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

压缩比是确定两组数据有多相似的非常快速和合理有效的方式。 阅读压缩的工作原理将会给你一个很好的想法,为什么这可能是如此有效。 对于一个快速释放algorithm,这可能是一个很好的起点。

透明度

再次,我不确定如何透明度数据存储为某些图像types,GIF PNG等,但这将是可以提取的,将作为一个有效的简化裁减与您的数据集透明度进行比较。

反转信号

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

替代文字http://www.themotorreport.com.au/wp-content/uploads/2008/07/noise-cancellation.gif

翻转图像,并将其添加到您的其他图像。 重复缩放/循环位置,直到find足够像素为白色(或黑色?我将其称为中性canvas)的结果图像为您提供正匹配或部分匹配。

但是,考虑两个相同的图像,除了其中一个具有适用的亮度效果:

替代文字

将其中一个倒转,然后将其添加到另一个将不会导致我们正在瞄准的中立canvas。 但是,当比较两个原始图像的像素时,我们可以明确地看到两者之间的明确关系。

我现在还没有研究过色彩,并且不确定色谱是否在线性范围内,但是如果您确定了两张图片之间的色差的平均因子,则可以使用此值对数据进行归一化处理这个技巧。

树数据结构

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

您可以考虑提取图像的某些属性(例如颜色箱)并生成一个huffman树或类似的数据结构。 您可能可以比较两棵树的相似性。 这对于例如具有大范围颜色的照片数据不适用,但是这可能起作用的是卡通或其他缩小的颜色设置图像。

这可能不起作用,但这是一个想法。 特里数据结构在存储词典方面非常出色,例如词典。 这是一个前缀树。 也许有可能build立一个相当于一个词典的图像(再次我只能想到颜色)来构build一个树状结构。 如果您将一幅300×300的图像缩减为5×5的正方形,然后将每个5×5的正方形分解为一系列颜色,则可以从结果数据中构build一个树状图。 如果一个2×2正方形包含:

 FFFFFF|000000|FDFD44|FFFFFF 

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

比较树木应该是相当容易的,并且可以提供有效的结果。

更多的想法

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

考虑的纹理测量是:共生matrix,灰度差异,纹理色调分析,由傅里叶谱导出的特征和Gabor滤波器。 一些傅立叶特征和一些Gabor滤波器被认为是很好的select,特别是当使用单个频带进行分类时。

尽pipe其中一些可能与您的数据集不相关,但可能需要更详细地调查这些测量结果。

其他事情要考虑

可能有很多关于这种事情的文章,所以阅读其中的一些应该会有所帮助,虽然他们可以是非常技术性的。 这是一个非常困难的计算领域,许多人试图做类似的事情花了许多没有成果的工作。 保持简单和build立在这些想法上将是最好的方法。 创build一个比随机匹配更好的algorithm应该是一个相当困难的挑战,并开始改进,真的开始变得很难实现。

每种方法都可能需要进行彻底的testing和调整,如果你有任何关于你将要检查的图片types的信息,这将是有用的。 例如广告,其中很多会有文字,因此进行文字识别是一种简单而可能的非常可靠的方法,尤其是在与其他解决scheme结合使用时。 如前所述,尝试利用数据集的通用属性。

结合替代测量和技术,每个可以有一个加权投票(取决于其有效性)将是一种方法,你可以创build一个系统,产生更准确的结果。

如果采用多种algorithm,就像在这个答案开始时提到的那样,可以find所有的肯定结果,但是假阳性率为20%,研究其他algorithm的性能/优势/弱点,有效地消除从另一个返回的误报。

小心不要试图完成永不落幕的项目,祝你好运!

阅读论文: Porikli,Fatih,Oncel Tuzel和Peter Meer。 “基于黎曼stream形上模型更新的协方差跟踪”。 (2006)IEEE计算机视觉和模式识别。

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

一个主意:

  1. 使用关键点检测器来查找图像中某些点(例如SIFT,SURF,GLOH或LESH)的缩放和变换不变描述符。
  2. 尝试使用两个图像中的类似描述符(如全景拼接)alignment关键点,如果需要(例如缩放和旋转或弹性拉伸)允许进行一些图像转换。
  3. 如果许多关键点很好地alignment(存在这样的转换,关键点alignment误差较低,或转换“能量”较低等),则可能有类似的图像。

步骤2不是微不足道的。 尤其是,您可能需要使用智能algorithm来查找其他图像上最相似的关键点。 点描述通常是非常高维的(比如一百个参数),并且有很多要查看的点。 kd-trees在这里可能很有用,哈希查找不起作用。

变种:

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

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

要开始,请记住,任何有价值的比较方法将基本上工作,将图像转换成不同的forms – 一种forms,更容易select类似的function。 通常情况下,这个东西不会让人读起来很轻

我能想到的最简单的例子之一是简单地使用每个图像的颜色空间。 如果两幅图像具有高度相似的颜色分布,那么您可以合理确定它们显示相同的东西。 至less,你可以有足够的把握来标记它,或者做更多的testing。 比较颜色空间中的图像也将抵制诸如旋转,缩放和某些裁剪之类的事情。 当然,它不会抵制对图像的重大修改或重新着色(甚至简单的色调转换将有点棘手)。

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

另一个例子涉及到一个叫做霍夫变换的东西。 这种转换实质上是将图像分解为一组线条。 然后,你可以在每个图像中采取一些“最强”的线条,看看他们是否排队。 你可以做一些额外的工作来尝试和补偿旋转和缩放 – 在这种情况下,由于比较几行比计算整个图像less得多的计算工作 – 它不会那么糟糕。

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

您将需要使用水印scheme将代码embedded到图像中。 为了退后一步,与一些人提出的一些低级方法(边缘检测等)相反,水印方法是优越的,因为:

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

它抵抗几何攻击►仿射变换►数据缩减 – 裁剪,裁剪等►随机局部失真►翘曲

做一些关于水印algorithm的研究,你将会在正确的道路上解决你的问题。 (注意:您可以使用STIRMARK数据集对您的方法进行基准testing,这是此类应用程序的公认标准。

这只是一个build议,可能无法正常工作,我准备好接受这个build议。

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

  1. 调整两个图像的大小,使它们具有相同的大小(我假设宽度和长度的比率在两个图像中都是相同的)。

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

  3. 查找具有相似文件大小的文件对。 例如,您可以按照文件大小的相似性对每对文件进行sorting,并检索顶部X.

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

我相信,如果你愿意把这个方法应用到每一个可能的方向和负面的版本,图像识别(具有良好的可靠性)的一个好的开始是使用特征: http : //en.wikipedia.org/wiki/Eigenface

另一个想法是将这两个图像转换成其组件的向量。 一个很好的方法是创build一个在x * y维度(x是图像宽度,y是高度)运行的向量,每个维度的值应用于(x,y)像素值。 然后运行K-Nearest Neighbors的变体,它有两个类别:匹配和不匹配。 如果足够接近原始图像,则适合于匹配类别,否则将不适用。

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

KNN的好处在于,与原始图像相比,变体越多,algorithm就越精确。 缺点是你需要一个图像目录来训练系统。

如果你愿意考虑采用不同的方法来检测你的图像的非法拷贝,你可以考虑加水印 。 (从1.4开始)

…将版权信息插入数字对象而不会损失质量。 每当数字对象的版权受到质疑时,就会提取该信息以识别合法的所有者。 也可以将原始买方的身份与版权所有者的身份一起编码,以便追查任何未经授权的副本。

虽然它也是一个复杂的领域,但有一些技术可以使水印信息在整个图像更改中保持不变(从1.9开始)

任何合理强度的信号变换都不能去除水印。 因此,一个愿意去除水印的盗版者将不会成功,除非他们贬低这个文件太多而不符合商业利益。

当然,常见问题解答会要求实施这种方法:“…非常具有挑战性”,但是如果您成功了,那么您对图像是否是副本有一个很高的信心,而不是一个百分比的可能性。

如果你正在运行Linux,我会build议两个工具:

从包裹hugin工具align_image_stack是一个命令行程序,可以自动纠正旋转,缩放和其他扭曲(它主要是为了合成HDR摄影,但也适用于video帧和其他文件)。 更多信息: http : //hugin.sourceforge.net/docs/manual/Align_image_stack.html

从包imagemagick比较 – 一个程序,可以find并计算两个图像中不同像素的数量。 这是一个整洁的教程: http : //www.imagemagick.org/Usage/compare/ uising the -fuzz N%你可以增加错误容忍度。 N越高,误差容忍度依然相同地计数两个像素。

align_image_stack应该纠正任何偏移,所以比较命令实际上有机会检测相同的像素。