El emparejamiento de imágenes (Image Matching) es un pilar fundamental en la visión por computadora, permitiendo la localización de patrones o plantillas específicas dentro de una escena. Este artículo analiza tres metodologías técnicas: la correlación cruzada, la distancia de Hausdorff y su variante optimizada mediante la transformada de distancia, proporcionando implementaciones funcionales en MATLAB.
1. Correlación Cruzada Normalizada (NCC)
La técnica de correlación busca medir el grado de similitud lineal entre una plantilla (template) y diferentes regiones de una imagen de búsqueda. El uso de la Correlación Cruzada Normalizada (NCC) es preferible en entornos reales ya que compensa las variaciones globales de iluminación mediante la normalización de la intensidad.
function [score_map, best_coords] = ejecutar_ncc(imagen_base, plantilla)
% Preprocesamiento: Conversión a escala de grises y tipo double
if size(imagen_base, 3) == 3, imagen_base = rgb2gray(imagen_base); end
if size(plantilla, 3) == 3, plantilla = rgb2gray(plantilla); end
img = double(imagen_base);
temp = double(plantilla);
[h_i, w_i] = size(img);
[h_t, w_t] = size(temp);
% Dimensiones de la matriz de resultados
out_h = h_i - h_t + 1;
out_w = w_i - w_t + 1;
score_map = zeros(out_h, out_w);
% Parámetros de la plantilla
temp_avg = mean(temp(:));
temp_norm = norm(temp(:) - temp_avg);
% Ventana deslizante para cálculo de similitud
for r = 1:out_h
for c = 1:out_w
ventana = img(r:r+h_t-1, c:c+w_t-1);
v_avg = mean(ventana(:));
v_diff = ventana - v_avg;
v_norm = norm(v_diff(:));
if v_norm > 0
covar = sum(sum((temp - temp_avg) .* v_diff));
score_map(r, c) = covar / (temp_norm * v_norm);
end
end
end
% Localización del máximo valor de correlación
[~, max_idx] = max(score_map(:));
[y, x] = ind2sub(size(score_map), max_idx);
best_coords = [y, x];
end
2. Métrica de Distancia de Hausdorff
A diferencia de los métodos basados en intensidad, la distancia de Hausdorff opera sobre conjuntos de puntos (generalmente bordes). Es extremadamente útil cuando el objeto de interés presenta oclusiones parciales o cuando solo se dispone del contorno.
La distancia se define como el máximo de los mínimos: determina qué tan lejos está el punto más distante de un conjunto respecto al punto más cercano en el otro conjunto.
function [dist_map, min_loc] = calcular_hausdorff(src_img, templ_img)
% Extracción de bordes mediante Canny
if size(src_img, 3) == 3, src_img = rgb2gray(src_img); end
if size(templ_img, 3) == 3, templ_img = rgb2gray(templ_img); end
bordes_src = edge(src_img, 'canny');
bordes_tpl = edge(templ_img, 'canny');
[y_tpl, x_tpl] = find(bordes_tpl);
coords_tpl = [x_tpl, y_tpl];
[h_s, w_s] = size(src_img);
[h_t, w_t] = size(templ_img);
dist_map = inf(h_s - h_t + 1, w_s - w_t + 1);
for i = 1:(h_s - h_t + 1)
for j = 1:(w_s - w_t + 1)
% Segmento actual de la imagen
region_bordes = bordes_src(i:i+h_t-1, j:j+w_t-1);
[y_reg, x_reg] = find(region_bordes);
coords_reg = [x_reg, y_reg];
if ~isempty(coords_reg)
% Distancia dirigida h(T, R) y h(R, T)
d_tr = max(min(pdist2(coords_tpl, coords_reg), [], 2));
d_rt = max(min(pdist2(coords_reg, coords_tpl), [], 2));
dist_map(i, j) = max(d_tr, d_rt);
end
end
end
[~, idx] = min(dist_map(:));
[fy, fx] = ind2sub(size(dist_map), idx);
min_loc = [fy, fx];
end
3. Hausdorff optimizado con Transformada de Distancia (DT)
El cálculo tradicional de Hausdorff es computacionalmente costoso, escalando con el producto del número de puntos de ambos conjuntos. La Transformada de Distancia permite pre-calcular la proximidad de cada píxel al borde más cercano en la imagen original, reduciendo drásticamente la complejidad en la fase de búsqueda.
function [mapa_dt, pos_final] = fast_hausdorff_dt(img, tpl)
% Obtención de mapas binarios de bordes
bw_img = edge(rgb2gray(img), 'canny');
bw_tpl = edge(rgb2gray(tpl), 'canny');
% Cálculo de la transformada de distancia de la imagen completa
dt_transform = bwdist(bw_img, 'euclidean');
[y_t, x_t] = find(bw_tpl);
puntos_tpl = [x_t, y_t];
[h_i, w_i] = size(bw_img);
[h_t, w_t] = size(bw_tpl);
mapa_dt = inf(h_i - h_t + 1, w_i - w_t + 1);
for r = 1:(h_i - h_t + 1)
for c = 1:(w_i - w_t + 1)
% Proyección de los puntos de la plantilla sobre la DT de la imagen
px_global = puntos_tpl(:,1) + c - 1;
py_global = puntos_tpl(:,2) + r - 1;
% Verificación de límites
validos = (px_global >= 1 & px_global <= w_i & py_global >= 1 & py_global <= h_i);
if any(validos)
indices = sub2ind(size(dt_transform), py_global(validos), px_global(validos));
% La distancia dirigida se obtiene con el máximo de los valores en la DT
mapa_dt(r, c) = max(dt_transform(indices));
end
end
end
[~, m_idx] = min(mapa_dt(:));
[row, col] = ind2sub(size(mapa_dt), m_idx);
pos_final = [row, col];
end
Comparativa de Metodologías
| Criterio | Correlación (NCC) | Hausdorff Estándar | Hausdorff + DT |
|---|---|---|---|
| Sensibilidad Lumínica | Baja (Muy robusto) | Alta | Alta |
| Resistencia a Oclusiones | Baja | Alta | Moderada/Alta |
| Velocidad de ejecución | Media | Lenta | Rápida |
| Tipo de Dato | Intensidad de Píxel | Coordenadas de Contorno | Campos de Distancia |
Consideraciones para la Implementación
Para mejorar la precisión y el rendimiento en sistemas de producción, se sugieren las siguientes optimizaciones:
- Estrategia de Pirámide de Imágenes: Realizar el emparjeamiento en niveles de baja resolución para acotar el área de búsqueda en la resolución completa.
- Invarianza a Rotación: Aplicar descriptores de características (como SIFT o SURF) si se espera que el objeto rote, ya que estas técnicas son inherentemente sensibles a la orientación.
- Filtrado de Bordes: En el caso de Hausdorff, un filtrado de ruido previo (Gaussiano) antes de la detección de bordes mejora significativamente la estabilidad de la métrica.