Projet du cours MTI Sujet : Filtrage Anisotrope ou Filtrage Tobogan Auteurs : Thomas DESCHAMPS - Meïr ABERGEL
Ce document est divisé en trois parties :
Le filtrage Anisotrope
Le filtrage Tobogan
Comparaison des filtres sur quelques exemples
Conclusion
Annexe
où 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
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
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
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
{
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");
}