Projet du cours MTI Sujet : Filtrage Anisotrope ou Filtrage Tobogan Auteurs : Thomas DESCHAMPS - Meïr ABERGEL

Filtrage Anisotrope - Filtrage Tobogan

Ce document est divisé en trois parties :

Le filtrage Anisotrope
Le filtrage Tobogan
Comparaison des filtres sur quelques exemples
Conclusion
Annexe


Le Filtrage Anisotrope

L'opération de convolution d'une image par le noyau d'une gaussienne d'une certaine variance entraine un processus de diffusion de l'intensité image autours des pixels voisins.
Cette difusion est de type isotrope : Elle agit de la même manière dans toutes les directions, et ne possède aucune direction ni zone privilégiée. Ce défaut peut poser de gros problèmes pour la restauration d'images bruitées : Les régions d'intensités non homogènes (présentant des discontinuités importantes de niveaux de gris) seront lissées, et le contraste sera notablement atténué
Pour traiter ce problème, la diffusion anisotrope a été proposée. Cette diffusion consiste à effectuer une forte diffusion dans les zones à faible gradient, et une diffusion faible dans les zones a fort gradient
Formellement, on effectue une convolution de l'image par le noyau de l'operateur :

c(.) désigne une fonction décroissante, telle que le noyau de la chaleur.
Le schémas de traitement numérique de l'image est :


Cette méthode présente toutefois plusieurs inconvénients :
- Le filtrage est innéficace dans les zones de fortes discontinuités
- Les solutions de l'équation différentielle peuvent ne pas exister, et le schémas numérique peut se montrer instable


Le Filtrage Tobogan

Le filtre tobogan s'effectue en deux étapes : Le filtrage, puis une segmentation de contraste (Filtre de SUK) .

Le filtrage Toboggan

