Aller au contenu principal

Filtrage et détection de contours

Cours​

Filtrage linéaire / non linéaire​

Filtres linéaires​

Produit de convolution : I′(i,j)=∑(u,v)∈HI(i−u,j−v).H(u,v)I'(i,j) = \sum \limits_{(u,v) \in H} I(i-u, j - v) . H(u,v), HH centré sur (i,j)(i,j) (avec I(i+u,j+v)I(i+u, j+v), on obtient une corrélation, identique à la convolution pour un noyau symétrique)

  • H : représente la fonction à appliquer (Box, Gaussienne, Laplacien)
  • Efficacité : utiliser des coefficients entiers + un paramètre de normalisation
  • Filtre gaussien : influence des voisins plus ou moins proches ; σ\sigma et la taille du support contrôlent le filtrage

Filtres non linéaires​

Filtre médian : I′(i,j)=median⁡{I(i+u,j+v)∣(u,v)∈H}I'(i,j) = \operatorname{median}\{I(i+u, j+v) \mid (u,v) \in H\}, HH : voisinage autour de (i,j)(i,j). Débruitage et "respect" des principales structures. Élimination des points isolés et des lignes fines, préservation des contours en "marche d'escalier" et lissage des coins.

Filtres min/max : I′(i,j)=min⁡/max⁡{I(i+u,j+v)∣(u,v)∈H}I'(i,j) = \min / \max \{I(i + u, j + v) \mid (u,v) \in H \}

Filtre bilatéral​

Il s'agit de mélanger l'influence spatiale et colorimétrique. Pour un pixel p=(i,j)∈Ip = (i,j) \in I et un pixel q=(u,v)∈V(p)q = (u,v) \in V(p) : I′(p)=∑q∈V(p)Gs(∥p−q∥).Gc(∥I(p)−I(q)∥).I(q)∑q∈V(p)Gs(∥p−q∥).Gc(∥I(p)−I(q)∥)I'(p) = \dfrac{\sum \limits_{q \in V(p)} G_s(\|p-q\|). G_c(\|I(p) - I(q)\|).I(q)}{\sum \limits_{q \in V(p)} G_s(\|p-q\|).G_c(\|I(p) - I(q)\|)}

avec G∗(x)=exp⁡(−x22σ∗2)∈ ]0,1]G_*(x) = \exp(-\dfrac{x^2}{2 \sigma_*^2}) \in \, ]0,1] : si x→+∞x \rightarrow + \infty, G∗(x)→0G_* (x) \rightarrow 0 ; si x→0x \rightarrow 0, G∗(x)→1G_*(x) \rightarrow 1.

Interprétation

Si Gs(.)=Gc(.)=1G_s(.) = G_c(.) = 1, alors I′(p)=∑q∈V(p)I(q)∑q∈V(p)1=∑q∈V(p)I(q)#V(p)I'(p) = \dfrac{\sum \limits_{q \in V(p)} I(q)}{\sum \limits_{q \in V(p)} 1} = \dfrac{\sum \limits_{q \in V(p)} I(q)}{\# V(p)}, c'est-à-dire un filtre moyenneur.

  • Gs(∥p−q∥)G_s(\|p-q \|) : pondération spatiale, un voisin proche spatialement contribue plus qu'un voisin éloigné
  • Gc(∥I(p)−I(q)∥)G_c(\|I(p) - I(q)\|) : pondération colorimétrique, un voisin proche en valeur contribue plus qu'un voisin éloigné. Les pixels situés de l'autre côté d'un contour contribuent peu : les contours sont préservés

NL-means​

Le filtre par moyennes non locales (non-local means) remplace chaque pixel pp par une moyenne pondérée des pixels qq d'une fenêtre de recherche, le poids dépendant de la ressemblance entre les patchs (petits voisinages) centrés en pp et en qq : w(p,q)∝exp⁡(−∥P(p)−P(q)∥2h2)w(p,q) \propto \exp\left(-\dfrac{\|P(p) - P(q)\|^2}{h^2}\right). Des pixels éloignés mais situés dans des structures similaires contribuent ainsi au débruitage, ce qui préserve bien les textures et les contours.

Filtres passe-bas et passe-haut 2D​

Les filtres idéaux, pour une fréquence de coupure DD, s'écrivent :

