Python 从一组值中屏蔽图像像素



提供了一个带有标签的图像(像素的值对应于其标签)以及接受的标签列表,如果像素标签被接受,我正在尝试创建一个具有255值的"蒙版"图像,否则0

我知道这是一种缓慢的方法,因为它以 python 速度迭代图像(但它很好地展示了这个想法):

mask = numpy.zeros(labels.shape[:2], dtype = "uint8")
for i in xrange(mask.shape[0]):
for j in xrange(mask.shape[1]):
if labels[i][j] in accepted:
mask[i][j] = 255

我知道使用 python 切片和掩码要快得多,但我不知道如何编写复杂的条件。当我逐个屏蔽像素接受的标签时,我仍然会得到巨大的加速,如下所示:

for value in accepted:
mask[labels == value] = 255

我可以以某种方式让单行做我想做的事吗?我的 python 知识很生疏(阅读:过去几年几乎没有 python),所以当我尝试使用我找到的一些示例来编写它时,这是我得到的最接近的:

mask[(labels in accepted).all()] = 255

在这种情况下,我收到以下错误:ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

我看过类似的SO问题(例如,这里或这里等等),但它们似乎都涵盖了值来自范围或低于/高于阈值(<10)的情况,或者要更改的图像切片是连续的。

任何关于如何检查"是接受值中的值"的建议都会很棒。

与此同时,我为自己的问题找到了一个可接受的速度解决方案:

mask = numpy.zeros(labels.shape[:2], dtype = "uint8")
mask[numpy.in1d(labels, accepted).reshape(mask.shape)] = 255

它包括首先使用numpy.in1dlabels数组中获取布尔数组,并检查accepted中存在哪些数组(python 关键字"in"的元素函数)。

由于这显然必然返回一个 1D 数组,即使它可以应用于 2D 数组(它只是解开数组),所以我接下来使用reshape()使布尔数组维度对应于mask的维度。

最后,我使用这个布尔数组来索引mask所需的元素,并将它们设置为所需的值。

list_pixels = np.array( [img[x,y,:] for x,y in zip(np.where(bool_obj)[0], np.where(bool_obj)[1])] )

最新更新