PIL TypeError: no se puede manejar este tipo de datos

4 minutos de lectura

avatar de usuario
Jerónimo

Tengo una imagen almacenada en una matriz numpy que quiero convertir a PIL.Image para realizar una interpolación solo disponible con PIL.

Al intentar convertirlo a través de Image.fromarray() genera el siguiente error:

TypeError: no se puede manejar este tipo de datos

He leído las respuestas aquí y aquí, pero no parecen ayudar en mi situación.

Lo que estoy tratando de ejecutar:

from PIL import Image

x  # a numpy array representing an image, shape: (256, 256, 3)

Image.fromarray(x)

  • La pregunta no tiene nada que ver machine-learning o deep-learning – Por favor, no envíe spam con etiquetas irrelevantes (eliminadas).

    – desertnaut

    24 de marzo de 2019 a las 11:27

  • Muestre un ejemplo de cómo se ven sus datos; de lo contrario, es imposible decir cuál es el problema.

    –Mark Setchell

    24 de marzo de 2019 a las 11:45

  • @desertnaut Pensé que dado que uso las imágenes para la clasificación con CNN, las etiquetas podrían ser relevantes.

    – Jerónimo

    25 de marzo de 2019 a las 2:18

  • No, las etiquetas deben ser solo sobre la pregunta. contenidono la contexto; No hay problema, solo tenlo en cuenta para el futuro.

    – desertnaut

    25 de marzo de 2019 a las 4:16

tl; dr

Lo hace x contener uint valores en [0, 255]? Si no, y sobre todo si x va de 0 a 1, esa es la razón del error.


Explicación

La mayoría de las bibliotecas de imágenes (por ejemplo, matplotlib, opencv, scikit-image) tienen dos formas de representar imágenes:

  • como uint con valores que van de 0 a 255.
  • como float con valores que van de 0 a 1.

Este último es más conveniente cuando se realizan operaciones entre imágenes y, por lo tanto, es más popular en el campo de la visión artificial. Sin embargo, PIL parece no es compatible con imágenes RGB.

si echas un vistazo aquí
parece que cuando intenta leer una imagen de una matriz, si la matriz tiene una forma de (height, width, 3) asume automáticamente que es una imagen RGB y espera que tenga un dtype de uint8! En su caso, sin embargo, tiene una imagen RBG con float valores de 0 a 1.


Solución

Puede solucionarlo convirtiendo su imagen al formato esperado por PIL:

im = Image.fromarray((x * 255).astype(np.uint8))

  • ¡Esto realmente ayudó! Es decepcionante que PIL no admita imágenes RBG con valores en [0, 1].

    – Jerónimo

    25 de marzo de 2019 a las 2:16

  • Recibo el siguiente mensaje de advertencia Lossy conversion from float64 to uint8. Range [0, 1]. Convert image to uint8 prior to saving to suppress this warning. ¿Qué significa Rango [0,1] ¿significar? Mi rango de x era [0,2]

    – Jack negro 21

    11 de julio de 2020 a las 7:32


  • @ BlackJack21 Creo que significa que primero debes convertir tu rango a [0,1] luego intente convertirlo usted uint8

    – Djib2011

    11 de julio de 2020 a las 16:38

  • No, traté de hacer eso también, pero el error permaneció. Esto estaba en Jupyter Lab, ¿podría ser algo relacionado con ipynb?

    – Jack negro 21

    11 de julio de 2020 a las 19:04

  • Convirtiendo el tipo a np.uint8 ¡lo hizo! Gracias.

    – U12-Adelante

    24 de marzo de 2021 a las 10:24

avatar de usuario
Poder uzal

yo resuelto es de otra manera.

Situación problemática:
al trabajar con imagen gris o imagen binariasi la forma de matriz numpy es (height, width, 1)este error también se generará.
Por ejemplo, una imagen gris de 32 x 32 píxeles (valor de 0 a 255)

np_img = np.random.randint(low=0, high=255, size=(32, 32, 1), dtype=np.uint8)
# np_img.shape == (32, 32, 1)
pil_img = Image.fromarray(np_img)

elevará TypeError: Cannot handle this data type: (1, 1, 1), |u1

Solución:

Si la forma de la imagen es como (32, 32, 1), reducir la dimensión dentro (32, 32)

np_img = np.squeeze(np_img, axis=2)  # axis=2 is channel dimension 
pil_img = Image.fromarray(np_img)

Esta vez funciona!!

Además, asegúrese de que el dtype es uint8(para gris) o bool(para binario).

En mi caso fue solo porque olvidé agregar el argumento “RGB” en la función “fromarray”.

pil_img = Image.fromarray(np_img, 'RGB')

Encontré un problema diferente para el mismo error en mi caso. La imagen que usé estaba en formato RGBA, así que antes de usar la función fromarray() simplemente conviértala a RGB usando la función convert() y funcionará perfectamente bien.

image_file = Image.open(image_file)
image_file = image_file.convert('RGB')

PD: publicar esta solución como un paso inicial, antes de convertir la imagen a np.

En mi caso, el formato de archivo de las imágenes se cambió a png a jpg. Funcionó bien cuando corregí el formato de imagen de las imágenes de error.

¿Ha sido útil esta solución?