TNI+VO · Exercice de Programmation

EP04_07 — ⛰️ Dilatation et Érosion Pondérées (mm.dil1 / mm.ero1)

4.9.7 EP04_07 ⛰️ Dilatation et Érosion Pondérées (mm.dil1 / mm.ero1)

Jusqu’à présent, l’élément structurant disait simplement « ce voisin compte » ou « ne compte pas » — mais dans les modèles numériques de terrain (utilisés en SIG et en planification du drainage urbain), chaque voisin devrait avoir un poids différent selon la distance ou la direction du relief. Les versions pondérées de la dilatation et de l’érosion, implémentées dans morph.py comme mm.dil1(f, b) et mm.ero1(f, b), additionnent (ou soustraient) le poids de chaque voisin avant de prendre le maximum (ou le minimum) — généralisant ainsi tout ce qui a été fait dans les EP précédents. Voir dans Figure 4.36 une simulation de cet EP.

4.9.7.1 📋 Directives d’Implémentation

  1. Dimensions de l’image : Lire les entiers \(L\) (lignes) et \(C\) (colonnes) de \(f\).
  2. Dimensions de \(b\) : Lire les entiers \(L_B\) (lignes) et \(C_B\) (colonnes) de l’élément structurant pondéré.
  3. Poids : Lire la matrice \(b\) des poids entiers (ils peuvent être négatifs, nuls ou positifs), ligne par ligne.
  4. Données : Lire la matrice \(f\) (l’image d’origine), ligne par ligne.
  5. Voisinage sans padding : Pour chaque pixel \((y,x)\), parcourir toutes les positions \((by,bx)\) de \(b\) (pas seulement celles où la valeur serait \(1\) — ici tout poids participe), en utilisant le même décalage que dans les EP précédents : \[ 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 \] Écarter tout \((v_y,v_x)\) hors de \([0,L)\times[0,C)\).
  6. Dilatation pondérée : Calculer \[ g_{dil}(y,x) = \max\Big(f(y,x),\ \max_{(v_y,v_x)\ \text{valide}} \big(f(v_y,v_x) + b(by,bx)\big)\Big) \]
  7. Érosion pondérée : Calculer, en utilisant le même \(b\) et sans réflexion : \[ g_{ero}(y,x) = \min\Big(f(y,x),\ \min_{(v_y,v_x)\ \text{valide}} \big(f(v_y,v_x) - b(by,bx)\big)\Big) \]
  8. Sortie : Afficher d’abord la matrice complète \(g_{dil}\), puis ensuite la matrice complète \(g_{ero}\).

4.9.7.2 📌 Contraintes Computationnelles

  • Aucune des deux ne réfléchit \(b\) — la version pondérée n’utilise pas la réflexion, même pour la dilatation (contrairement à mm.dil0).
  • Tous les poids participent : Il n’existe pas ici de filtre « \(B=1\) » ; même un poids \(0\) entre en compte.
  • Sans padding : les voisins hors de l’image sont ignorés, jamais virtuellement remplis.
  • Type : La sortie peut contenir des valeurs négatives ou supérieures à \(255\) — pas de clipping dans cet EP.
  • Astuce : Pour supprimer les messages de dépassement lors du dépassement des limites du type uint8, inclure au début du code :
import warnings
warnings.filterwarnings("ignore")

4.9.7.3 🧠 Fondement Théorique

Concept Signification Impact Visuel
Poids positif « Tire » la valeur du voisin vers le haut lors de la dilatation Simule un relief qui monte dans cette direction
Poids négatif Réduit la contribution du voisin Simule la distance ou une atténuation directionnelle
Dualité pondérée \(\text{ero1}(f,b) = -\text{dil1}(-f,b)\) La symétrie entre les deux opérations se maintient même avec des poids

4.9.7.4 📦 Spécification d’Entrée et de Sortie (VPL)

Entrée :

  • Ligne 1 : Entier \(L\).
  • Ligne 2 : Entier \(C\).
  • Ligne 3 : Entier \(L_B\).
  • Ligne 4 : Entier \(C_B\).
  • Les \(L_B\) lignes suivantes : éléments entiers (pouvant être négatifs) de la matrice \(b\).
  • Les \(L\) lignes suivantes : éléments entiers de la matrice \(f\).

Sortie :

  • D’abord la matrice \(g_{dil}\) en \(L\) lignes et \(C\) colonnes.
  • Ensuite la matrice \(g_{ero}\) en \(L\) lignes et \(C\) colonnes.

4.9.7.5 📌 Exemples

Entrée Sortie Observation
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
Le poids central \(2\) accélère la croissance lors de la dilatation et le rétrécissement lors de l’érosion
⛰️ Simulateur EP04_07 : Poids dans l'Élément Structurant dil1 / ero1

Ajustez les poids de l'élément structurant b avec les curseurs et observez l'effet de la dilatation et de l'érosion pondérées sur la matrice f.

Poids b (Ajustez les Curseurs par Cellule)
f Original
dil1(f, b) (Dilatation)
ero1(f, b) (Érosion)
Figure 4.36: Simulateur EP04_07 : Dilatation et Érosion avec Poids (mm.dil1 / mm.ero1)
%%writefile EP04_07.py
# Code Python
Overwriting EP04_07.py
TestSuite("EP04_07.py").run()
✔️ EP04_07.cases existe déjà dans casos/
📋 3 cas chargé(s) depuis casos/EP04_07.cases

🔍 Test de Python : EP04_07.py
⚠️ EP04_07.py : fichier vide (moins de 3 lignes). Tests ignorés.