Следующий фрагмент создаст тестовое изображение
# Create 3x3x3 image
test_image = []
for i in range(9):
if i < 6:
image.append([255, 22, 96])
else:
image.append([255, 0, 0])
Вне:
array([[[255, 22, 96],
[255, 22, 96],
[255, 22, 96]],
[[255, 22, 96],
[255, 22, 96],
[255, 22, 96]],
[[255, 0, 0],
[255, 0, 0],
[255, 0, 0]]], dtype=int32)
Моя цель создать одноканальное изображение нулей НО для каждого [255, 22, 96] в test_image, я хочу установить число 100 в новом изображении single_channel:
Я пробовал следующее:
test_image = np.array(test_image)
height, width, channels = test_image.shape
single_channel_img = np.zeros(test_image.shape, dtype=int)
msk = test_image == [255, 22, 96] # DOES NOT WORK AS EXPECTED
single_channel_img[msk] = 100
Что не работает, потому что результат маскировки:
msk = test_image == [255, 22, 96]
возвращает:
array([[[ True, True, True],
[ True, True, True],
[ True, True, True]],
[[ True, True, True],
[ True, True, True],
[ True, True, True]],
[[ True, False, False],
[ True, False, False],
[ True, False, False]]])
Почему маскирование возвращает True для последних 3 пикселей и как я могу убедиться, что это сравнение возвращает True, только если все 3 значения одинаковы? Мое предположение заключалось в том, что способ, которым я маскирую, должен просто возвращать True, когда все 3 значения RGB равны [255, 22, 96].
@TimRoberts это решило это для меня. Я действительно думал, что numpy выполняет сравнение по каналам, если я предоставляю список с 3 элементами внутри.






Вы можете преобразовать msk в трехмерный массив, используя вещание массива:
https://numpy.org/doc/stable/user/basics.broadcasting.html
Команду .reshape можно использовать для изменения размеров массива. Numpy автоматически заполнит «тонкое» измерение. Так, например, сравнение массивов с фигурами (n,n,3) и (1,1,3) аналогично сравнению каждого подмассива test_image[i,j,:] с целью (1,1,3).
import numpy as np
# Create 3x3x3 image
test_image = []
for i in range(9):
if i < 6:
test_image.append([255, 22, 96])
else:
test_image.append([255, 0, 0])
test_image = np.array(test_image).reshape((3,3,3)) # test image shape needed to be fixed
single_channel_img = np.zeros(test_image.shape, dtype=int)
msk = test_image == np.array([255,22,96]).reshape((1,1,3)) # now it works
single_channel_img[msk] = 100
print(single_channel_img)
# [[[100 100 100]
# [100 100 100]
# [100 100 100]]
#
# [[100 100 100]
# [100 100 100]
# [100 100 100]]
#
# [[100 0 0]
# [100 0 0]
# [100 0 0]]]
PS. PyTorch также имеет широковещательную рассылку массивов, это действительно полезно в глубоком обучении.
Спасибо за хорошее объяснение. Теперь я могу правильно кодировать свои метки для сегментации изображения.
Numpy не знает о пикселях. Он сравнивает элементы массива один за другим. Вы можете использовать
all, чтобы уменьшить это. Я считаю, чтоmsk.all(axis=2)должен это сделать. Он возвращает true, если все части верны.