Ajuste los pesos del elemento estructurante b con los controles deslizantes y observe el efecto de la dilatación y erosión con pesos sobre la matriz f.
4.9.7 EP04_07 ⛰️ Dilatación y Erosión con Pesos (mm.dil1 / mm.ero1)
Hasta ahora, el elemento estructurante solo decía “este vecino cuenta” o “no cuenta” — pero en modelos digitales de elevación (usados en SIG y en planificación de drenaje urbano), cada vecino debería tener un peso diferente dependiendo de la distancia o de la dirección del relieve. Las versiones ponderadas de la dilatación y de la erosión, implementadas en morph.py como mm::dil1(f, b) y mm::ero1(f, b), suman (o restan) el peso de cada vecino antes de tomar el máximo (o mínimo) — generalizando todo lo realizado en los EPs anteriores. Ver en Figura 4.36 una simulación de este EP.
4.9.7.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 ponderado.
- Pesos: Leer la matriz \(b\) de pesos enteros (pueden ser negativos, cero o positivos), fila a fila.
- Datos: Leer la matriz \(f\) (la imagen original), fila a fila.
- Vecindario sin padding: Para cada píxel \((y,x)\), recorrer todas las posiciones \((by,bx)\) de \(b\) (no solo donde valdría \(1\) — aquí todo peso participa), usando el mismo desplazamiento de los EPs anteriores: \[ 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)\).
- Dilatación ponderada: Calcular \[ g_{dil}(y,x) = \max\Big(f(y,x),\ \max_{(v_y,v_x)\ \text{válido}} \big(f(v_y,v_x) + b(by,bx)\big)\Big) \]
- Erosión ponderada: Calcular, usando el mismo \(b\) y sin reflejar: \[ g_{ero}(y,x) = \min\Big(f(y,x),\ \min_{(v_y,v_x)\ \text{válido}} \big(f(v_y,v_x) - b(by,bx)\big)\Big) \]
- Salida: Mostrar primero la matriz \(g_{dil}\) completa, y después la matriz \(g_{ero}\) completa.
4.9.7.2 📌 Restricciones Computacionales
- Ninguna de las dos refleja \(b\) — la versión ponderada no usa reflexión, incluso en la dilatación (diferente de
mm::dil0). - Todos los pesos participan: No existe aquí el filtro “\(B=1\)”; incluso el peso \(0\) entra en la cuenta.
- Sin padding: los vecinos fuera de la imagen se ignoran, nunca se rellenan virtualmente.
- Tipo: La salida puede contener valores negativos o mayores que \(255\) — no hay clipping en este EP.
- Consejo: Para eliminar mensajes de desbordamiento al superar los límites del tipo uint8, incluir al inicio del código:
import warnings
warnings.filterwarnings("ignore")4.9.7.3 🧠 Fundamentación Teórica
| Concepto | Significado | Impacto Visual |
|---|---|---|
| Peso positivo | “Empuja” el valor del vecino hacia arriba en la dilatación | Simula relieve que asciende en esa dirección |
| Peso negativo | Reduce la contribución del vecino | Simula distancia o atenuación direccional |
| Dualidad ponderada | \(\text{ero1}(f,b) = -\text{dil1}(-f,b)\) | La simetría entre las dos operaciones se mantiene incluso con pesos |
4.9.7.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 (pueden ser negativos) de la matriz \(b\).
- Siguientes \(L\) líneas: elementos enteros de la matriz \(f\).
Salida:
- Primero la matriz \(g_{dil}\) en \(L\) líneas y \(C\) columnas.
- A continuación la matriz \(g_{ero}\) en \(L\) líneas y \(C\) columnas.
4.9.7.5 📌 Ejemplos
| Entrada | Salida | Observación |
|---|---|---|
| 3 3 3 3 0 1 0 1 2 1 0 1 0 10 20 30 40 50 60 70 80 90 |
50 60 61 80 90 91 81 91 92 8 9 19 9 10 20 39 40 50 |
Peso central \(2\) acelera el crecimiento en la dilatación y la contracción en la erosión |
⛰️ Simulador EP04_07: Pesos en el Elemento Estructurante
dil1 / ero1
Pesos b (Ajuste los Sliders por Celda)
f Original
dil1(f, b) (Dilatación)
ero1(f, b) (Erosión)
%%writefile EP04_07.cpp
// your solutionOverwriting EP04_07.cpp
TestSuite("EP04_07.cpp").run()✔️ EP04_07.cases ya existe en casos/
📋 3 caso(s) cargado(s) de casos/EP04_07.cases
🔍 Probando C++: EP04_07.cpp
⚠️ EP04_07.cpp: archivo vacío (menos de 3 líneas). Pruebas omitidas.