jueves, 17 de abril de 2025

Curvas de contraste con R

Una curva de contraste es una función de entrada/salida de tipo sigmoide (forma de 'S'), utilizada intensivamente en programas de procesado de imagen para aumentar (o disminuir) el contraste aparente de una imagen. En general se prefiere una curva con sus extremos en (0,0) y (1,1), y que sea estrictamente monótona creciente para que nunca pueda provocar una pérdida o cruce de niveles tonales. De esta forma además será una biyección y por tanto reversible lo que, errores de redondeo al margen, supone un procesado no destructivo.

Vamos a proponer la formulación de una curva de contraste con las anteriores características rescatando la siguiente fórmula parametrizable de curva de contraste que construí hace unos años:



La curva se define para x en el dominio normalizado [0,1] proporcionando valores de salida para y en el mismo rango. El significado de cada parámetro es el siguiente:
  • a,b: punto de inflexión de la curva (0<a<1, 0<b<1).
  • E: define la pendiente en el punto de inflexión (coincide con su valor exacto si a=b y m=0). Modula si la curva es de contraste (E>1) o de reducción de contraste (0<E<1), permitiendo controlar la intensidad del contraste/descontraste aplicado.
  • m: define la pendiente en los extremos x=0 y x=1 (coincide con su valor exacto si a=b). También permite definir si la curva será de contraste (0≤m<1) o de reducción de contraste (1<m≤2), aunque encuentro preferible usar E para ese fin dejando m para refinar los extremos de la curva.

La ecuación es formalmente una spline: curva polinómica definida a tramos, continua y con la derivada primera también continua, de ahí su forma suave. La derivada segunda en cambio ya presenta discontinuidades como intuiremos por los quiebros de la primera derivada.

En su forma más estándar vemos como m define la pendiente en los extremos y E en el punto de inflexión:




Observando la derivada primera vemos que en los extremos es menor de 1, y solo en la parte central coloreada es mayor de 1. Esto significa que la curva comprime los niveles de las luces y las sombras sobre un rango de salida menor al de entrada (reduce el contraste), y sin embargo expande los niveles de entrada de los tonos medios (aumenta el contraste).

A efectos prácticos las imágenes de bajo contraste concentran sus niveles en la parte central de la curva, haciendo que el efecto de ésta se perciba mayoritariamente como un aumento de contraste. En definitiva una curva de contraste busca oscurecer más las partes oscuras y aclarar más las claras.

Es deseable que la curva se personalice en función de la distribución de niveles (histograma) de la imagen a tratar como veremos en un ejemplo práctico. Ajustes de contraste genéricos como el de Photoshop o ACR son precisamente poco recomendables por aplicar la misma curva estándar a todas las imágenes.

~~~

A continuación se muestra cómo varía la curva para diferentes valores de los parámetros m y E:




Y aquí desplazando el punto de inflexión fuera de la diagonal, facilidad que vamos a explotar en un ejercicio posterior de mapeo de tonos. Al no cumplirse ya que a=b, E sigue determinando la pendiente en el punto de inflexión pero no coincide con su valor exacto:



~~~

Vamos a probar nuestra curva de contraste con una imagen resultante de revelar linealmente con DCRAW un archivo DNG de la Leica Q3. Estos revelados son muy planos así que se pueden beneficiar mucho de un contrastado.

Construimos una curva adaptada a la imagen en cuestión situando el punto de inflexión a en la mediana del histograma de valores RGB, dando ese mismo valor de salida b para así oscurecer exactamente el 50% de niveles y aclarar el otro 50%. Esto contrastará la imagen pero preservando su luminosidad media (en realidad mediana):



El histograma tras aplicar la curva se expande hacia los extremos. Al compartir mediana ambas imágenes, sus histogramas tienen los mismos niveles a cada lado de dicha mediana representando además el 50% del total de valores:



A continuación comparamos la imagen original con su versión contrastada. Aplicar una curva de contraste básica directamente sobre los niveles RGB de una fotografía produce no solo un aumento del contraste sino cierto incremento de saturación de color (hacer clic para ver a mayor resolución):


Repositorio con el código R y simulador de curvas en Excel: GitHub.

No hay comentarios:

Publicar un comentario

Por claridad del blog, por favor trata de utilizar una sintaxis lo más correcta posible y no abusar del uso de emoticonos, mayúsculas y similares.