Blur (gaussien)
Auteurs: Daniel Lacroix
Date de parution:30 avril 2006
Dernière modification:9 juin 2006

Le premier type de filtre que l’on va voir sont les filtres de moyennage. On se base sur le principe que l’information dans une image est redondante. On va se servir de cette redondance pour supprimer le bruit. Pour cela, on calcule la valeur d’un point après filtrage comme étant la moyenne des points de son voisinnage.

Si on considère que l’on fait la moyenne sur les 9 points qui entourent le point considéré, le calcul ressemble à :


pix_res(x,y) = (pix(x-1,y-1)+pix(x,y-1)+pix(x+1,y-1)+
               pix(x-1,y  )+pix(x,y  )+pix(x+1,y  )+
               pix(x-1,y+1)+pix(x,y+1)+pix(x+1,y+1))/9.0;

Généralement on représente le filtre sous forme d’un masque où chaque case correspond à la valeur par laquelle il faut multiplier le point correspondant dans l’image source. Ensuite on fait la somme de toutes les multiplications et on divise par la somme des coefficients. On obtiendrait pour la moyenne le masque :

111
111
111

Et il faudra diviser le résultat par 9 (9*1).

Si on utilise cette notation c’est parce que l’on ne fait pas la moyenne qu’avec des coefficients de 1. En effet, on peut pondérer les différents points du voisinnage avec des coefficients différents. Par exemple, on peut favoriser le point de l’image source sur ses voisins.

Voici un exemple de filtre avec pondération en forme de gaussienne pour éliminer les bruits dit gaussiens :

121
242
121

La somme étant alors à diviser par 16. C’est souvent ce filtre qui est utilisé pour faire du "blur".

PNG - 95.4 ko
image avant utilisation du filtre gaussien
PNG - 100.9 ko
image après utilisation du filtre gaussien

Voici le code C qui permet de réaliser ce filtre :


/**************************************************************/
/* Fait un flou gaussien de l'image psrc et place le résultat */
/* dans pdest. pdest et psrc doivent avoir la même taille.    */
void image_blur(image *pdest, image *psrc)
{ int32 vx,vy;
 int i,j;
 float res_r, res_g, res_b;
 pix vpix;
 /* définition du filtre utilisé (en forme de cloche => gaussien) */
 float filter[3][3] = {{1.0,2.0,1.0},
                       {2.0,4.0,2.0},
                        {1.0,2.0,1.0}};
 float filter_div = 16.0;

 /* si les préconditions ne sont pas remplies, on quitte */
 if((pdest == NULL) || (psrc == NULL) ||
    (psrc->width != pdest->width) || (psrc->height != pdest->height))
   return;

 for(vy = 0;vy < psrc->height; vy++)
 {
   for(vx = 0;vx < psrc->width; vx++)
   {
     res_r = 0;
     res_g = 0;
     res_b = 0;
     for(j=0;j<3;j++)
       for(i=0;i<3;i++)
        {
           vpix = get_pix(psrc, vx-(3>>1)+i, vy-(3>>1)+j);
          res_r += (float)COL_RED  (vpix) * filter[j][i];
          res_g += (float)COL_GREEN(vpix) * filter[j][i];
          res_b += (float)COL_BLUE (vpix) * filter[j][i];
        }
     res_r /= filter_div;
     res_g /= filter_div;
     res_b /= filter_div;

     /* on sature le résultat */
     res_r = (res_r > 255.0)? 255.0 : ((res_r < 0.0)? 0.0:res_r);
     res_g = (res_g > 255.0)? 255.0 : ((res_g < 0.0)? 0.0:res_g);
     res_b = (res_b > 255.0)? 255.0 : ((res_b < 0.0)? 0.0:res_b);

     /* on place le résultat dans l'image destination */      
     put_pix_alpha_replace(pdest, vx, vy, COL(
       (uint8)res_r,(uint8)res_g,(uint8)res_b));
   }
 }
}
/**************************************************************/


Site créé avec SPIP. Conçu pour être visionné avec Mozilla