Corrección de imágenes en MATLAB: lineal, gamma y sigmoidal

Las transformaciones de intensidad son la primera herramienta que se aprende en procesamiento digital de imágenes: permiten aclarar una imagen oscura, aumentar el contraste o resaltar detalles en ciertas zonas de gris. En este post, basado en una clase que preparé, te explico tres correcciones clásicas en MATLAB, la lineal, la gamma y la sigmoidal, con su fórmula, un ejemplo numérico y el código corregido para que funcione en versiones actuales.

La idea: cada píxel pasa por una función

Una imagen en escala de grises es una matriz de números. Si la normalizamos entre 0 (negro) y 1 (blanco), una transformación de intensidad es una función g = T(x) que se aplica a cada píxel por separado. No importa dónde esté el píxel, solo su valor. Por eso estas operaciones son muy rápidas y fáciles de programar.

1. Corrección lineal: g = m·x + b

  • m (pendiente) controla el contraste: si m > 1 lo aumenta, si m < 1 lo reduce.
  • b (desplazamiento) controla el brillo: si b > 0 aclara, si b < 0 oscurece.

Ejemplo: con m = 1,5 y b = −0,2, un píxel de valor 0,4 pasa a 1,5 · 0,4 − 0,2 = 0,4 (se queda igual), uno de 0,8 pasa a 1,0 y uno de 0,1 pasa a −0,05. Los valores fuera del rango 0–1 se recortan: quedan en negro o blanco puro. Por eso conviene usar min(max(g,0),1) después de la transformación.

2. Corrección gamma: g = xγ

  • Si γ < 1, la imagen se aclara: los tonos oscuros se expanden.
  • Si γ > 1, la imagen se oscurece: se expanden los tonos claros.
  • Con γ = 1 la imagen no cambia.

Ejemplo: un píxel de 0,25 con γ = 0,5 pasa a 0,250,5 = 0,5, el doble de brillante. Con γ = 2 pasa a 0,252 = 0,0625, mucho más oscuro. Los valores 0 y 1 nunca cambian, así que la gamma ajusta los tonos medios sin perder el negro ni el blanco. Es la misma corrección que usan las pantallas y las cámaras.

3. Corrección sigmoidal: g = 1 / (1 + e−γx + β)

La función sigmoide tiene forma de "S": comprime los tonos muy oscuros y muy claros y expande los tonos intermedios. Así aumenta el contraste justo en la zona que nos interesa.

  • γ controla la inclinación de la S: cuanto mayor, más contraste.
  • β desplaza la S. El centro de la curva (donde g = 0,5) está en x = β/γ.

Ejemplo: con γ = 10 y β = 5, el centro está en x = 0,5. Un píxel de 0,5 da g = 1/(1 + e0) = 0,5; uno de 0,7 da 1/(1 + e−2) ≈ 0,88; uno de 0,3 da 1/(1 + e2) ≈ 0,12. Una diferencia de 0,4 en la entrada se convierte en 0,76 en la salida: el contraste en los grises medios casi se duplica.

El código en MATLAB (corregido)

Este es el programa original de la clase, con dos correcciones: imshow va en minúscula (MATLAB distingue mayúsculas y la versión con "I" mayúscula falla en versiones actuales) y se recorta el resultado al rango 0–1.

%% Corrección de imágenes: lineal, gamma y sigmoidal - by Luis Carlos
clc; clear; close all;
load mri;                          % imagen de ejemplo de MATLAB: D (128x128x1x27) y map
x = ind2gray(D(:,:,:,1), map);     % primer corte de la resonancia, en grises
x = mat2gray(x);                   % normalizar entre 0 y 1

correccion = input('1 lineal; 2 gamma; 3 sigmoidal: ');

switch correccion
    case 1   % ecuación lineal
        m  = input('Ingrese el valor de m: ');
        b  = input('Ingrese el valor de b: ');
        gx = m*x + b;
    case 2   % corrección gamma
        gamma = input('Ingrese el valor de gamma: ');
        gx = x.^gamma;
    case 3   % sigmoidal
        gamma = input('Ingrese el valor de gamma: ');
        beta  = input('Ingrese el valor de beta: ');
        gx = 1 ./ (1 + exp(-gamma*x + beta));
    otherwise
        error('Opción no válida');
end

gx = min(max(gx,0),1);             % recortar al rango 0..1

subplot(1,2,1), imshow(x),  title('Original');
subplot(1,2,2), imshow(gx), title('Corregida');

Qué hace cada parte

  1. load mri carga un conjunto de imágenes de resonancia magnética que trae MATLAB; tomamos el primer corte.
  2. ind2gray convierte la imagen indexada (índices + mapa de colores) a escala de grises.
  3. mat2gray normaliza los valores entre 0 y 1, necesario para que las fórmulas funcionen como esperamos.
  4. switch reemplaza los tres if del código original y añade un mensaje si el usuario escribe otra opción.
  5. Usamos .^ y ./ (con punto) porque la operación se hace elemento por elemento.

Ver las curvas de transformación

Para entender lo que hace cada corrección, grafica la función T(x):

x = linspace(0,1,256);
plot(x, x, 'k--', x, min(max(1.5*x-0.2,0),1), x, x.^0.5, x, x.^2, ...
     x, 1./(1+exp(-10*x+5)), 'LineWidth', 1.5);
legend('identidad','lineal m=1.5 b=-0.2','gamma 0.5','gamma 2','sigmoide 10/5');
xlabel('Entrada x'); ylabel('Salida g'); grid on;

Si la curva está por encima de la diagonal, la imagen se aclara; si está por debajo, se oscurece; y donde la curva es más empinada, aumenta el contraste.

Errores comunes

  • "Undefined function 'Imshow'": escribe imshow en minúsculas.
  • La imagen sale completamente blanca: estás aplicando las fórmulas a una imagen uint8 (0–255) sin normalizar. Usa mat2gray o im2double.
  • Error de dimensiones: usaste ^ en lugar de .^.
  • La sigmoide deja la imagen casi negra o casi blanca: el centro β/γ está lejos del rango de grises de tu imagen. Ajusta β.

Preguntas frecuentes

¿Necesito la Image Processing Toolbox?

Funciones como ind2gray, mat2gray e imshow pertenecen a esa toolbox. Las fórmulas en sí son operaciones básicas de MATLAB.

¿Qué corrección es mejor para una imagen oscura?

Normalmente la gamma con γ entre 0,4 y 0,7, porque aclara los tonos oscuros sin saturar los blancos.

¿Puedo aplicarlas a imágenes a color?

Sí, aplicando la función a cada canal o, mejor, solo al canal de luminancia (por ejemplo, convirtiendo a HSV y modificando V).

Para guardar el resultado, mira cómo guardar una imagen en JPG con MATLAB. Y para practicar más con vectores, onda senoidal en MATLAB.

Conclusión

La corrección lineal ajusta brillo y contraste de forma uniforme, la gamma mejora los tonos medios sin perder negros ni blancos, y la sigmoidal concentra el contraste en una zona de grises elegida. Con el código de este post puedes probarlas en segundos y ver el efecto de cada parámetro.

1 comentario