Pasar a gris deja un número por píxel
Convertir una imagen a escala de grises es cambiar los tres números de cada píxel por uno solo, que dice cuánta luz hay. Casi todo el análisis de imágenes empieza así, porque medir un número es más fácil que medir tres.
Hoy aprendes la fórmula y la aplicas a mano.
Al final de esta lección
Nota
Puedo convertir una imagen en color a gris con los pesos de luminosidad.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Escala de grises | imagen con un solo número por píxel, de 0 a 255 | |
| Luminosidad | la luz que percibe el ojo en un punto | |
| Peso | cuánto cuenta cada canal en la suma | 0,587 |
| Modo L | el modo de Pillow con un solo canal de gris | |
| Media simple | sumar los tres canales y dividir entre tres |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
El ojo ve más claro el verde
Si sumas los tres canales y divides entre tres, un verde puro sale mucho más oscuro de lo que lo ves. El ojo es más sensible al verde que al rojo, y mucho más que al azul.
Por eso la luminosidad da a cada canal un peso distinto: 0,299 al rojo, 0,587 al verde y 0,114 al azul. Los tres pesos suman 1.
Ejemplo resuelto: luminosidad frente a media simple
| Píxel | Media simple | Con pesos | Qué se ve |
|---|---|---|---|
| (255, 0, 0) | 85 | 76 | Un rojo algo oscuro |
| (0, 255, 0) | 85 | 149 | Un verde claro |
| (0, 0, 255) | 85 | 29 | Un azul casi negro |
| (255, 255, 255) | 255 | 255 | Blanco |
| (197, 157, 62) | 138 | 158 | El dorado de una moneda |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
La fórmula en Python
# Los pesos de la luminosidad, multiplicados por 1000 para no usar decimales.
pixel = [197, 157, 62]
red = pixel[0]
green = pixel[1]
blue = pixel[2]
grey = (299 * red + 587 * green + 114 * blue) // 1000
mean = (red + green + blue) // 3
print("gris con pesos:", grey)
print("media simple:", mean)
# Cambia el píxel a [0, 255, 0]. ¿Qué método lo ve más claro?
La cuenta del píxel dorado
docker exec jupyter python3 -c "print((299 * 197 + 587 * 157 + 114 * 62) // 1000)"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Rojo puro: media y pesos
docker exec jupyter python3 -c "print(255 // 3, (299 * 255) // 1000)"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Los números enteros evitan los decimales
Los pesos se multiplican por 1000 y el resultado se divide entre 1000 con //, que descarta los decimales. Así el gris sale siempre como un número entero, de 0 a 255.
El primer Ejecutar imprime 158: es el gris del píxel dorado. El segundo imprime 85 76, la media simple y el gris con pesos del rojo puro.
Un error muy común
Advertencia
Mucha gente cree que el gris es la media de los tres canales. Esa media trata igual al verde y al azul, y el ojo no lo hace. Con los pesos, un verde puro sale a 149 y un azul puro a 29. Usa la media solo si te piden una media.
Qué cuenta el script de gris del laboratorio
El script grey.py convierte coins.png con convert("L"). Imprime en inglés: colour mode y grey mode son los dos modos, y pixels from 0 to 63 es cuántos píxeles tienen un gris en esa banda.
El píxel dorado de 50, 50 pasa a 158. Hay 63.231 píxeles oscuros, ninguno entre 64 y 127, 13.566 entre 128 y 191 y solo 3 entre 192 y 255.
Convierte la imagen de monedas a gris
docker exec jupyter python3 steps/grey.pySe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejemplo resuelto: píxeles por banda de gris
| Banda de gris | Píxeles | Qué hay ahí |
|---|---|---|
| 0 a 63 | 63.231 | El fondo oscuro |
| 64 a 127 | 0 | Nada: hay un hueco |
| 128 a 191 | 13.566 | Las monedas |
| 192 a 255 | 3 | Unos pocos puntos de brillo |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Para ir más lejos: otros píxeles
En el código de arriba prueba el píxel [0, 0, 255] y compara los dos métodos. Después prueba [128, 128, 128].
Un píxel con los tres canales iguales no cambia de valor con ninguno de los dos métodos. ¿Por qué?