Создание логических масок из значений RGB пикселей Python - PullRequest
0 голосов
/ 14 марта 2019

У меня есть следующие маски изображений со значениями RGB и соответствующими классами:

  1. BG: 255 0 0
  2. лицо: 255 255 0
  3. волосы: 127 0 0
  4. глаза: 0 0 255
  5. нос: 0 255 255
  6. рот: 0 255 0

Теперь я хочу, чтобы у каждого класса на уровне пикселей был логический массив NumPy, чтобы на каждый пиксель у меня был соответствующий класс, т. Е. Логический массив на класс [length, width] с True или False для каждого пикселя, в зависимости от того, он принадлежит к этому классу.

Для BG, рта и глаз, я могу просто скопировать ось 0, 1 или 2 и использовать np.bool, чтобы преобразовать его в True или False (255 = True, 0 = False).

Однако для других классов я изо всех сил пытаюсь заставить это работать, не используя двойной цикл for. Может ли кто-нибудь помочь мне получить то, что я хочу, без использования цикла for?

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

Вы можете использовать широковещательную трансляцию:

Пример:

>>> 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]]])

При использовании трансляции можно одновременно проверить три канала.Затем, используя all вдоль оси 2, мы можем выбрать точки, которые удовлетворяют всем трем равенствам.

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

Вот и все.Результат:

>>> 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]])}
0 голосов
/ 14 марта 2019

как насчет этого?

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

кстати:

Для BG, рта и глаз, я могу просто скопировать ось 0, 1 или 2 и использовать np.bool для преобразования его в True или False (255 = True, 0 = False).

приведет к неоднозначным меткам.нос будет забиваться как BG и глаза, например

...