English version

Le Coin du Traitement d'Image


Filtre Mean Shift
Précédent 

Le filtre Mean Shift est un lissage de l'image par moyennage qui préserve les contours.

Il possède deux paramètres : un voisinage de pixel et une valeur d'intensité Imin correspondant au gradient minimum d'un contour.

Le principe est d'appliquer l'algorithme suivant pour chaque pixel l'un après l'autre :

Le résultat avec une fenêtre carrée 9x9 pixels et une intensité minimale de gradient de contour de 20 par canal est présenté ci-dessous. La première ligne donne les images bruités en entrée, la seconde le résultat, la troisième et la quatrième montrent un détail avec des couleurs renforçant les contrastes.

Click to enlarge. Click to kill. Click to enlarge. Click to kill. Click to enlarge. Click to kill. Click to enlarge. Click to kill.
Click to enlarge. Click to kill. Click to enlarge. Click to kill. Click to enlarge. Click to kill. Click to enlarge. Click to kill.

Click to enlarge. Click to kill. Click to enlarge. Click to kill. Click to enlarge. Click to kill. Click to enlarge. Click to kill.
Click to enlarge. Click to kill. Click to enlarge. Click to kill. Click to enlarge. Click to kill. Click to enlarge. Click to kill.
Gaussien (sigma=20)Uniforme (+/-20)Poivre et sel (3%)Périodique (jpg)

Temps d'exécution sur un AMD 1800+ pour l'image 384x288 : 0.95 secondes pour les bruits gaussiens et uniformes, 0.49 secondes pour le "poivre et sel" et le périodique (convergence plus rapide).

Première remarque : ce filtre préserve bien les contours de gradients supérieur à Imin.

Seconde remarque : les résultats sur les bruits gaussiens, uniformes et périodiques sont excellents au vu du fort bruit ajouté.

Troisième remarque : le filtre n'est pas du tout adapté au bruit "poivre et sel". En effet, ce type de bruit est considéré comme un contour, et donc non filtré.

Le code source en C du coeur de l'algorithme est donné ci-dessous. Les variables non déclarées et la gestion de la structure image sont sans ambiguité et doivent être complétées pour avoir un programme compilable.

// Loop on pixels for(int v=0; v<sizeV; ++v) { for(int u=0; u<sizeU; ++u) { // Compute mean box int uMin = utMax(u-halfWindowSize, 0); int uMax = utMin(u+halfWindowSize, sizeU-1); int vMin = utMax(v-halfWindowSize, 0); int vMax = utMin(v+halfWindowSize, sizeV-1); // Initialize pixel filtering int startOffset = u + v*sizeU; int currentR = bufferR[startOffset]; int currentG = bufferG[startOffset]; int currentB = bufferB[startOffset]; // Filter the pixel int iterationQty = 10; // Convergence with integers is not ensured while(iterationQty--) { // Compute mean inside noise sphere int qty = 0; int sumR = 0; int sumG = 0; int sumB = 0; meanIterationQty += 1; for(int v1=vMin; v1<=vMax; ++v1) { int offset = uMin + v1*sizeU; for(int i=1+uMax-uMin; i; --i, ++offset) { if(utAbs(currentR-(int)bufferR[offset])+ utAbs(currentG-(int)bufferG[offset])+ utAbs(currentB-(int)bufferB[offset])<noiseIntensity) { sumR += bufferR[offset]; sumG += bufferG[offset]; sumB += bufferB[offset]; qty += 1; } } } // Update the color int oldR = currentR; int oldG = currentG; int oldB = currentB; currentR = sumR/qty; currentG = sumG/qty; currentB = sumB/qty; // Check the convergence if(oldR==currentR && oldG==currentG && oldB==currentB) { break; } } // End of iterations on the pixel // Store the result for this pixel resultBufR[startOffset] = (unsigned char)currentR; resultBufG[startOffset] = (unsigned char)currentG; resultBufB[startOffset] = (unsigned char)currentB; } // End of loop on columns } // End of loop on rows

Précédent 

visiteurs
Généré avec l'outil webSitePP.py
Dernières modifications le 20 octobre 2004