提取具有图像差异的对象

时间:2018-07-27 14:02:49

标签: python opencv image-processing object-detection

使用opencv在Python中进行对象检测。

我有两张照片

  1. 其中没有对象的参考图片。

Picture One

  1. 带有对象的图片。

Picture Two

  1. 图像的结果是:

Result picture

问题是,参考图像的图案现在在我的对象上。我想删除此模式,但我不知道该怎么做。对于进一步的图像处理,我需要对象的正确轮廓。 也许您知道如何修复它,或者有更好的主意来吸引对象。 我很高兴您的帮助。

编辑:4.黑色对象:

Picture with black object

1 个答案:

答案 0 :(得分:2)

@Mark Setchell commented一样,两幅图像的差异显示了包含对象的像素,您不应尝试将其用作输出。而是找到具有明显差异的像素,然后直接从输入图像中读取这些像素。

在这里,我正在使用Otsu阈值法来确定“显着差异”是什么。还有许多其他方法可以做到这一点。然后,我使用蒙版的反像来消除输入图像中的像素。

import PyDIP as dip

bg = dip.ImageReadTIFF('background.tif')
bg = bg.TensorElement(1)   # The image has 3 channels, let's use just the green one
fg = dip.ImageReadTIFF('object.tif')
fg = fg.TensorElement(1)

mask = dip.Abs(bg - fg)               # Difference between the two images
mask, t = dip.Threshold(mask, 'otsu') # Find significant differences only
mask = dip.Closing(mask, 7)           # Smooth the outline a bit
fg[~mask] = 0                         # Blank out pixels not in the mask

enter image description here

我在上面使用的是PyDIP,而不是OpenCV,因为我没有安装OpenCV。您可以使用OpenCV轻松地执行相同的操作。

像我以前那样平滑二进制掩码的另一种方法是在阈值化之前对mask图像进行平滑,例如使用dip.Gauss(mask,[2])(一种高斯平滑)。

编辑:黑色对象。

此图像发生的情况是其照度发生了很大变化,或者您的相机中有一些自动曝光设置。确保已关闭所有功能,以使每张图像曝光完全相同,并且为此直接使用原始图像,而不要使用经过某些自动增强程序甚至是JPEG压缩的图像可以避免。

我计算了背景图像的中位数除以对象图像(在上面的代码中,{fg,但对于这个新图像),得出的平均值为1.073。这意味着背景图像比对象图像亮7%。然后在计算绝对差之前,我将fg乘以该值:

mask = dip.Abs(fg * dip.Median(bg/fg)[0][0] - bg)

这有所帮助,但是它表明整个图像的对比度变化不一致。

接下来,您可以更改阈值选择方法。 Otsu假设双峰直方图,如果每个组(前景和背景)中都有大量像素,则Otsu效果很好。在这里,属于对象的像素会更少,因为只有一些对象像素的颜色与背景颜色不同。 'triangle'方法在这种情况下适用:

mask, t = dip.Threshold(mask, 'triangle')

这将导致仅包含某些对象像素的蒙版。您必须添加有关对象的其他知识(即,它是旋转的正方形)才能找到完整的对象。阈值还拾取了一些孤立的背景像素,使用阈值之前的一些模糊或阈值之后的小开口很容易消除这些背景像素。

在这种情况下,使用当前设置无法获得对象的确切轮廓。我建议您通过以下任一方法来改进设置:

  • 使背景的照明更加均匀
  • 使用颜色(这样可以减少与背景颜色完全匹配的可能对象)
  • 使用红外成像(也许背景与所有要在红外中检测到的物体具有不同的特性?)
  • 使用背照式(如果您要测量物体,这是最好的方法)