如何在python中屏蔽对象的轮廓

时间:2015-05-19 19:31:00

标签: python opencv image-processing numpy python-imaging-library

如何屏蔽图像中的对象,例如通过概述对象的形状或存储数组作为对象一部分的所有像素的索引?由于我将仅在具有对象的区域中进行其他进一步处理,因此我想“摆脱”/忽略背景并仅关注对象本身。

这两个图像(物体是金属球和光散射球)与我将要处理的相似。我将尝试改善对象和背景之间的对比度,并在我拍摄更多图像时处理支撑物体的支撑“支架”,但是对于这里给出的图像,有没有办法掩盖物体?

最初,我想对图像进行阈值处理,以便保留比某个值“更亮”的像素,然后使用numpy.nonzero(threshold_image)找出像素的所有像素的所有索引。图片。但是,我发现它对于这种“嘈杂”的图像效果不佳。

谢谢

metal ball scattering ball

2 个答案:

答案 0 :(得分:3)

理论上可以使用Numpy's masked arrays来存储数组的掩码,但是我不推荐它(性能方面它非常慢,我将稍后编辑我的帖子)

最Pythonic方式(因此最酷)只是存储一个与图像大小相同的普通bool数组,并使用*运算符来组合它(因为数字乘以False变为0,除了明显的例外NaN

# creates an array of bool of same shape as image
maskAboveThreshold = image > 30 

# Show a 'cropped' version on the image
from matplotlib import pyplot as plt
plt.imshow(image * maskAboveThreshold, cmap='gray')

请注意,我在此假设image是灰度的2D图像,但只要您的蒙版形状与图像相同,它就可以在任何维度上工作。

至于图像的分离,我不知道你对图像处理技术有多熟悉,但总的来说,在你发现噪音很麻烦的情况下,在其他任何东西通常有效之前模糊你的图像,因为小区域的隐含平均意味着噪声(尖峰)被平滑。

迭代ndarrays的旁注: 您可能不想迭代np.nonzero()输出,因为像素位置会给您带来未分类的含义,这意味着您将最终访问图像中的随机位置而不是访问连续(跟随彼此)地址,是一种常见的“内存访问最坏情况”,会降低执行速度。

对于二进制图像处理,例如删除掩码中的小孤立像素组,请查看Binary Morphology

答案 1 :(得分:2)

您可以从输入图像的每个颜色通道(r,g,b)进行阈值处理。下部图像中的对象应该可以在绿色通道中分离,对于顶部图片,即使只是亮度也可以做好初始工作。

掩码中的第二步是labeling connected components,也许使用上面链接中的函数。

最后,您可以按尺寸/形状选择最佳组件。

如果你的所有物体都是圆圈,你可以从形状开始检测它们 - 这意味着要进行边缘检测然后Hough Transfrom