HL(u,v)={1  si  u2+v2≤D0  si  u2+v2>DHH(u,v)={0  si  u2+v2≤D1  si  u2+v2>DH_L(u,v) = \begin{cases} 1 \; \text{si} \; \sqrt{u^2 + v^2} \leq D \\ 0 \; \text{si} \; \sqrt{u^2 + v^2} > D \end{cases} \quad H_H(u,v) = \begin{cases} 0 \; \text{si} \; \sqrt{u^2 + v^2} \leq D \\ 1 \; \text{si} \; \sqrt{u^2 + v^2} > D \end{cases}

  • Passe-haut : plus DD est grand, plus on ne récupère que les contours et le bruit

  • Passe-bas : plus DD est petit, plus on perd de signal utile (l'image devient floue)

  • Filtre de Butterworth : HLB(u)=11+(uD)2nHHB(u)=11+(Du)2nH_{LB}(u) = \dfrac{1}{1 + (\dfrac{u}{D})^{2n}} \quad H_{HB}(u) = \dfrac{1}{1 + (\dfrac{D}{u})^{2n}}

  • Filtre gaussien : HLG(u,v)=exp⁡(−u2+v22σ2)HHG(u,v)=1−HLG(u,v)H_{LG}(u,v) = \exp(-\dfrac{u^2 + v^2}{2 \sigma^2}) \quad H_{HG}(u,v) = 1 - H_{LG}(u,v)

  • Filtres réjecteur / passe-bande (Butterworth) : HBR(u,v)=11+(wu2+v2(u2+v2)−r2)2nHBP(u,v)=1−HBR(u,v)H_{BR}(u,v) = \dfrac{1}{1+\left(\dfrac{w \sqrt{u^2 + v^2}}{(u^2+v^2)-r^2}\right)^{2n}} \quad H_{BP}(u,v) = 1 - H_{BR}(u,v) avec rr le rayon et ww la largeur de la bande

Dérivées premières et fonctions discrètes​

Les contours impliquent des grandes valeurs de la dérivée f′(x)=df(x)dxf'(x)=\dfrac{df(x)}{dx} (opérateurs du 1er ordre). L'approximation des dérivées (pente) utilise des points à droite et à gauche. Plusieurs approximations sont possibles :

  • Différence à droite (forward) ∂+f(u)=f(u+1)−f(u)\partial^+ f(u) = f(u+1) - f(u)
  • Différence à gauche (backward) ∂−f(u)=f(u)−f(u−1)\partial^- f(u) = f(u) - f(u-1)
  • Différence centrée (moyenne) ∂f(u)=f(u+1)−f(u−1)2\partial f(u) = \dfrac{f(u+1) - f(u-1)}{2}

Pour une image 2D discrète II, le gradient ∇I(i,j)\nabla I(i,j) localisé au point (i,j)(i,j) est le vecteur :

  • ∇I(i,j)=[∂iI(i,j)  ∂jI(i,j)]T\nabla I(i,j) = [\partial_i I(i,j) \; \partial_j I(i,j)]^T
  • Magnitude du gradient (sa norme) ∣∣∇I(i,j)∣∣2=(∂iI(i,j))2+(∂jI(i,j))2||\nabla I(i,j)||_2 = \sqrt{(\partial_i I(i,j))^2 + (\partial_j I(i,j))^2}
  • Direction du gradient : ϕ(I(i,j))=tan⁡−1(∂iI(i,j)∂jI(i,j))\phi(I(i,j)) = \tan^{-1} (\dfrac{\partial_i I(i,j)}{\partial_j I(i,j)})

Différences finies par convolution et moyenneur​

  • Différence à droite : ∂+f(u)=f(u+1)−f(u)\partial^+ f(u) = f(u+1) - f(u), noyau H+=[0  −1  1]H^+ = [0 \; -1 \; 1]
  • Différence centrée : ∂f(u)=f(u+1)−f(u−1)2\partial f(u) = \dfrac{f(u+1) - f(u-1)}{2}, noyau H=12[−1  0  1]H = \frac{1}{2}[ -1 \; 0 \; 1 ], soit ∂f(u)=(f∗H)(u)\partial f(u) = (f \ast H)(u). Les différences finies sont sensibles au bruit : le bruit peut être vu comme un point de contour, il faut donc coupler la différentiation avec un filtrage.
  • Détecteur de Prewitt : HhP=(10−110−110−1)=(111)v⊗(10−1)h  HvP=(111000−1−1−1)=(10−1)v⊗(111)hH_h^P = \begin{pmatrix} 1 & 0 & -1 \\ 1 & 0 & -1 \\ 1 & 0 & -1 \end{pmatrix} = \begin{pmatrix} 1 \\ 1 \\ 1 \end{pmatrix}_ v \otimes \begin{pmatrix} 1 & 0 & -1 \end{pmatrix}_ h \; H_v^P = \begin{pmatrix} 1 & 1 & 1 \\ 0 & 0 & 0 \\ -1 & -1 & -1 \end{pmatrix} = \begin{pmatrix} 1 \\ 0 \\ -1\end{pmatrix}_v \otimes \begin{pmatrix} 1 & 1 & 1 \end{pmatrix}_h
  • Détecteur de Sobel : HhS=(10−120−210−1)=(121)v⊗(10−1)h  HvS=(121000−1−2−1)=(10−1)v⊗(121)hH_h^S = \begin{pmatrix} 1 & 0 & -1 \\ 2 & 0 & -2 \\ 1 & 0 & -1 \end{pmatrix} = \begin{pmatrix} 1 \\ 2 \\ 1 \end{pmatrix}_ v \otimes \begin{pmatrix} 1 & 0 & -1 \end{pmatrix}_ h \; H_v^S = \begin{pmatrix} 1 & 2 & 1 \\ 0 & 0 & 0 \\ -1 & -2 & -1 \end{pmatrix} = \begin{pmatrix} 1 \\ 0 \\ -1\end{pmatrix}_v \otimes \begin{pmatrix} 1 & 2 & 1 \end{pmatrix}_h

Autres approches : dérivées secondes​

Détection du contour par le passage à zéro de la dérivée seconde. Pour cela on utilise le laplacien Δf(x)=(∇2f)(x)=∂x2f(x)=∂x(∂xf(x))\Delta f(x) = (\nabla^2 f)(x) = \partial^2_x f(x) = \partial_x(\partial_x f(x)). Son approximation discrète est ΔI(i,j)=∂i2I(i,j)+∂j2I(i,j)\Delta I(i,j) = \partial^2_i I(i,j) + \partial^2_j I(i,j).

Amélioration : filtre passe bas​

L'idée est de filtrer l'image par une gaussienne GσG_\sigma de largeur σ\sigma. Le laplacien de II filtré par GσG_\sigma devient Δ(I∗Gσ)=I∗ΔGσ\Delta(I \ast G_\sigma) = I \ast \Delta G_\sigma : cela revient à convoluer directement II avec le Laplacien de GσG_\sigma (LoG). Attention : la convolution avec une gaussienne trop large rend l'image floue et les contours fins sont perdus.

Schéma classique d'extraction de contours :

  • calculer le gradient (∇\nabla) ou le Laplacien (Δ\Delta)
  • localiser les maxima locaux de la norme du gradient ou le passage à zéro du Laplacien
  • un seuillage permet d'avoir la carte binaire de contour mais il y a un risque de déconnexion des contours (améliorable via des algorithmes de re-chaînage)
  • utilisation des contours dans d'autres applications

Mise en pratique​

median-filter <r> <ims> <imd>​

Écrire le programme median-filter.cpp

  • ce programme permet de charger une image donnée en paramètre <ims>
  • l'image source est considérée comme une image en niveaux de gris
  • le programme réalise le filtrage médian où la fenêtre de recherche de taille (2r+1)×(2r+1)(2r + 1) \times (2 r +1) est déterminée par le paramètre <r>
  • sauver le résultat dans l'image <imd>
  • comparer avec la fonction medianBlur
  • visualiser avec pvisu les différents résultats

bilateral <sigma_s> <sigma_g> <ims> <imd>​

Écrire le programme bilateral.cpp

  • ce programme permet de charger une image donnée en paramètre <ims>
  • l'image source est considérée comme une image en niveaux de gris
  • le programme réalise le filtrage bilatéral
  • le paramètre <sigma_g> permet de calculer la Gaussienne pour la pondération sur les intensités et <sigma_s> celle pour la pondération des distances. On pourra pré-calculer ces coefficients et seuiller celle sur les distances afin de déterminer la taille du voisinage : Gσs(x)=exp⁡(−x2/2σs2)≤sG_{\sigma_s}(x) = \exp(-x^2 / 2 \sigma^2_s) \leq s, par exemple s=0.1s=0.1
  • le programme sauve l'image <imd>
  • comparer les résultats avec la fonction bilateralFilter
  • visualiser avec pvisu les différents résultats

nl-means <sigma> <ims> <imd>​

Écrire le programme nl-means.cpp

  • ce programme permet de charger une image donnée en paramètre <ims>
  • l'image source est considérée comme une image en niveaux de gris
  • le programme réalise le filtrage par moyennes non locales
  • le paramètre <sigma> permet de calculer les poids associés aux patchs
  • les auteurs donnent des paramètres empiriques : une fenêtre de recherche de taille 11×1111 \times 11 et des patchs 7×77 \times 7
  • le programme sauve l'image <imd>
  • visualiser avec pvisu les différents résultats

fourier <ims> <freq>​

Écrire le programme fourier.cpp

  • ce programme permet de charger une image donnée en paramètre <ims>
  • le programme réalise la transformée de Fourier directe (fonction dft)
  • affiche le spectre d'amplitude et de phase (centrés) et la sauve dans les fichiers magnitude.png et phase.png
  • le programme réalise un filtrage dans le domaine de Fourier et annule (de manière symétrique) la fréquence <freq> donnée en paramètre
  • sauve le spectre d'amplitude modifié dans un fichier magnitude-modify.png afin d'observer l'annulation des fréquences
  • le programme réalise la transformée de Fourier inverse et sauve le résultat dans le fichier inverse.png
  • visualiser avec pvisu les différents résultats