Le but de ce traitement est une augmentation du contraste
A partir d'un point non deja parcouru : On prend la carte d'une certaine mesure de discontinuite (DCE, Deriche, user defined) et on descend cette carte comme sur un toboggan (d'ou le nom) en empilant tous les points par lesquels on passe jusqu'a ce qu'on tombe dans un minimum local, autrement dit la fin du toboggan. On attribue alors la valeur du niveau de gris du point minimum local et on l'attribue a tous les points par lesquels on est passe. On attribue l'étiquette parcouru a tous les points par lesquels on est passé. Puis on passe a un autre point non parcouru, et ce jusqu'a ce que tous les points aient été parcourus

La segmentation de contraste

La segmentation de contraste consiste à séparer l'image en classes pour la relation : Le pixel 1 est en relation avec le pixel 2 si et seulement si leur différence de contraste est inférieure à s On obtient ainsi des zones de contraste, ce qui permet une detection des contours



Comparaison des filtres sur des exemples

Originaux :

On etudie le filtrage sur trois originaux :
- Une image tres contrastee
- Une image avec un spectre important dans les hautes frequences (barres des immeubles)
- Une photo "banale", trouvee sur le WEB

Filtrage Anisotrope avec un faible coefficient de diffusion:

Les photos avec de fort contrastes ne sont quasiment pas affectees (c'etait bien le but du filtrage anisotrope), tandis que la troisieme image est considerablement assombrie : sur les zones de faible contraste, la densite s'est considerablement diffusee

Filtrage Anisotrope avec un fort coefficient de diffusion:

Les zones de fort contraste sur les deux premieres photos resistent assez bien au filtrage a fort coefficient de diffusion (En particulier, la premiere photo n'est quasiment pas modifiee : on a perdu quelques details au niveau du bureau, et les attaches des fenetres ont disparu). La troisieme image n'a pas resiste au traitement : seule les zones tres caracteristiques du visage (yeux, cheveux, coin de la bouche) sont encore reconaissables

Filtrage Tobogan :

Le filtrage Tobogan a un effet de "granularisation" des images : il a tendance a augmenter le contraste des points isoles


Conclusion

On ne peut pas dire que le filtrage tobogan soit meilleur ou moins bon que le filtrage anisotrope. L'intérêt du filtrage tobogan réside dans le fait qu'il est rapide (en O(n)), conceptuellement plus simple et plus stable que le filtrage anisotrope (et donc son implantation numérique est plus facilement modifiable)






Annexe

Programme C du filtrage tobogan

#include
#include
#include
#include
#include
int LireFichierPgm(const char * Path, unsigned int ** Tab, int & Dx,int & Dy)
{
FILE * F = fopen(Path,"rb");
int Size;


if (F == NULL)
return 0;

char FBuf[1024];

fgets(FBuf,1023,F);
if (strcmp(FBuf,"P2\n"))
{
fclose(F);
return 0;
}
do
{
fgets(FBuf,1023,F);
}
while (! feof(F) && (FBuf[0] == '#'));


if (sscanf(FBuf,"%d %d",&Dx,&Dy) != 2)
{
fclose(F);
return 0;
}


fgets(FBuf,1023,F);

Size = Dx * Dy;

*Tab= new unsigned int [Size];

/* char s[1000];
while (fgets(s,1000,F)!=NULL)
printf("%s",s);
*/

int k=0;
while (! feof(F))
{
fscanf(F,"%d",&(*Tab)[k]);
k++;
}
printf("\nDernier element:%d\n",(*Tab)[Size]);

fclose(F);

return 1;
}


int SaveToPgm (const unsigned int * Tab, const int Dx, const int Dy, const char * FileName)
{
FILE * F = fopen(FileName,"wb");

if (F == NULL)
return 0;

int Size = Dx * Dy;

fprintf(F,"P2\n");
fprintf(F,"# Image test\n"); // Commentaire
fprintf(F,"%d %d\n255\n",Dx,Dy);

for(int k=0;k fprintf(F,"%d ",Tab[k]);

fclose(F);

return 1;
}



int low(const unsigned int * Tab,unsigned int ** Newtab, int Offset, const int Dx, const int Dy)
{
int minn = 255;
int Compt = 0;
int i = Offset % Dx;
int j = Offset / Dx;
for(int k=max(i-1,0); k < min(i+1,Dx-1);k++)
for(int l=max(j-1,0); l < min(j+1,Dy-1);l++)
{
if((Tab[k+l*Dx] {
minn = Tab[k+l*Dx];
Compt++;
}
}
if(Compt>1)
return minn;
}

int high(const unsigned int * Tab, unsigned int ** Newtab, int Offset, const int Dx, const int Dy)
{
int maxx = 0;
int i = Offset % Dx;
int j = Offset / Dx;
for(int k=max(i-1,0); k < min(i+1,Dx-1);k++)
for(int l=max(j-1,0); l < min(j+1,Dy-1);l++)
{
if((Tab[k+l*Dx]>maxx))
maxx = Tab[k+l*Dx];
}

return maxx;
}

int DCE(const unsigned int * Tab,unsigned int ** Newtab, int Offset, const int Dx, const int Dy)
{
return min(Tab[Offset]-low(Tab,Newtab,Offset,Dx,Dy), high(Tab,Newtab,Offset,Dx,Dy) -Tab[Offset]);
}

int least(int Offset, const int Dx, const int Dy, const unsigned int * Tab,unsigned int * * Newtab)
{
int valbis;
int val = 1000000;
int Offsetmin = Offset;
int i = Offset % Dx;
int j = Offset / Dx;
for(int k=max(i-1,0); k < min(i+1,Dx-1);k++)
for(int l=max(j-1,0); l < min(j+1,Dy-1);l++)
{
valbis = DCE(Tab,Newtab,k+l*Dx,Dx,Dy);
if((valbis < val))
{
val = valbis;
Offsetmin = k+l*Dx;
}
}
return Offsetmin;
}

void Toboggan(const unsigned int * Tab,unsigned int ** Newtab, const int Dx, const int Dy)
{
int Size = Dx*Dy,Compt = 1;
int val, Offsetval,val1,val2,val3;
unsigned int * stack = new unsigned int [Size];
int indice_stack = 1;
*Newtab = new unsigned int [Size];

for(int t=0;t {
(*Newtab)[t] = 300;
}

for(int i=0;i for(int j=0;j if((*Newtab)[i+j*Dx] = 300)
{
Offsetval = i+j*Dx;
Compt = 1;

indice_stack = 1;
while(DCE(Tab,Newtab,least(Offsetval,Dx,Dy,Tab,Newtab),Dx,Dy) < DCE(Tab,Newtab,Offsetval,Dx,Dy))
{
stack[indice_stack] = Offsetval;
indice_stack++;
Offsetval = least(Offsetval,Dx,Dy,Tab,Newtab);
Compt++;
if((*Newtab)[least(Offsetval,Dx,Dy,Tab,Newtab)]!=300)
break;
}
val = Tab[Offsetval];
(*Newtab)[Offsetval] = val;
while(indice_stack!=1)
{
indice_stack--;
Offsetval = stack[indice_stack];
(*Newtab)[Offsetval] = val;
}
}
}


void main(int argc, const char * argv[])
{

unsigned int * Tab;
unsigned int * Newtab;
int Dx, Dy;
char FileName[1024];

strcpy(FileName, "maitre.pgm");

if (! LireFichierPgm( FileName, &Tab, Dx, Dy))
{
printf("Impossible d'ouvrir %s \n", argv[1]);
exit(0);
}
printf("\nDebut du toboggan\n");
Toboggan(Tab,&Newtab,Dx,Dy);
printf("\nToboggan termine\n");
SaveToPgm(Newtab,Dx,Dy,"resultat.pgm");

printf("%d %d %d\n",Dx,Dy,Dx*Dy);
printf("OK !\n");

}