paint-brush
Algoritmos de procesamiento de imágenes: ajuste del contraste y el brillo de la imagenpor@aryamansharda
20,013 lecturas
20,013 lecturas

Algoritmos de procesamiento de imágenes: ajuste del contraste y el brillo de la imagen

por Aryaman Sharda5m2021/01/24
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

Echemos un vistazo a los enfoques comunes para implementar ajustes de contraste de imagen. Repasaremos la extensión y la ecualización de histogramas.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail

Coin Mentioned

Mention Thumbnail
featured image - Algoritmos de procesamiento de imágenes: ajuste del contraste y el brillo de la imagen
Aryaman Sharda HackerNoon profile picture

Como fotógrafo aficionado, siempre me he preguntado cómo Apple Photos, Lightroom y Photoshop implementan los ajustes de contraste de la imagen. Después de pasar un tiempo leyéndolo, vale la pena compartir el enfoque.

Empecemos con lo básico.

Un histograma es simplemente un gráfico de barras que representa [en este caso] diferentes frecuencias de colores en una imagen.

Aquí hay un histograma típico que puede ver:

Fuente: Histogramas para principiantes

Brillo

Como paso preliminar, intentemos manipular el brillo de una imagen. Se prestará para hacer ajustes de contraste más adelante.

Dado un histograma, si desplazamos su contenido hacia la izquierda o hacia la derecha, podemos hacer que la imagen sea más oscura o más clara, respectivamente.

Supongamos que estamos tratando con un espacio de color RGB de 8 bits. Un lado del histograma sería (0, 0, 0) [negro] y el otro lado sería (255, 255, 255) [blanco].

A medida que movemos el histograma hacia la derecha, aumentamos la frecuencia de los valores más cercanos al blanco en la imagen, lo que ilumina la imagen. Por el contrario, desplazar el histograma hacia la izquierda mueve más valores hacia el negro, oscureciendo así la imagen.

Aquí hay un ejemplo de una función que puede cambiar el brillo de una imagen.

Imagen original

Brillo + 40%

Brillo - 40 %

El código anterior es demasiado simplista. Una implementación adecuada asignaría el espacio de color RGB a HSL. Luego, modificaría los valores de luminancia y luego convertiría la imagen nuevamente al espacio de color RGB. Sin embargo, modificar los valores RGB de esta manera aún ilustra el punto sin aumentar el alcance del artículo.

Contraste

El contraste es realmente solo una medida de la diferencia entre las intensidades de píxeles máxima y mínima en una imagen. Entonces, para aumentar el contraste en una imagen, necesitamos aumentar la distancia entre las intensidades de píxeles máxima y mínima.

Echaremos un vistazo a algunos algoritmos de ajuste de contraste diferentes, comenzando con el estiramiento de contraste/histograma.

Estiramiento de contraste / Estiramiento de histograma

Como su nombre lo indica, esto es realmente solo el proceso de tomar los valores de intensidad existentes en la imagen y "estirarlos" para que se ajusten a todo el rango de valores potenciales: [0, 255].

Foto de Giancarlo Corti en Unsplash

Si observamos el histograma de la imagen, veremos que la mayoría de los valores de intensidad están sesgados hacia el lado izquierdo del gráfico y existen muy pocos valores en el rango de intensidad más alto.

Después de aplicar la ampliación del contraste a esta foto, los valores de intensidad del histograma deben distribuirse en todo este rango.

Como hemos aumentado la diferencia entre los valores de intensidad máxima y mínima, puede ver que hemos aumentado el contraste en la imagen.

También es importante tener en cuenta que la forma general del histograma se conserva con este enfoque. Este no será el caso con los futuros algoritmos que veremos.

Para implementar el estiramiento de contraste, primero debemos encontrar las intensidades de píxeles mínima y máxima. Luego, simplemente podemos aplicar la siguiente transformación en cada píxel para obtener el nuevo valor de intensidad para ese píxel en la imagen de salida.

Si quisiéramos aplicar este mismo enfoque a una imagen RGB, necesitaríamos convertir la imagen a un espacio de color de Tono, Saturación e Intensidad (HSI). Luego, realizaríamos el mismo cálculo anterior solo en el valor de Intensidad y luego asignaríamos el resultado al espacio de color RGB.

El resultado de este paso de normalización sería un valor entre 0 y 1,0 que luego multiplicaríamos por 255 para obtener el valor correcto del píxel.

Código

Sin embargo, hay una trampa con este enfoque.

