septiembre 22, 2021 10:00 am

Jesús

La óptica es un campo increíblemente interesante. Su enfoque, evidentemente, se centra en el estudio de la luz, y cómo ella repercute, influencia y posibilita la visión. 

Gracias a los avances en esta área de estudio, hoy día contamos con cámaras fotográficas en prácticamente todos los smartphones, y son raros los momentos que escapan a nuestras lentes.

No obstante, la mayoría de las personas no están conscientes de que nuestros ojos y nuestras cámaras funcionan de formas diferentes, a pesar de que el efecto final sea el mismo: capturar imágenes.

Una de las principales distinciones reside en cómo percibimos los colores y la luminancia:

  • Una cámara percibe el doble de luz cuando el doble de fotones impactan contra una superficie; es una relación lineal.
  • Nuestros ojos perciben el doble de luz (es decir, el doble de fotones) como apenas un poco más de brillo; es una relación no lineal.
  • En el caso de los tonos oscuros, pasa lo mismo en nuestros ojos: son más sensibles a cambios en tonos oscuros que a tonos claros, por tanto, se trata de otra relación no lineal.

Afortunadamente, contamos con una herramienta matemática, conocida como ajuste o corrección Gamma, que se usa para traducir la sensibilidad de nuestros ojos a los de la cámara, y en este artículo aprenderemos a implementarla en OpenCV.

Al final de este post habrás aprendido:

  • Cómo funciona la corrección Gamma.
  • Cómo implementar la corrección Gamma en OpenCV.
  • Cómo ajustar la iluminación en tus propias imágenes mediante el ajuste Gamma en OpenCV.

¡Empecemos!

¿Cómo Funciona el Ajuste Gamma?

El ajuste Gamma, o tambén conocido como la Ley de Transformación de Poder (Power Law Transform), es un algoritmo muy sencillo que consta de los siguientes pasos:
  1. 1
    Los píxeles de la imagen deben ser escalados del rango [0, 255] al rango [0, 1].
  2. 2
    Aplicamos la siguiente fórmula a cada píxel: R = P ^ (1 / G), donde: R es el valor del píxel después de aplicar la fórmula; P es el valor del píxel antes de aplicar la fórmula; y G es el valor de Gamma.
  3. 3
    Convertimos nuevamente los píxeles al rango [0, 255].

¡ATENTO!

¿Qué valor de Gamma deberías escoger?

Por regla general, los valores < 1 tenderán a producir imágenes más oscuras, mientras que valores > 1 producirán imágenes más claras. Un valor igual a 1 no tendrá ningún efecto.

Creación del Entorno de Programación con Anaconda

Veamos rápidamente la estructura del proyecto:

Estructura del proyecto

Estructura del proyecto

  • La implementación del algoritmo de corrección Gamma vivirá en datasmarts/gamma_correct.py.
  • En resources tendremos varias imágenes de ejemplo que usaremos para probar el algoritmo.

Para crear el ambiente de Anaconda, corre este comando:

conda env create -f env.yml

Con esta instrucción habremos un ambiente llamado opencv-gamma-correction, configurado así: 

Finalmente, para activar el ambiente, ejecuta:

conda activate opencv-gamma-correction

¡Listo!

Corrección Gamma en OpenCV

Abre el archivo datasmarts/gamma_correct.py, e inserta estas líneas para importar las dependencias del proyecto:

Definimos la función auxiliar adjust_gamma(), la cual, como su nombre indica, aplica la fórmula de la corrección Gamma que aprendimos en secciones anteriores:

¿Cómo funciona exactamente la implementación de adjust_gamma()? Funciona en dos pasos:

  1. 1
    Construimos una tabla de referencia que aplica la fórmula del ajuste Gamma a cada posible valor entre 0 y 255.
  2. 2
    Usamos la tabla construida en el paso anterior para transformar cada píxel en la imagen de entrada, mediante la útil función de OpenCV cv2.LUT().

Ahora construimos el menú del programa, compuesto de un único parámetro, -i/--image, la ruta a la imagen de entrada:

Leemos la imagen de entrada y la redimensionamos para acelerar un poco el procesamiento de la misma (en caso de que sea muy grande):

Para propósitos ilustrativos, usamos diferentes valores de Gamma con el fin de ver cómo varía el resultado:

Como parte del ciclo anterior, etiquetamos cada transformación con el valor de Gamma utilizado, y creamos una imagen comparativa de la imagen original versus la ajustada.

Listo, con esto terminamos la implementación. Podemos correr el programa así:

python datasmarts/gamma_correct.py -i resources/truck.jpeg

En principio, veremos las siguientes imágenes, correspondientes a los valores de Gamma=0.1 y Gamma=0.5, respectivamente:

Lo primero que notamos es que, a medida que el valor de Gamma se aproxima a 0, el resultado es una imagen mucho más oscura, donde apenas se pueden discernir ciertos detalles.

Sucede algo análogo cuando los valores de Gamma son mayores a 1:

A medida que los valores de Gamma crecen, observamos que la imagen se va iluminando más y más. No obstante, cuando Gamma es mucho mayor a 1 (nótense los casos de Gamma=2.5 y Gamma=3.0), la iluminación excesiva empieza a borrar o difuminar los detalles en la fotografía, incluso haciéndola ver desgastada.

Resumen

En este artículo aprendimos sobre el papel que juega la luminancia en una fotografíía, así como la diferencia patente entre cómo las lentes de una cámara y nuestros ojos perciben la luz.

Afortunadamente, contamos con una herramienta conocida como la Ley de Transformación de Poder, o Corrección Gamma, que nos permite traducir la sensibilidad lumínica de las cámaras a la de nuestros globos oculares.

En este post, precisamente, nos dedicamos a implementar una versión muy sencilla del algoritmo de Ajuste Gamma valiéndonos únicamente de OpenCV.

Posteriormente, aplicamos nuestra implementación sobre una imagen de prueba para estudiar los efectos que diferentes valores de Gamma tienen sobre el resultado final.

Concretamente, descubrimos que para valores de Gamma < 1, la imagen resultante es más oscura, mientras que valores > 1 suelen revelar más y más elementos de la misma, ya que la imagen se ve más iluminada. No obstante, si nos excedemos en la magnitud de Gamma, puede suceder que la imagen final se vea, más bien, desgastada.

¿Qué te pareció el post de hoy? ¿Lo encontraste útil? Para consolidar lo aprendido, te recomiendo que descargues el código asociado a este artículo y que experimentes por tu cuenta:

¡Hasta pronto! ¡Un abrazo!

Sobre el Autor

Jesús Martínez es el creador de DataSmarts, un lugar para los apasionados por computer vision y machine learning. Cuando no se encuentra bloggeando, jugando con algún algoritmo o trabajando en un proyecto (muy) cool, disfruta escuchar a The Beatles, leer o viajar por carretera.