Как применить многомерную справочную таблицу к цветному изображению?

Для простоты предположим, что изображение имеет две строки и четыре столбца, а цвета пикселей представлены триплетом уровней интенсивности (интенсивность квантуется до пяти различных целочисленных значений). Я хочу преобразовать такое цветное изображение в одноканальное изображение с помощью трехмерной справочной таблицы, используя уровни интенсивности каждого пикселя в качестве индексов. Этот игрушечный пример может быть реализован следующим образом:

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()
Другие вопросы по тегам