Как применить многомерную справочную таблицу к цветному изображению?
Для простоты предположим, что изображение имеет две строки и четыре столбца, а цвета пикселей представлены триплетом уровней интенсивности (интенсивность квантуется до пяти различных целочисленных значений). Я хочу преобразовать такое цветное изображение в одноканальное изображение с помощью трехмерной справочной таблицы, используя уровни интенсивности каждого пикселя в качестве индексов. Этот игрушечный пример может быть реализован следующим образом:
import numpy as np
levels = 5
rows, columns, channels = 2, 4, 3
lut = np.arange(levels**channels).reshape([levels for n in range(channels)])
np.random.seed(0)
img = np.random.randint(low=0, high=levels, size=(rows, columns, channels))
Я знаю, что могу жестко закодировать индексацию следующим образом:
red = img[:, :, 0]
green = img[:, :, 1]
blue = img[:, :, 2]
indexed = lut[red, green, blue]
Приведенный выше код можно обобщить для работы с мультиспектральными изображениями:
indexed = lut[[img[:, :, i] for i in range(channels)]]
Оба подхода дают одинаковый результат:
In [931]: indexed
Out[931]:
array([[103, 91, 89, 4],
[ 55, 30, 48, 15]])
Мой вопрос: есть ли более элегантный способ получить тот же результат? Более конкретно, я ищу функцию NumPy, которая разбивает цветное изображение (трехмерный массив) на список его хроматических каналов (двумерные массивы). В качестве альтернативы я думал, что преобразование может быть выполнено с помощью matplotlib, используя lut
как цветовая карта.
1 ответ
Это:
red, green, blue = img.transpose()
lut[red, green, blue].transpose()
что ты ищешь?
img.transpose()
необходим для перестановки осей, ожидаемых для распаковки канала.
Для произвольного количества каналов:
lut[tuple(img.transpose())].transpose()