Ecualización de histogramas en Python

¿Recuerdas cuando viste esa imagen de baja calidad y te sentiste un poco decepcionado? No estaba lo suficientemente claro, y los detalles estaban un poco confusos. ¿Qué pasaría si pudieras mejorar esa imagen a una mejor versión? ¿No sería genial? Afortunadamente, hay una manera de hacerlo usando Python!

Uno de los métodos que puede utilizar para mejorar una imagen es ecualización de histograma, lo que en particular mejora la contraste de la imagen. Casi todos los sistemas de cámaras usan ecualización de histogramas para hacer que nuestras imágenes se vean mejor, y al final del tutorial descubrirás por qué esto es así..

En la siguiente sección, profundizaré en lo que se entiende por ecualización de histogramas y lo que sucede con la imagen al aplicar el método, y luego veremos cómo podemos implementar el método en Python. Listo?

Ecualización de histograma

Digamos que tienes la imagen pout.jpg (adelante y descárgala). Esta es una imagen de demostración utilizada en MATLAB, de donde la obtuve, pero la usaremos en nuestro tutorial aquí. La imagen se ve de la siguiente manera:

Echemos un vistazo a cómo podemos acceder a los valores de píxeles de la imagen, denominados intensidades. Escribí este pequeño script de Python que podemos usar para hacer eso (note que estoy usando la biblioteca OpenCV):

importar cv2 img = cv2.imread ('pout.jpg') img_shape = img.shape height = img_shape [0] width = img_shape [1] para fila en rango (ancho): para columna en rango (altura): imprimir (img [columna] [fila])

Lo que estoy haciendo aquí es leer nuestra imagen (pout.jpg), y luego investigar la forma (tamaño) de la imagen. img_shape volverá: (1031, 850, 3). Esto significa que nuestra imagen es de altura (número de columnas) 1031, y de ancho (numero de filas) 850, y tiene 3 Canales (RGB). Observe que el primer parámetro en el resultado es la altura, y el segundo parámetro es el ancho. Finalmente, recorramos las filas y columnas e imprimimos los diferentes valores de píxeles (intensidades) en cada par de filas / columnas.

Una muestra de la salida es: [137 137 137]. Sí, lo sé, esperabas un valor como resultado de la intensidad de píxel. Aquí tenemos el valor de la intensidad de píxeles, pero lo que nos muestra la salida son los resultados del rojo, el verde y el azul (RGB) canales. Tenga en cuenta, sin embargo, que en OpenCV el pedido es BGR, ya que así es como OpenCV carga la imagen. Por lo tanto, el resultado de la muestra anterior contiene el valor 137 para cada canal, en el orden de segundo, sol, y R, respectivamente.

El motivo de la introducción es que la ecualización del histograma se trata en realidad de la Modificación de las intensidades de pixel. Por el bien de mejorar el contraste de la imagen. Por lo tanto, nuestro trabajo principal aquí será en el nivel de intensidad de píxeles..

En este punto, quizás se esté preguntando qué histograma es. Aunque a veces el término puede ser un poco confuso, en realidad es un concepto muy simple. El histograma es simplemente un diagrama que representa el número de píxeles en una imagen en cada valor de intensidad encontrado en esa imagen.

Dado que nuestros píxeles tienen tres valores, uno para cada uno de los canales BGR, una forma de dibujar el histograma es tener tres histogramas, uno para cada canal, donde el eje x tendrá los diferentes valores de píxeles (intensidades), y la y El eje mostrará cuántas veces (frecuencia) apareció ese valor de píxel en particular entre los diferentes valores de píxel..

Por ejemplo, el histograma de canal rojo puede tener un valor de píxel de 137 en el eje x, y el eje y puede mostrar cuántos píxeles tenían este valor para el canal rojo, por ejemplo, 86. Así que la forma en que leemos es diciendo que el valor de píxel para el canal rojo de 137 apareció en 86 píxeles, o ha repetido 86 veces en nuestra imagen.

Al usar el código de este artículo del histograma de imágenes para dibujar el histograma de nuestra imagen, obtenemos lo siguiente:

El histograma es en realidad para los canales rojo, verde y azul. Tomemos una pequeña muestra de la salida que obtendría del código anterior, como se muestra a continuación. Esto muestra que los valores de los canales parecen ser siempre los mismos, y las tres líneas diferentes dibujadas tendrán los mismos valores y se dibujarán una encima de la otra, apareciendo como una sola línea.

[94 94 94] [95 95 95] [97 97 97] [99 99 99] [100 100 100] [101 101 101] [101 101 101] [101 101 101] [100 100 100] [98 98 98] [95 95 95] [93 93 93]