Teniendo en cuenta la fórmula anterior, podemos ver que si los valores mínimo y máximo son 0 y 255, la imagen no se ve afectada. Por lo tanto, la mayoría de las implementaciones de este algoritmo seleccionan valores del 5% de los bordes en lugar de estrictamente los valores de intensidad mínimos/máximos.

Siempre puede jugar con qué tan lejos se mueve desde los bordes para controlar cuánto contraste adicional se aplica a la imagen.

Antes

Después

Ecualización de histograma

Mientras que la ampliación del histograma modifica el rango de valores de intensidad para extenderse por todo el rango posible, la ecualización del histograma crea una distribución uniforme de los valores del histograma.

Crédito: Wikipedia

La ecualización del histograma de ninguna manera garantiza mejores resultados. Convertir los valores de intensidad en una distribución uniforme puede muy bien disminuir el contraste o introducir ruido adicional en la imagen.

pseudocódigo

  1. Iterar a través de todos los píxeles de la imagen.
  2. Cuente la frecuencia de cada valor de intensidad en un diccionario.
  3. Cree una matriz vacía de longitud 256.
  4. Usando nuestro diccionario, completaremos esta matriz de modo que cada índice almacene la probabilidad de que ese valor de intensidad ocurra en la imagen de origen. Por ejemplo, el índice 5 en la matriz representará la probabilidad con la que aparece una intensidad de 5 en la imagen de entrada.
  5. Cree una función de distribución acumulativa (repasaremos esto en un momento).
  6. Utilice la función de distribución acumulativa para transformar el valor del píxel original y calcular el nuevo valor del píxel en la imagen de salida.

El primer paso es contar las diversas frecuencias de intensidad en nuestra imagen de origen:

El código completo está disponible a continuación, pero aquí hay un extracto de la salida:

 0, 3028
1, 1216
2, 1188
3, 1262
4, 1242
...

No debería sorprender que los valores del histograma estén muy sesgados hacia la izquierda, lo que indica que la imagen está en el lado oscuro.

Ahora que tenemos nuestra distribución de probabilidad, generemos nuestra función de distribución acumulativa [CDF]. Un CDF es una representación de cuántos valores menores que un cierto valor existen en nuestra imagen de entrada.

Por ejemplo, en el gráfico a continuación podemos ver que hay aprox. 150.000 píxeles que son menores o iguales a un nivel de intensidad de 65 (de 255).

Calcular todas estas frecuencias y probabilidades nos ayuda en la transformación del histograma en una distribución uniforme.

¡Excelente! Todo lo que necesitamos hacer es usar la información en el CDF para transformar los valores de intensidad en la imagen original.

Para realizar esta traducción, tomaremos un píxel de la imagen original, por ejemplo, el píxel en (10, 10), y encontraremos su valor de intensidad. Luego, usaremos ese valor de intensidad para indexar en nuestra matriz que almacena los resultados de la CDF para encontrar la nueva intensidad para el píxel de salida.

Si esto todavía es un poco confuso, el código debería aclarar las cosas.

Ahora, tenemos nuestra nueva imagen de salida:

Verifiquemos nuestro trabajo y observemos el histograma de esta nueva imagen:

me parece bastante uniforme :)

Código

Alternativas

Veamos rápidamente algunos otros enfoques.

Estiramiento no lineal

Cuando discutíamos el estiramiento del contraste, estábamos estirando todas las partes del histograma por igual. El estiramiento no lineal es esencialmente el mismo enfoque, pero usará alguna otra función para estirar selectivamente diferentes partes del histograma de manera diferente. Por ejemplo, una implementación podría usar una función logarítmica para estirar el histograma.

Especificación de histograma

Este enfoque está estrechamente relacionado con la ecualización de histogramas. En lugar de crear una distribución uniforme, la especificación de histogramas le permite transformar el histograma de una imagen para que coincida con algún otro histograma que especifique. Por lo tanto, la ecualización del histograma es solo una variante de este enfoque en el que el histograma proporcionado se distribuye uniformemente. En cambio, este enfoque le permite pasar cualquier histograma para que coincida.

Modificación adaptativa del histograma

Este enfoque implica la creación de varios histogramas, cada uno de los cuales corresponde a diferentes partes de la imagen de origen. Esto le permite tener ajustes de contraste mucho más granulares. Este enfoque se usa a menudo cuando desea proporcionar ajustes de contraste locales o, de manera más general, refinar los bordes de su imagen.

Si te gusta esta inmersión técnica en los algoritmos modernos, no dudes en seguirme en Twitter , o echa un vistazo a mi sitio personal para ver más publicaciones.

Fuentes

Publicado anteriormente en https://digitalbunker.dev/2021/01/09/understanding-contrast-algorithms/