Regola i pesi dell'elemento strutturante b con i cursori e osserva l'effetto di dilatazione ed erosione con pesi sulla matrice f.
4.9.7 EP04_07 ⛰️ Dilatazione ed Erosione con Pesi (mm.dil1 / mm.ero1)
Finora, l’elemento strutturante diceva solo “questo vicino conta” o “non conta” — ma nei modelli digitali di elevazione (usati nei GIS e nella pianificazione del drenaggio urbano), ogni vicino dovrebbe avere un peso diverso a seconda della distanza o della direzione del rilievo. Le versioni ponderate della dilatazione e dell’erosione, implementate in morph.py come mm.dil1(f, b) e mm.ero1(f, b), sommano (o sottraggono) il peso di ciascun vicino prima di prendere il massimo (o il minimo) — generalizzando tutto ciò che è stato fatto negli EP precedenti. Vedere in Figura 4.36 una simulazione di questo EP.
4.9.7.1 📋 Linee Guida di Implementazione
- Dimensioni dell’immagine: Leggere gli interi \(L\) (righe) e \(C\) (colonne) di \(f\).
- Dimensioni di \(b\): Leggere gli interi \(L_B\) (righe) e \(C_B\) (colonne) dell’elemento strutturante ponderato.
- Pesi: Leggere la matrice \(b\) di pesi interi (possono essere negativi, zero o positivi), riga per riga.
- Dati: Leggere la matrice \(f\) (l’immagine originale), riga per riga.
- Vicinato senza padding: Per ogni pixel \((y,x)\), percorrere tutte le posizioni \((by,bx)\) di \(b\) (non solo dove varrebbe \(1\) — qui tutto il peso partecipa), usando lo stesso spostamento degli EP precedenti: \[ 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 \] Scartare ogni \((v_y,v_x)\) fuori da \([0,L)\times[0,C)\).
- Dilatazione ponderata: Calcolare \[ g_{dil}(y,x) = \max\Big(f(y,x),\ \max_{(v_y,v_x)\ \text{valido}} \big(f(v_y,v_x) + b(by,bx)\big)\Big) \]
- Erosione ponderata: Calcolare, usando lo stesso \(b\) e senza riflessione: \[ g_{ero}(y,x) = \min\Big(f(y,x),\ \min_{(v_y,v_x)\ \text{valido}} \big(f(v_y,v_x) - b(by,bx)\big)\Big) \]
- Uscita: Mostrare prima la matrice completa \(g_{dil}\), e poi la matrice completa \(g_{ero}\).
4.9.7.2 📌 Vincoli Computazionali
- Nessuna delle due riflette \(b\) — la versione ponderata non usa riflessione, nemmeno nella dilatazione (diversamente da
mm.dil0). - Tutti i pesi partecipano: Non esiste qui il filtro “\(B=1\)”; anche il peso \(0\) entra nel calcolo.
- Senza padding: i vicini fuori dall’immagine sono ignorati, mai virtualmente riempiti.
- Tipo: L’uscita può contenere valori negativi o maggiori di \(255\) — non c’è clipping in questo EP.
- Suggerimento: Per rimuovere i messaggi di overflow quando si superano i limiti del tipo uint8, includere all’inizio del codice:
import warnings
warnings.filterwarnings("ignore")4.9.7.3 🧠 Fondamenti Teorici
| Concetto | Significato | Impatto Visivo |
|---|---|---|
| Peso positivo | “Spinge” il valore del vicino verso l’alto nella dilatazione | Simula un rilievo che sale in quella direzione |
| Peso negativo | Riduce il contributo del vicino | Simula distanza o attenuazione direzionale |
| Dualità ponderata | \(\text{ero1}(f,b) = -\text{dil1}(-f,b)\) | La simmetria tra le due operazioni si mantiene anche con i pesi |
4.9.7.4 📦 Specifica di Input e Output (VPL)
Input:
- Riga 1: Intero \(L\).
- Riga 2: Intero \(C\).
- Riga 3: Intero \(L_B\).
- Riga 4: Intero \(C_B\).
- Prossime \(L_B\) righe: elementi interi (possono essere negativi) della matrice \(b\).
- Prossime \(L\) righe: elementi interi della matrice \(f\).
Output:
- Prima la matrice \(g_{dil}\) in \(L\) righe e \(C\) colonne.
- Successivamente la matrice \(g_{ero}\) in \(L\) righe e \(C\) colonne.
4.9.7.5 📌 Esempi
| Input | Output | Osservazione |
|---|---|---|
| 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 |
Il peso centrale \(2\) accelera la crescita nella dilatazione e il restringimento nell’erosione |
⛰️ Simulatore EP04_07: Pesi nell'Elemento Strutturante
dil1 / ero1
Pesi b (Regola i Cursori per Cella)
f Originale
dil1(f, b) (Dilatazione)
ero1(f, b) (Erosione)
%%writefile EP04_07.py
# Codice PythonOverwriting EP04_07.py
TestSuite("EP04_07.py").run()✔️ EP04_07.cases esiste già in casos/
📋 3 caso/i caricato/i da casos/EP04_07.cases
🔍 Test di Python: EP04_07.py
⚠️ EP04_07.py: file vuoto (meno di 3 righe). Test saltati.