4.9.3 EP04_03 🌱 Dilatación Binaria Plana (mm.dil0)
En microscopía de partículas y en OCR de placas de automóvil desgastadas, los trazos finos o discontinuos deben “engrosarse” para que el reconocimiento funcione. La dilatación morfológica hace exactamente eso: expande regiones claras usando un elemento estructurante \(B\) — la misma operación implementada en morph.py como mm::dil0(f, B), usada cuando \(B\) es plano (sin pesos, solo \(0\)/\(1\)). Ver en Figura 4.32 una simulación de este EP.
4.9.3.1 📋 Directrices de Implementación
Dimensiones de la imagen: Leer los enteros \(L\) (filas) y \(C\) (columnas) de \(f\).
Dimensiones de \(B\): Leer los enteros \(L_B\) (filas) y \(C_B\) (columnas) del elemento estructurante.
Elemento estructurante: Leer la matriz \(B\) con valores \(0\) o \(1\), fila a fila.
Datos: Leer la matriz \(f\) (la imagen original), fila a fila.
Reflexión: Construir \(B_{ref}\), la versión de \(B\) reflejada en \(180°\) (filas y columnas invertidas) — exactamente como hace mm::dil0 internamente.
Vecindad sin padding: Para cada píxel \((y,x)\), recorrer las posiciones \((by,bx)\) de \(B_{ref}\) centradas en \((y,x)\), usando el desplazamiento \[
v_y = y + by + o_y,\quad v_x = x + bx + o_x,\quad o_y=-\tfrac{L_B}{2}+0{,}5,\quad o_x=-\tfrac{C_B}{2}+0{,}5
\]Descartar todo \((v_y,v_x)\) fuera de \([0,L)\times[0,C)\) — no rellenar con ceros.
Mapeo: Calcular cada píxel de salida como el máximo entre \(f(y,x)\) y todos los \(f(v_y,v_x)\) válidos cuya posición correspondiente en \(B_{ref}\) vale \(1\): \[
g(y,x) = \max\Big(f(y,x),\ \max_{\substack{(v_y,v_x)\ \text{válido}\\ B_{ref}(by,bx)=1}} f(v_y,v_x)\Big)
\]
Salida: Mostrar la matriz \(g\) con dimensiones \(L \times C\).
4.9.3.2 📌 Restricciones Computacionales
Sin padding: Nunca inventar vecinos fuera de la imagen; usar solo los que existen realmente.
Reflexión obligatoria:\(B\) debe reflejarse antes de aplicarse (es lo que diferencia mm::dil0 de una simple búsqueda de máximo).
Robustez de borde: Si ninguna posición válida de \(B_{ref}=1\) cae dentro del dominio para un píxel dado, este mantiene su valor original.
4.9.3.3 🧠 Fundamentación Teórica
Concepto
Significado
Impacto Visual
Dilatación
\(g \geq f\) siempre (extensiva)
Las regiones claras crecen, los huecos oscuros se encogen
\(B\) mayor
Vecindad más amplia
Crecimiento más agresivo
Reflexión de \(B\)
\(B_{ref}(y,x) = B(-y,-x)\)
Garantiza la definición formal de Minkowski de la dilatación
4.9.3.4 📦 Especificación de Entrada y Salida (VPL)
Entrada:
Línea 1: Entero \(L\).
Línea 2: Entero \(C\).
Línea 3: Entero \(L_B\).
Línea 4: Entero \(C_B\).
Siguientes \(L_B\) líneas: elementos enteros (\(0\) o \(1\)) de la matriz \(B\).
Siguientes \(L\) líneas: elementos enteros de la matriz \(f\).
Salida:
Matriz \(g\) en \(L\) filas y \(C\) columnas, valores enteros separados por espacio.
4.9.3.5 📌 Ejemplos
Entrada
Salida
Observación
3
3
3
3
0 1 0
1 1 1
0 1 0
0 0 0
0 9 0
0 0 0
0 9 0
9 9 9
0 9 0
\(B\) en cruz simétrico: punto aislado se expande en cruz
1
4
1
3
1 1 1
10 200 5 80
200 200 200 80
\(B\) horizontal: cada píxel “atrae” el máximo de los vecinos de la fila
🌱 Simulador EP04_03: Dilatación Plana (mm.dil0)g = f ⊕ B
Cambie el elemento estructurante B (o seleccione los preajustes) y haga clic en las celdas de la imagen original f para encender o apagar píxeles.
Elemento Estructurante B (Clic para Alternar 0/1)
Imagen Original f (5×5)
Dilatada g (f ⊕ B)
g(y,x) = máximo sobre vecinos válidos de B reflejado
Figura 4.32: Simulador EP04_03: Dilatación Binaria Plana (g = f ⊕ B)
%%writefile EP04_03.cpp// your solution
Overwriting EP04_03.cpp
TestSuite("EP04_03.cpp").run()
✔️ EP04_03.cases ya existe en casos/
📋 5 caso(s) cargado(s) de casos/EP04_03.cases
🔍 Probando C++: EP04_03.cpp
⚠️ EP04_03.cpp: archivo vacío (menos de 3 líneas). Pruebas omitidas.