Lo que hará el método de ecualización del histograma para el histograma anterior es que transformará los valores de intensidad de manera que el histograma se vea adular En la imagen resultante. En otras palabras, la ecualización del histograma es un método que ajusta las intensidades de la imagen para mejorar el contraste de la imagen..

El histograma anterior se ve un poco concentrado hacia la mitad de la figura, y lo que hará la ecualización del histograma es distribuir los valores de intensidad de píxel aún más para obtener un histograma más plano..

Creo que eso es suficiente sobre la ecualización de histogramas para discutir aquí, ya que no queremos obtener más información matemática en este tutorial, especialmente porque se trata más de la implementación del método en Python. Sin embargo, puede consultar estas notas que muestran las diferentes fórmulas involucradas en el método: ecualización de ecogramas. Así que ahora vamos a sumergirnos en la implementación!

Ecualización de histogramas en Python

En esta sección, le mostraré cómo implementar el método de ecualización de histogramas en Python. Usaremos la imagen anterior (pout.jpg) en nuestros experimentos. Vayamos por el proceso paso a paso. Lo primero que debemos hacer es importar las bibliotecas OpenCV y NumPy, de la siguiente manera:

import cv2 import numpy

Después de eso, simplemente necesitamos leer nuestra imagen, pout.jpg:

img = cv2.imread ('pout.jpg')

La buena noticia es que OpenCV nos proporciona una función a través de la cual podemos aplicar la ecualización de histogramas en una imagen, a saber, equalizeHist (). Es sencillo aplicar esta función en una imagen en escala de grises, ya que el método en realidad iguala el histograma de una escala de grises imagen, pero en nuestro caso tenemos tres canales (RGB) para cada píxel y no podemos aplicar la ecualización de histogramas en los tres canales de forma separada.

Una buena solución que encontré en el libro Python: Real World Machine Learning es convertir nuestra imagen al espacio de color YUV, igualar el Y Canal, y finalmente convertir el resultado a RGB. Así que lo primero que hacemos es convertir nuestra imagen a YUV. Esto se puede hacer usando el método cvtColor (), que convierte la imagen de un color de espacio a otro, de la siguiente manera:

img_to_yuv = cv2.cvtColor (img, cv2.COLOR_BGR2YUV)

Note que usamos BGR en lugar de RGB Aquí, ya que OpenCV (como se mencionó anteriormente) carga las imágenes en BGR formato.

Ahora aplicamos el método de ecualización de histograma en el Y canal utilizando el método equalizeHist ():

img_to_yuv [:,:, 0] = cv2.equalizeHist (img_to_yuv [:,:, 0])

Finalmente, convertimos el Y canal a RGB (BGR en OpenCV), como sigue:

hist_equalization_result = cv2.cvtColor (img_to_yuv, cv2.COLOR_YUV2BGR)

¡Felicidades! Ahora ha aplicado ecualización de histograma a la imagen. En la siguiente subsección, pondré todo el código y le mostraré cómo se verá nuestra imagen después de aplicar la ecualización de histogramas.

Poniendolo todo junto

Pongamos todo lo que hemos aprendido juntos. El script de Python para aplicar ecualización de histograma en pout.jpg se ve de la siguiente manera:

import cv2 import numpy img = cv2.imread ('pout.jpg') img_to_yuv = cv2.cvtColor (img, cv2.COLOR_BGR2YUV) img_to_yuv [:,) y cp2. hist_equalization_result = cv2.cvtColor (img_to_yuv, cv2.COLOR_YUV2BGR) cv2.imwrite ('result.jpg', hist_equalization_result)

La salida del script anterior es la siguiente imagen:

Para notar mejor la diferencia, pondré las dos imágenes una al lado de la otra (izquierda: imagen original; derecha: resultado de la ecualización del histograma):

¿Notaste la diferencia? La imagen correcta se ve mucho más clara que la imagen original. No es de extrañar por qué casi todos los sistemas de imágenes realizan ecualización de ecogramas!

Antes de terminar, veamos cómo se ve el histograma de nuestro resultado:

Si compara el histograma de la imagen resultante con el histograma de la imagen original, notará que el histograma de la imagen resultante es más plano que el histograma de la imagen original, y esto es exactamente lo que hace el método de ecualización del histograma..

Conclusión

En este tutorial, vimos cómo podemos mejorar el contraste de una imagen usando un método llamado ecualización de histograma, y cómo es fácil de implementar utilizando Python y OpenCV.

El resultado fue muy interesante, ya que era mucho más claro que la imagen original, y el histograma del resultado era más plano que el histograma de la imagen original, mostrando una mejor distribución de los valores de intensidad de píxeles en toda la imagen.

Por último, no dude en ver lo que tenemos disponible para la venta y para el estudio en el mercado de Envato, y haga cualquier pregunta y proporcione sus valiosos comentarios utilizando la siguiente información..