50

Tengo un problema simple pero no puedo encontrar una buena solución para él.Cómo convertir matriz Numpy a imagen PIL aplicando matplotlib colormap

Quiero tomar una matriz numpy 2D que representa una imagen en escala de grises, y convertirla en una imagen PIL RGB mientras aplica algunos de los mapas de color matplotlib.

puedo obtener una salida PNG razonable utilizando el comando pyplot.figure.figimage:

dpi = 100.0 
w, h = myarray.shape[1]/dpi, myarray.shape[0]/dpi 
fig = plt.figure(figsize=(w,h), dpi=dpi) 
fig.figimage(sub, cmap=cm.gist_earth) 
plt.savefig('out.png') 

Aunque podría adaptar esta a conseguir lo que quiero (probablemente utilizando StringIO hacer llegar la imagen PIL), me pregunto si hay no es una forma más sencilla de hacerlo, ya que parece ser un problema muy natural de visualización de imágenes. Digamos algo como esto:

colored_PIL_image = magic_function(array, cmap) 

¡Gracias por su lectura!

+0

Para un código completamente funcional, puede ref: [¿Hay algún buen mapa de color para convertir la imagen en escala de grises en colores usando el PIL de Python?] (Http://stackoverflow.com/questions/43457308/is-there-any- good-color-map-to-convert-gray-scale-image-to-colorful-ones-using-p) – Adam

Respuesta

99

Bastante ocupado un trazador de líneas, pero aquí está:

  1. En primer lugar asegurarse de que su matriz numpy, myarray, se normaliza con el valor máximo en 1.0.
  2. Aplicar el mapa de colores directamente al myarray.
  3. Escala al rango 0-255.
  4. Convierte a enteros, usando np.uint8().
  5. Utilice Image.fromarray().

y ya está:

from PIL import Image 
im = Image.fromarray(np.uint8(cm.gist_earth(myarray)*255)) 

con plt.savefig():

enter image description here

con im.save():

enter image description here

+4

El "Aplicar el mapa de color directamente a 'myarray'" parte cortada directamente al corazón! ¡No sabía que fuera posible, gracias! – heltonbiker

+0

@heltonbiker - sí, es genial;) – fraxel

+27

Estudiando los documentos sobre LinearSegmentedColormap (de la cual cm.gist_earth es una instancia), descubrí que es posible llamarlo con un argumento de "bytes" que ya lo convierte en uint8. Entonces, el one-liner se pone mucho más silencioso: 'im = Image.fromarray (cm.gist_earth (myarray, bytes = True))' – heltonbiker

Cuestiones relacionadas