使用opencv在Python中进行对象检测。
我有两张照片
问题是,参考图像的图案现在在我的对象上。我想删除此模式,但我不知道该怎么做。对于进一步的图像处理,我需要对象的正确轮廓。 也许您知道如何修复它,或者有更好的主意来吸引对象。 我很高兴您的帮助。
编辑:4.黑色对象:
答案 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
我在上面使用的是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')
这将导致仅包含某些对象像素的蒙版。您必须添加有关对象的其他知识(即,它是旋转的正方形)才能找到完整的对象。阈值还拾取了一些孤立的背景像素,使用阈值之前的一些模糊或阈值之后的小开口很容易消除这些背景像素。
在这种情况下,使用当前设置无法获得对象的确切轮廓。我建议您通过以下任一方法来改进设置: