Там могут быть лучшие способы сделать это;Я не уверен.Если вы прочитаете help(cm.jet)
, вы увидите алгоритм, используемый для сопоставления значений в интервале [0,1] с 3-кортежами RGB.С небольшим количеством бумаги и карандаша вы могли бы разработать формулы для инвертирования кусочно-линейных функций, которые определяют отображение.
Однако существует ряд проблем, которые делают решение для бумаги и карандаша несколько непривлекательным:
Это много трудоемкой алгебры, и решение является специфическим для cm.jet.Вам придется снова проделать всю эту работу, если вы измените карту цветов.Как автоматизировать решение этих алгебраических уравнений интересно, но я не знаю, как решить эту проблему.
В общем случае карта цветов может быть необратимой (может быть несколько значенийбыть сопоставлены с тем же цветом).В случае cm.jet значения от 0,11 до 0,125 отображаются, например, в 3-кортеже RGB (0,0,1).Поэтому, если ваше изображение содержит чистый синий пиксель, на самом деле нет никакого способа узнать, пришло ли оно из значения 0,11 или, скажем, 0,125.
- Отображение из [0,1] к 3-кортежу - это кривая в 3-пространстве.Цвета на вашем изображении могут не идеально лежать на этой кривой.Например, может быть ошибка округления.Таким образом, любое практическое решение должно иметь возможность интерполировать или каким-либо образом проецировать точки в трехмерном пространстве на кривую.
Из-за проблемы неединственности и проблемы проекции / интерполяции может быть многовозможные решения проблемы, которую вы ставите.Ниже приведена только одна возможность.
Вот один из способов решения проблем уникальности и проекции / интерполяции:
Создайте gradient
, который действует как «кодовая книга».gradient
- это массив RGBA 4-х кортежей в цветовой карте cm.jet.Цвета gradient
соответствуют значениям от 0 до 1. Используйте функцию векторного квантования scipy scipy.cluster.vq.vq , чтобы отобразить все цвета в вашем изображении, mri_demo.png, на ближайший цвет.в gradient
.Поскольку цветовая карта может использовать один и тот же цвет для многих значений, градиент может содержать повторяющиеся цвета.Я оставляю до scipy.cluster.vq.vq
, чтобы решить, какой (возможно) неуникальный индекс кодовой книги связать с конкретным цветом.
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
import scipy.cluster.vq as scv
def colormap2arr(arr,cmap):
# /2669779/kak-preobrazovat-izobrazhenie-tsvetovoi-karty-v-skalyarnye-znacheniya
gradient=cmap(np.linspace(0.0,1.0,100))
# Reshape arr to something like (240*240, 4), all the 4-tuples in a long list...
arr2=arr.reshape((arr.shape[0]*arr.shape[1],arr.shape[2]))
# Use vector quantization to shift the values in arr2 to the nearest point in
# the code book (gradient).
code,dist=scv.vq(arr2,gradient)
# code is an array of length arr2 (240*240), holding the code book index for
# each observation. (arr2 are the "observations".)
# Scale the values so they are from 0 to 1.
values=code.astype('float')/gradient.shape[0]
# Reshape values back to (240,240)
values=values.reshape(arr.shape[0],arr.shape[1])
values=values[::-1]
return values
arr=plt.imread('mri_demo.png')
values=colormap2arr(arr,cm.jet)
# Proof that it works:
plt.imshow(values,interpolation='bilinear', cmap=cm.jet,
origin='lower', extent=[-3,3,-3,3])
plt.show()
Изображение, которое вы видите, должно быть близко к воспроизведению mri_demo.png:
(Исходный файл mri_demo.png имел белую рамку. Так как белыйэто не цвет в cm.jet, обратите внимание, что scipy.cluster.vq.vq
отображает белый цвет на ближайшую точку в кодовой книге gradient
, которая бывает бледно-зеленого цвета.)