提供了一个带有标签的图像(像素的值对应于其标签)以及接受的标签列表,如果像素标签被接受,我正在尝试创建一个具有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.in1d
从labels
数组中获取布尔数组,并检查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])] )