简体   繁体   English

Python从一组值遮罩图像像素

[英]Python mask image pixels from a set of values

Provided an image with labels (the value of a pixel corresponds to its label), and the list of labels that are accepted, I am trying to create a "mask" image with 255 value if the pixels label is accepted, 0 otherwise. 提供一个带有标签的图像(一个像素的值与其标签相对应)以及可接受的标签列表,如果像素标签被接受,我试图创建一个值为255的“蒙版”图像,否则创建0

I know that this is a slow approach as it iterates over the image at python-speed (but it demonstrates the idea well): 我知道这是一种缓慢的方法,因为它以python-speed的速度遍历图像(但是很好地展示了这个想法):

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

I know that it is much faster to use python slicing and masking, but I do not know how to compose a complicated condition. 我知道使用python切片和遮罩要快得多,但我不知道如何编写复杂的条件。 I still get a tremendous speed-up when I mask the pixels one-by-one accepted label, like so: 当我逐一遮盖像素接受的标签时,我仍然可以大大提高速度,如下所示:

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

Can I somehow make a one-liner doing what I want? 我能以某种方式使单线工作成为我想要的吗? My python knowledge is rusty (read: almost no python in the last few years), so while I tried composing this using some examples I found, this is the closest I got: 我的python知识是生锈的(阅读:最近几年几乎没有python),因此当我尝试使用发现的一些示例来编写此代码时,这是我得到的最接近的代码:

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

And in this case I get the following error: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 在这种情况下,我得到以下错误: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I've looked at similar SO questions (eg here or here and more) but they all seem to cover the cases where either the values are from a range or lower/higher than a threshold (<10) , or where the image slice to change is continuous. 我看过类似的SO问题(例如, 此处此处以及更多),但它们似乎都涵盖了值在某个范围内或低于/高于阈值(<10)或图像切片为变化是连续的。

Any suggestion on how check "is value among accepted values" would be great. 关于如何检查“可接受的值中的值”的任何建议都很好。

In the meantime, I found an acceptable-speed solution to my own question: 同时,我为自己的问题找到了可接受的速度解决方案:

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

It consists in first using numpy.in1d to get a boolean array from the labels array, and check which ones are present in accepted (element-wise function of the python keyword "in"). 它包括首先使用numpy.in1dlabels数组中获取一个布尔数组,并检查accepted数组中存在哪些(python关键字“ in”的逐元素函数)。

As this apparently necessarily returns a 1D array, even if it can be applied to a 2D array (it simply unravels the array), so I follow by using reshape() to make the boolean array dimensions correspond to that of the mask . 因为这显然必须返回一个1D数组,即使它可以应用于2D数组(它只是解散该数组),所以我接下来使用reshape()使布尔数组的尺寸与mask尺寸相对应。

Finally, I use this boolean array to index the required elements of mask and set them to a desired value. 最后,我使用此布尔数组为mask的必需元素编制索引并将其设置为所需的值。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM