Для этого трехмерного изображения у него есть 6 классов, которые:
Impervious surfaces (RGB: 255, 255, 255)
Building (RGB: 0, 0, 255)
Low vegetation (RGB: 0, 255, 255)
Tree (RGB: 0, 255, 0)
Car (RGB: 255, 255, 0)
Clutter/background (RGB: 255, 0, 0)
Я хотел бы передать это изображение на 2d-изображение, где
Impervious surfaces --> 0
Building --> 1
Low vegetation --> 2
Tree --> 3
Car --> 4
Clutter/background --> 5
Я мог только вычислить, чтобы использовать для цикла как:
im = imageio.imread('kPUoO.png')
w,h = im.shape[:2]
im_ = np.zeros((w,h), dtype=np.uint8)
for i in range(w):
for j in range(h):
if list(im[i,j]) == [0,0,255]:
im_[i,j] = 1
if list(im[i,j]) == [0,255,255]:
im_[i,j] = 2
if list(im[i,j]) == [0,255,0]:
im_[i,j] = 3
if list(im[i,j]) == [255,255,0]:
im_[i,j] = 4
if list(im[i,j]) == [255,0,0]:
im_[i,j] = 5
Мне интересно, есть ли более простой способ этой работы. Спасибо!
Я пытался подумать о более общей проблеме, где вы могли бы иметь любую ценность от 0 до 255, присутствующих в каждой группе, или даже более трех групп...
Мы можем кодировать позиции 0 и 255 путем применения другого сдвига бит к каждому столбцу (от 0 до 3 бит для нулей в столбцах 0, 1 и/или 2 и от 4 до 6 бит для 255 в столбцах 0, 1 и/или 2):
a = (im == 0) << numpy.array([0,1,2], numpy.uint8)
a += (im == 255) << numpy.array([3,4,5], numpy.uint8)
Сумма вдоль последней оси тогда однозначно кодирует классы. Разделение на 7 не обязательно, оно просто дает более простые метки классов.
numpy.add.reduce(a, -1) // 7
Оттуда это стандартная карта 1:1 для повторной маркировки классов. Я думаю, что для больших изображений или большого количества изображений этот подход может быть быстрее.
Чтобы увидеть, как это работает:
0,0,0 = 1<<0 + 1<<1 + 1<<2 + 0<<3 + 0<<4 + 0<<5 = 7, /7 = 1
0,0,255 = 1<<0 + 1<<1 + 0<<2 + 0<<3 + 0<<4 + 1<<5 = 35, /7 = 5
0,255,255 = 1<<0 + 0<<1 + 0<<2 + 0<<3 + 1<<4 + 1<<5 = 49, /7 = 7
255,255,255 = 0<<0 + 0<<1 + 0<<2 + 1<<3 + 1<<4 + 1<<5 = 56, /7 = 8
etc...
Эквивалентная формулировка:
a = (im == 0) * numpy.array([1,2,4], numpy.uint8)
a += (im == 255) * numpy.array([8,16,32], numpy.uint8)
numpy.add.reduce(a, -1) //7
im = imageio.imread('kPUoO.png')
w,h = im.shape[:2]
im_ = np.zeros((w,h), dtype=np.uint8)
pos1 = np.where((im[:,:,0]==0) & (im[:,:,1]==0) & (im[:,:,2]==255))
pos2 = np.where((im[:,:,0]==0) & (im[:,:,1]==255) & (im[:,:,2]==255))
pos3 = np.where((im[:,:,0]==0) & (im[:,:,1]==255) & (im[:,:,2]==0))
pos4 = np.where((im[:,:,0]==255) & (im[:,:,1]==255) & (im[:,:,2]==0))
pos5 = np.where((im[:,:,0]==255) & (im[:,:,1]==0) & (im[:,:,2]==0))
im_[pos1] = 1
im_[pos2] = 2
im_[pos3] = 3
im_[pos4] = 4
im_[pos5] = 5
im[0, 0]
равно[ 14, 255, 237]
. В этом изображении более 4000 различных цветов. Изображение хранится в формате JPEG , который является форматом с потерями . Если у вас изначально было только шесть цветов, упомянутых в вопросе, и вы хотите сохранить эти значения точно в файле изображения, используйте формат без потерь, такой как PNG .