Маскируйте изображение, где маскированные пиксели существуют в списке значений пикселей - PullRequest
0 голосов
/ 28 сентября 2018

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

Рассмотрим следующие «изображения» и «значения пикселей»

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

Я пытаюсь придумать некоторую процедуру, которая выведет массив 2d маски, где маскированные значения соответствуют значениям пикселей всписок pixels

Цель:

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

Попытка 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) Iполагаем, что этот ответ предполагает 2-мерный ввод в виде 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(), но представьте, что есть более краткий подход, чем циклическое прохождение каждого значения.

Ответы [ 4 ]

0 голосов
/ 29 сентября 2018

Решение, которое я нашел, которое быстрее, чем другие ответы на данный момент, и требует минимальной дополнительной памяти:

mask = numpy.zeros( img.shape[:2], dtype=bool )
for pixel in numpy.unique(pixels, axis=0):
    mask |= (img == pixel).all(-1)
0 голосов
/ 28 сентября 2018

Преобразуйте ваш 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 возвращает одно значение истинности.

0 голосов
/ 28 сентября 2018

Настройка

Убедитесь, что ваш pixels является numpy.array первым:

pixels = np.array(pixels)

Вы можете сделатьИспользование вещания здесь, только будьте осторожны, чтобы не слишком высокая потребность в памяти:

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

array([[1, 0, 0],
       [1, 0, 0],
       [0, 0, 0]])
0 голосов
/ 28 сентября 2018

Вы получаете ValueError, потому что вы используете np.array как «input» для оператора if.Но это должен быть номер или число.Когда вы используете numpy.all, вы превращаете массив NumPy в логическое значение (это правда, когда все элементы отличаются, чем ноль).

Решение

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...