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
- load mri carga un conjunto de imágenes de resonancia magnética que trae MATLAB; tomamos el primer corte.
- ind2gray convierte la imagen indexada (índices + mapa de colores) a escala de grises.
- mat2gray normaliza los valores entre 0 y 1, necesario para que las fórmulas funcionen como esperamos.
- switch reemplaza los tres
ifdel código original y añade un mensaje si el usuario escribe otra opción. - 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
imshowen minúsculas. - La imagen sale completamente blanca: estás aplicando las fórmulas a una imagen
uint8(0–255) sin normalizar. Usamat2grayoim2double. - 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.
funciona a la perfeccion
ResponderEliminar