关于数组:从 RGB 像素值 python 创建布尔掩码

Creating boolean masks from RGB pixel values python

我有以下带有 RGB 值和相应类的图像掩码:

  • 背景:255 0 0
  • 脸:255 255 0
  • 头发:127 0 0
  • 眼睛:0 0 255
  • nose:0 255 255
  • 嘴巴:0 255 0
  • 现在我想在像素级别上为每个类创建一个布尔 numpy 数组,以便每个像素都有相应的类,即每个 [length, width] 类的布尔数组,每个像素的 True 或 False 取决于是否它属于那个类。

    对于 BG、嘴巴和眼睛,我可以简单地复制轴 0、1 或 2,然后使用 np.bool 将其转换为 True 或 False(255 = True,0 = False)。

    然而,对于其他类,我正在努力让它在不使用双 for 循环的情况下工作。有人可以帮助我在不使用 for 循环的情况下获得我想要的吗?


    您可以利用 numpy 广播:

    一个例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    >>> pprint(labels)
    {'BG': array([255,   0,   0]),
     'eyes': array([  0,   0, 255]),
     'face': array([255, 255,   0]),
     'hair': array([127,   0,   0]),
     'mouth': array([  0, 255,   0]),
     'nose': array([  0, 255, 255])}
    >>> example
    array([[[255,   0,   0],
            [127,   0,   0],
            [255,   0,   0],
            [255,   0,   0]],

           [[255, 255,   0],
            [  0, 255,   0],
            [255,   0,   0],
            [  0, 255,   0]],

           [[  0,   0, 255],
            [255, 255,   0],
            [  0,   0, 255],
            [  0,   0, 255]]])

    使用广播可以同时检查三个频道。然后沿轴 2 使用 all 我们可以选择满足所有三个等式的点。

    1
    >>> masks = {k: (example==v).all(2) for k, v in labels.items()}

    就是这样。结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    >>> pprint(masks)
    {'BG': array([[ True, False,  True,  True],
           [False, False,  True, False],
           [False, False, False, False]]),
     'eyes': array([[False, False, False, False],
           [False, False, False, False],
           [ True, False,  True,  True]]),
     'face': array([[False, False, False, False],
           [ True, False, False, False],
           [False,  True, False, False]]),
     'hair': array([[False,  True, False, False],
           [False, False, False, False],
           [False, False, False, False]]),
     'mouth': array([[False, False, False, False],
           [False,  True, False,  True],
           [False, False, False, False]]),
     'nose': array([[False, False, False, False],
           [False, False, False, False],
           [False, False, False, False]])}

    这样的事情怎么样?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    labels = {'bg' : [255, 0, 0],
    'face' : [255, 255, 0],
    'hair' : [127, 0, 0],
    'eyes' : [0,0,255],
    'nose' : [0, 255, 255],
    'mouth' : [0,255,0],
    }

    arr = np.random.choice([0,127,255], size=(3,500,500)) # simulated image



    for key in labels.keys():
        key_img = (arr[0,...]==labels[key][0]) * (arr[1,...]==labels[key][1]) *     (arr[2,...]==labels[key][2])
        # do something with key_img

    顺便说一句:

    For BG, mouth and eyes, I can simple copy axis 0, 1, or 2 and use np.bool to convert it to True or False (255 = True, 0 = False).

    会导致标签不明确。nose会得分为 BG 和眼睛,例如