2010-03-31 69 views
8

任务:我们在我们装配线的末端安装了摄像头,其中 捕获生产物品的图像。举个例子说,我们 产生票(其上有一些文字和图片)。所以每张 产生的票都被拍成照片并保存到磁盘上作为图像。现在我 想检查这些保存的图像的异常(即比较 他们的图像(模板),这是OK)。因此,如果在我们的组装线上出现问题 (包含缺失图片,污点等),我的 应用程序应该找到它(因为它的图像与我的 模板相差太多)。比较图像以找出差异

问:什么是最简单的方法来比较图片,并找到他们之间的差异?我是否需要编写自己的方法,或者我可以使用现有的方法吗?如果我只是设置一个容差值 (即图像可以不同于1%),将会很好,将两个图像放在一个函数中,并获得返回值true或false :)

工具:C#或VB。 NET,Emgu.CV(OpenCV的.NET包装)或类似的东西

回答

2

我支持d建议看看AForge Imaging library,因为它对这类工作有很多真正有用的功能。

有几种方法可以使用:

  1. 简单的减法(模板图像 - 电流),看看有多少像素是不同的。您可能想要对结果进行阈值设置,即只包含10或更多(例如)不同的像素。
  2. 如果票据可以在视野内移动,那么物品1)将不起作用,除非您可以先查找票证。例如,如果票据在黑色背景上是白色的,那么您可以在图片上设置一个阈值,这会让您知道票据的位置。
  3. 我之前使用过的另一种技术是“模型查找”或“模式匹配”,但我只知道包含这些函数的商业库Matrox Imaging Library(或MIL),因为它们不是微不足道的。

此外,您还需要确保知道票的哪些部分更重要。例如,我猜想一个缺失的标志或水印是一个大问题。但是一些区域可能有可变的文本,比如序列号,所以你会期望它们有所不同。基本上你可能需要将图像的某些区域与其他区域区别开来。

1

我不知道细节,但我知道在高吞吐量是必不可少的工业环境中,有时候使用神经网络来完成。它们将数百万位(相机像素)变成1(好或坏)。 也许这会帮助你进行搜索。

3

我对OpenCV并不了解,但对图像处理有点不了解。

要走的路要看拍摄新照片的频率。一个简单的方法是计算一个你'好'的模板和你实际产品的图像的差异图片。

如果图像是100%相同的,您的结果图像应该是空的。如果存在残余像素,则可以将这些像素计数,并将其作为偏离标准的度量。

但是,您必须匹配其中一个图像的方向(以及可能的比例)以对齐边界,否则此方法将无法使用。

如果您有时间限制,您可能需要在处理图像之前减少图像中的信息(例如,使用边缘检测和/或将其转换为灰度甚至单色位图(如果产品的功能足够重要)

1

肯定有应用程序和库已经做了你想做的事情,但我不知道任何手段。很明显,我们可以将这两个图像进行散列并进行比较,但是期望的结果是完全相同,并且不会为光线差异或类似情况留下任何余地。

假设你已经控制了图像中的物体,等同定向和定位相同,有一件事你可能做的是通过每幅图像的像素游行,并得到各的HSV值,就像这样:

Color color1 = Image1.GetPixel(i,j); 
Color color2 = Image2.GetPIxel(i,j); 
float hue1 = color1.GetHue(); 
float sat1 = color1.GetSaturation(); 
float bright1 = color1.GetBrightness(); 
float hue2 = color2.GetHue(); 
float sat2 = color2.GetSaturation(); 
float bright2 = color2.GetBrightness(); 

并与这些值做一些比较。这可以让你比较它们,我认为,比使用RGB值更可靠,特别是因为你想在你的比较中包含一些容差。


编辑:

只是为了好玩,我写了上面使用我的想法有点示例应用程序。基本上,它总计了H,S和V值相差一定数量(我选择0.1作为我的值)的像素数量,然后如果H,S或V计数器超过38400或2%像素(0.02 * 1600 * 1200)。在最糟糕的情况下,比较两张相同的图像需要大约2秒。当我比较一幅被改变的图像超过2%的值时,通常会花费几分之一秒。

很明显,如果每秒都会产生大量图像,这可能会太慢,但我认为这很有趣。

+0

散列是一个不错的主意,但由于每个图像的像素数量很大(想到1600 * 1200字节或灰度为1.875 MB),整个图像上的像素逐像素分析不会产生最佳性能 – sum1stolemyname 2010-03-31 14:51:27

+0

似乎就像它取决于所用算法的速度一样,因为任何预计能够识别1-2%的差异的算法都必须遍历整个文件。 也许做一个快速减去图像,然后总结余下的。这将尽可能快地完成,同时仍然检查整个图像。 – tloflin 2010-03-31 16:16:40

1

This guy here为同样的问题写了一个简单的Java代码。我想,将其转换为C#并不难。它工作得很好,也可以找到一个更新更强的版本。