Как выбрать все не черные пиксели в массиве NumPy? - PullRequest
0 голосов
/ 10 октября 2018

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

Например, при обработке следующего изображения:

enter image description here

Мне удалось получить список всех черных пикселей, используя:

np.where(np.all(mask == [0,0,0], axis=-1))

Но когда я пытаюсь сделать:

np.where(np.all(mask != [0,0,0], axis=-1))

Iполучаю довольно странный результат:

enter image description here

Похоже, NumPy вернул только индексы, где R, G и B не равны 0

Вот минимальный пример того, что я пытаюсь сделать:

import numpy as np
import cv2

# Read mask
mask = cv2.imread("path/to/img")
excluded_color = [0,0,0]

# Try to get indices of pixel with different colors
indices_list = np.where(np.all(mask != excluded_color, axis=-1))

# For some reason, the list doesn't contain all different colors
print("excluded indices are", indices_list)

# Visualization
mask[indices_list] = [255,255,255]

cv2.imshow(mask)
cv2.waitKey(0)

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Вы должны использовать np.any вместо np.all для второго случая выбора всех пикселей, кроме черных:

np.any(image != [0, 0, 0], axis=-1)

Или просто получитьдополнение черных пикселей путем инвертирования логического массива на ~:

black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)
non_black_pixels_mask = ~black_pixels_mask

Рабочий пример:

import numpy as np
import matplotlib.pyplot as plt


image = plt.imread('example.png')
plt.imshow(image)
plt.show()

enter image description here

image_copy = image.copy()

black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)

non_black_pixels_mask = np.any(image != [0, 0, 0], axis=-1)  
# or non_black_pixels_mask = ~black_pixels_mask

image_copy[black_pixels_mask] = [255, 255, 255]
image_copy[non_black_pixels_mask] = [0, 0, 0]

plt.imshow(image_copy)
plt.show()

enter image description here


В случае, если кто-то использует matplotlib для отображения результатов и получает полностьюЧерное изображение или предупреждения, см. этот пост: Преобразование всех не черных пикселей в один цвет не приводит к ожидаемому выводу

0 голосов
/ 10 октября 2018

Необходимость: нужна матрица с этой формой = (любая, любая, 3)

Решение:

COLOR = (255,0,0)
indices = np.where(np.all(mask == COLOR, axis=-1))
indexes = zip(indices[0], indices[1])
for i in indexes:
    print(i)

Решение 2:

получить интервал определенного цвета, например КРАСНЫЙ:

COLOR1 = [250,0,0]
COLOR2 = [260,0,0] # doesnt matter its over limit

indices1 = np.where(np.all(mask >= COLOR1, axis=-1))
indexes1 = zip(indices[0], indices[1])

indices2 = np.where(np.all(mask <= COLOR2, axis=-1))
indexes2 = zip(indices[0], indices[1])

# You now want indexes that are in both indexes1 and indexes2

Решение 3 - РАБОТАЕТ

Если предыдущий не работает, тоесть одно решение, которое работает на 100%

Преобразование из канала RGB в HSV.Сделать 2D маску из 3D изображения.2D маска будет содержать значение Hue.Сравнение оттенков проще, чем RGB, поскольку оттенок равен 1 значению, а RGB - вектор с тремя значениями.После того, как у вас есть 2D-матрица со значениями оттенков, сделайте, как указано выше:

HUE1 = 0.5
HUE2 = 0.7 

indices1 = np.where(HUEmask >= HUE1)
indexes1 = zip(indices[0], indices[1])

indices2 = np.where(HUEmask <= HUE2)
indexes2 = zip(indices[0], indices[1])

Вы можете сделать то же самое для насыщенности и значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...