Puede haber mejores maneras de hacer esta; No estoy seguro. Si lee help(cm.jet)
, verá el algoritmo utilizado para mapear valores en el intervalo [0,1] a RGB 3-tuplas. Podrías, con un poco de papel y lápiz, elaborar fórmulas para invertir las funciones lineales por tramos que definen el mapeo.
Sin embargo, hay una serie de cuestiones que hacen que la solución de papel y lápiz algo poco atractivo:
Es mucho más laboriosa del álgebra, y la solución es específico para cm.jet. Tendría que hacer todo este trabajo nuevamente si cambia el mapa de colores. Cómo automatizar la resolución de estas ecuaciones algebraicas es interesante, pero no es un problema que sepa cómo resolverlo.
En general, el mapa de color puede no ser invertible (se puede asignar más de un valor al del mismo color). En el caso de cm.jet, los valores entre 0.11 y 0.125 se asignan todos al RGB 3-tuple (0,0,1), por ejemplo. Por lo tanto, si su imagen contiene un píleo azul puro , realmente no hay forma de que diga si proviene de un valor de 0.11 o un valor de, digamos, 0.125.
- La asignación de [0,1] a 3-tuplas es una curva en 3 espacios. Los colores en su imagen pueden no estar perfectamente en esta curva. Es posible que sea un error de redondeo, por ejemplo. Entonces, cualquier solución práctica tiene que poder interpolar o de alguna manera proyectar puntos en 3 espacios en la curva.
Debido a la falta de exclusividad y al problema de proyección/interpolación, puede haber muchas soluciones posibles al problema que plantea. A continuación hay solo una posibilidad.
Aquí es una forma de resolver los problemas de singularidad y proyección/interpolación:
Crear una gradient
que actúa como un "libro de códigos". El gradient
es una matriz de 4-tuplas RGBA en el mapa de colores cm.jet. Los colores de gradient
corresponden a valores de 0 a 1. Utilice la función de cuantificación de vector de scipy scipy.cluster.vq.vq para asignar todos los colores en su imagen, mri_demo.png, al color más cercano en gradient
. Dado que un mapa de color puede usar el mismo color para muchos valores, el degradado puede contener colores duplicados. Lo dejo en scipy.cluster.vq.vq
para decidir qué (posiblemente) índice de libro de código no único para asociar con un color en particular.
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
import scipy.cluster.vq as scv
def colormap2arr(arr,cmap):
# http://stackoverflow.com/questions/3720840/how-to-reverse-color-map-image-to-scalar-values/3722674#3722674
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()
La imagen que se ve debe estar cerca de reproducción mri_demo.png:
(El mri_demo.png original tenía un borde blanco Puesto que el blanco no es un color en cm.jet. , tenga en cuenta que scipy.cluster.vq.vq
mapas en blanco a al punto más cercano en el libro gradient
código, que pasa a ser de un color verde pálido.)
Sí, esto es esencialmente lo que pensé que era posible. Su solución inicial incluía leer una línea de una imagen con el mismo mapa de color, lo que puede ser útil para las personas que dicen, escanean una figura y quieren hacer su propio análisis numérico. Me estaba quedando atrapado en la cuantificación del vector: inicialmente, parecía que la mejor opción era recorrer cada color posible en el lut y calcular una distancia en 3D del valor real del píxel, que no podía ver cómo hacerlo rápidamente sin bucle ¡Gracias! – user448764