【问题标题】:Mask an image where masked pixels exist in list of pixel values屏蔽像素值列表中存在被屏蔽像素的图像
【发布时间】:2018-09-28 18:15:54
【问题描述】:

我正在尝试屏蔽一个图像,其中屏蔽值对应于列表中的多个值中的任何一个。

考虑以下“图像”和“像素值”

import numpy

img = numpy.arange(27).reshape(3,3,3) #something to represent an image
pixels = [numpy.array([0,1,2]), numpy.array([9,10,11])] #arbitrarily selected "pixel" values

我正在尝试提出一些程序,该程序将输出一个二维掩码数组,其中掩码值对应于列表中的像素值pixels

目标:

In [93]: mask
Out[93]: 
array([[1, 0, 0],
       [1, 0, 0],
       [0, 0, 0]])

来自this answer的尝试1:

mask = numpy.zeros( img.shape[:2], dtype = "uint8" )
mask[numpy.in1d(img, pixels).reshape(mask.shape)] = 1

这导致ValueError: cannot reshape array of size 27 into shape (3,3) 我相信这个答案假设二维输入为img

尝试 2:

mask = numpy.zeros(img.shape[:2])
for x,y in [(x,y) for x in range(img.shape[0]) for y in range(img.shape[1])]:
    if img[x,y,:] in pixels:
        mask[x,y] = 1

这会产生ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all(),但想象一下,有一种比循环遍历每个值更简洁的方法。

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    设置

    首先确保您的pixelsnumpy.array

    pixels = np.array(pixels)
    

    这里可以使用广播,注意内存要求不要太高:

    (img[:, None] == pixels[:, None]).all(-1).sum(1)
    

    array([[1, 0, 0],
           [1, 0, 0],
           [0, 0, 0]])
    

    【讨论】:

      【解决方案2】:

      你得到一个 ValueError,因为你使用 np.array 作为 if 语句的“输入”。但它必须是一个布尔值或一个数字。当您使用numpy.all 时,您会将 numpy 数组转换为布尔值(当所有元素都不同然后为零时为 True)。

      解决方案

      for x,y in [(x,y) for x in range(img.shape[0]) for y in range(img.shape[1])]:
              if numpy.all(numpy.isin(img[x, y, :], pixels)):
                  mask[x,y] = 1
      

      【讨论】:

        【解决方案3】:

        将您的 pixels 转换为列表列表,然后您可以使用简单的列表理解来做到这一点:

        pixels = [list(pixel) for pixel in pixels]
        mask = [[int(list(row) in pixels) for row in i] for i in img]
        

        输出:

        [[1, 0, 0], [1, 0, 0], [0, 0, 0]]
        

        当您使用== 进行比较时,np.array 会为每个元素返回一个值,这就是为什么当您使用in 进行比较时会出现该错误的原因。 sublist in list 返回一个真值。

        【讨论】:

          【解决方案4】:

          我发现的一个解决方案比迄今为止的其他答案更快,并且需要最少的额外内存:

          mask = numpy.zeros( img.shape[:2], dtype=bool )
          for pixel in numpy.unique(pixels, axis=0):
              mask |= (img == pixel).all(-1)
          

          【讨论】:

            猜你喜欢
            • 2017-08-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-07-02
            • 2013-10-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多