Conversión de imágenes Bayer a RGB mediante interpolación con gradientes
Implementación del algoritmo GBTF (Gradient-Based Threshold-Free) en MATLAB para transformar imágenes monocromáticas en formato Bayer a RGB completo. Esta técnica utiliza ponderación por gradientes para minimizar artefactos de color en regiones de alto contraste.
function imagenRGB = demosaico_gbtf(imagenBayer, patron)
[alt, anc] = size(imagenBayer);
imagenRGB = zeros(alt, anc, 3, 'like', imagenBayer);
switch lower(patron)
case 'rggb'
R = imagenBayer(1:2:end, 1:2:end);
VerR = imagenBayer(1:2:end, 2:2:end);
VerB = imagenBayer(2:2:end, 1:2:end);
Az = imagenBayer(2:2:end, 2:2:end);
case 'bggr'
Az = imagenBayer(1:2:end, 1:2:end);
VerR = imagenBayer(1:2:end, 2:2:end);
VerB = imagenBayer(2:2:end, 1:2:end);
R = imagenBayer(2:2:end, 2:2:end);
otherwise
error('Patrón Bayer no soportado');
end
Verde = interpolar_verde(R, VerR, VerB, Az);
R_VerB = interpolar_R_VerB(VerR, VerB, Verde);
Az_VerR = interpolar_Az_VerR(VerR, VerB, Verde);
R = interpolar_R(R, R_VerB, Verde);
Az = interpolar_Az(Az, Az_VerR, Verde);
imagenRGB(:,:,1) = R;
imagenRGB(:,:,2) = Verde;
imagenRGB(:,:,3) = Az;
end
function Verde = interpolar_verde(R, VerR, VerB, Az)
[h, w] = size(R);
Verde = zeros(h, w);
margen = 2;
R_pad = padarray(R, [margen margen], 'symmetric');
VerR_pad = padarray(VerR, [margen margen], 'symmetric');
VerB_pad = padarray(VerB, [margen margen], 'symmetric');
Az_pad = padarray(Az, [margen margen], 'symmetric');
for fila = 3:h+2
for col = 3:w+2
if mod(fila-2,2)==1 && mod(col-2,2)==0
valor_centro = R_pad(fila, col);
vecinos = [VerR_pad(fila, col+1), VerR_pad(fila, col-1);
VerB_pad(fila, col+1), VerB_pad(fila, col-1)];
elseif mod(fila-2,2)==0 && mod(col-2,2)==1
valor_centro = Az_pad(fila, col);
vecinos = [VerR_pad(fila, col+1), VerR_pad(fila, col-1);
VerB_pad(fila, col+1), VerB_pad(fila, col-1)];
else
continue
end
dif_h = diff(vecinos, 1, 2);
dif_v = diff(vecinos, 1, 1);
magnitud_grad = hypot(dif_h, dif_v);
pesos = 1./(magnitud_grad + eps);
pesos = pesos / sum(pesos(:));
ajuste = sum(pesos(:) .* (vecinos(:) - valor_centro));
Verde(fila-2, col-2) = valor_centro + ajuste;
end
end
Verde(1:2:end, 2:2:end) = VerR;
Verde(2:2:end, 1:2:end) = VerB;
end
function R = interpolar_R(R, R_VerB, Verde)
[h, w] = size(R);
R_completo = R;
margen = 1;
R_pad = padarray(R, [margen margen], 'replicate');
R_VerB_pad = padarray(R_VerB, [margen margen], 'replicate');
Verde_pad = padarray(Verde, [margen margen], 'replicate');
for fila = 2:h+1
for col = 2:w+1
if mod(fila,2)==1 && mod(col,2)==0
deriv_h = (R_VerB_pad(fila, col+1) - R_VerB_pad(fila, col-1))/2;
deriv_v = (R_VerB_pad(fila+1, col) - R_VerB_pad(fila-1, col))/2;
R_completo(fila-1, col-1) = Verde_pad(fila, col) + deriv_h + deriv_v;
end
end
end
R = R_completo;
end
Mecanismo del algoritmo
- Interpolación del canal verde: Calcula gradientes en ventanas 5×5 para ajustar pesos de interpolación, priorizando píxeles en regiones homogéneas
- Recuperación de canales rojo/azul: Emplea diferencias cromáticas en ventanas 3×3 usando valores verdes interpolados como referencia
- Manejo de bordes: Aplica relleno simétrico para evitar discontinuidades en los límites de la imagen
Ejemplo de uso
% Cargar datos RAW en formato Bayer
datosBayer = imread('imagen_raw.tiff');
rgb = demosaico_gbtf(datosBayer, 'RGGB');
% Visualizar resultados
imshow(rgb);
imwrite(rgb, 'resultado_rgb.jpg');
Mejoras sugeridas
- Conversión a C/MEX para optimización de rendimiento en procesamiento de video
- Incorpoar corrección de balance de blancos antes de la interpolación
- Aplicar matriz de corrección cromática post-demosaico