View  Edit  Attributes  History  Attach  Print  Search

ACCUEIL | ARDUINO > S'INSTALLER > DEBUTER > APPROFONDIR | PROCESSING | MECATRONIQUE | MATERIEL | OUTILS | TESTS | Plus...|
Python > Shell > ATELIERS Python + Qt > PyQt apps > PyQt+Arduino | Mes Robots | RepRap | Mes lib'Arduino | Mes shields Arduino | Mes distros | Les Mini-PC |
ATELIERS ARDUINO| VIDEOS | COMPRENDRE | REFERENCES | CODER | TECHNIQUE | GNU/LINUX | LIENS | Rien à voir |

Principe de la convolution en traitement d'image

Principe général

  • La convolution consiste à recalculer la valeur d'un pixel donné d'une image de départ (image Source) en se basant sur la valeur du pixel lui-même et sur la valeur des pixels environnants le pixel à recalculer.
  • Chaque pixel environnant est affecté d'un coefficient de calcul, l'ensemble des coefficients utilisés sont regroupés dans un tableau de valeurs (appelé aussi "matrice"). Ce tableau est appelé le masque.
  • La valeur finale du pixel dans l'image finale (image destination) correspond à un calcul prenant en compte tous les pixels environnants du pixel de départ et le pixel de départ, combinés un à un aux coefficients du masque.

Ressources utiles :

Expression mathématique de la convolution

Mathématiquement, une image peut être considérée comme une fonction discrète (c'est à dire en valeur entières) que l'on pourra noter :

{$ f[x,y] $} où :

  • x et y sont les coordonnées d'un pixel de l'image.
  • f[x,y] correspond à la valeur du pixel, soit en niveau de gris, à une valeur entre 0 et 255.

L'image résultante de la convolution pourra être notée :

{$ f_(new)[x,y]$} où :

  • x et y sont les coordonnées du pixel de l'image
  • f_new_[x,y] correspond à la nouvelle valeur du pixel.

Le masque de convolution est lui-même une fonction discrète que l'on peut appeler h, de [x_1_,x_2_] x [y_1_,y_2_].

La convolution correspondra à :

{$ f_(new)=(f*h)[x,y]= sum_{i=x_1}^{x_2} sum_{j=y_1}^{y_2} h[i,j]*f[x-i,y-j]$}

Autrement dit, on multipliera la valeur de chaque pixel pris en compte par la valeur correspondante du noyau de convolution et on additionnera l'ensemble. La valeur obtenue sera la valeur du pixel final.

Les masques (ou filtres) de convolution utilisés

  • Les valeurs utilisés pour les masques correspondent en fait à une approximation en valeurs entières (on dit également "valeurs discrètes") de la fonction mathématique appliquée à l'image.
  • De nombreux masques sont au format 3x3. Par exemple :

{$ [(1,1,1),(1,1,1),(1,1,1)]$}

  • D'autres masques sont au format 5x5. Par exemple :

{$ [(1,1,1,1,1),(1,1,1,1,1),(1,1,1,1,1),(1,1,1,1,1),(1,1,1,1,1)]$}

  • Plus le masque est grand et plus les calculs à effectuer seront longs. Certaines fonctions sont cependant difficiles à approximer en matrices 3x3 (par exemple la fonction Gaussienne).

Les principaux masques de convolution

Liens utiles :

Bon à savoir : Le logiciel de traitement d'image Gimp permet de tester des masques de convolution simplement. Voir ici : http://docs.gimp.org/fr/plug-in-convmatrix.html

Exemple de code Processing type appliquant un filtre par convolution à une image.


//xxxxxxxxxxxxxxxxxxxx fonction filtre Lapalcien convexité 8 (détection contours) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

PImage filtreLaplacien8 (PImage imgIn) { //------------- début fonction filtre Laplacien convexité 8 -------------------

    PImage imgLaplacien8; // image qui sera renvoyée par la fonction

    imgLaplacien8=imgIn.get(); // crée une image à partir image reçue par la fonction

    imgLaplacien8.loadPixels(); // charge les pixels de l'image en mémoire

    //------------- définition du masque  Laplacien convexité 8 - matrice 3 x 3 -------------  
    //  1  1  1  
    //  1  -8  1
    //  1  1  1

    int LP8[][] = new int[3][3];

    // 3x3  Mask
    LP8[0][0] = 1;
    LP8[0][1] = 1;
    LP8[0][2] = 1;
    LP8[1][0] = 1;
    LP8[1][1] = -8;
    LP8[1][2] = 1;
    LP8[2][0] = 1;
    LP8[2][1] = 1;
    LP8[2][2] = 1;


    //------------- variables de canaux couleurs des pixels ------
    int sumR = 0;
    int sumG = 0;
    int sumB = 0;

   //--------------- passage en revue des pixels de l'image -------------


    for(int y = 0+1; y < imgLaplacien8.height-1; y++) {// ---- défilement des y en excluant la première et dernière ligne
      // car le calcul sobel nécessite 1 pixel autour du pixel calculé

      for(int x = 0+1; x < imgLaplacien8.width-1; x++) { // ---- défilement des x en excluant la première et dernière ligne
      // car le calcul sobel nécessite 1 pixel autour du pixel calculé


        // convolution horizontale

          // Convolve across the X axis and return gradiant aproximation
          //------- parcourt les pixels autour du pixel à évaluer - détection lignes horizontales---
          //---- nombre pixels pris en compte = idem taille matrice

          for(int i = -1; i <= 1; i++) {

            for(int j = -1; j <= 1; j++){

              color col =  imgIn.get(x + i, y + j); // récupère la couleur du pixel à prendre en compte à partir image de départ
              float r = red(col); // récupère le rouge
              float g = green(col); // récupère le vert
              float b = blue(col); // récupère le bleu


              sumR = sumR + (int(r) * LP8[ i + 1][ j + 1]); // applique le masque sur le canal rouge
              sumG = sumG + (int(g) *LP8[ i + 1][ j + 1]); // applique le masque sur le canal vert
              sumB = sumB + (int(b) *LP8[ i + 1][ j + 1]); // applique le masque sur le canal bleu

            } // fin for j

          } // fin for i


             //sumR=abs(sumR);
             //sumG=abs(sumR);
             //sumB=abs(sumR);

             constrain(sumR,0,255);
             constrain(sumG,0,255);
             constrain(sumB,0,255);

          //------ recalcule les pixels ----
          imgLaplacien8.pixels[ x + (y * imgLaplacien8.width) ] = color(sumR, sumG, sumB);

          //--- RAZ des variables ----
          sumR=0;
          sumG=0;
          sumB=0;

        } // fin for x

      } // fin for y


          //img1.updatePixels();  // met à jour les pixels  
          imgLaplacien8.updatePixels();  // met à jour les pixels

          return imgLaplacien8; // renvoie l'image modifiée

    } //---------------- fin filtre Laplacien 8 -----------------