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 |

Processing : Mes fonctions Processing de traitement d'image.

Présentation

  • Sur cette page, je vous propose le code Processing de mes fonctions de traitement d'image. Ce code est utilisable par copier/coller dans votre propre programme.
  • Les fonctions implémentées sont variées, notamment :
    • des fonctions de tracé d'histogramme simple et cumulé d'une image
    • fonctions de gestion des canaux RGB, notamment le mixeur de canaux (idem Gimp)
    • les fonctions de filtres :
      • filtre Gaussien
      • filtre Laplacien
      • filtre de Sobel
  • Ces fonctions combinées ensemble sont utilisées dans mes différents programmes de suivi d'objet ou de reconnaissance visuelle.

Code des fonctions


///////////////////////// FONCTIONS TRAITEMENT IMAGE //////////////////////////
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

//------------ Mémo fonctions disponibles --------------------

        //---- fonction histogramme      
        //imgDest=normalisationHisto(imgDest, 70, 255); // application fonction normalisation histogramme
        //imgDest=egalisationHisto(imgDest); // application fonction égalisation histogramme
        //histogramme(imgDest, xWidth[1], yHeight[2], width/nbColonnes, height/nbLignes); // appelle fonction tracé histogramme
        //histogrammeCumul(imgDest, xWidth[1], yHeight[3], width/nbColonnes, height/nbLignes); // appelle fonction tracé histogramme

        //---- filtres
        //imgDest=filtreLaplacien8(imgDest); // applique filtre Laplacien convexité 8
        //imgDest=filtreGaussien3x3(imgDest); // applique filtre Gaussien 3x3
        //imgDest=filtreGaussien5x5(imgDest); // applique filtre Gaussien 5x5
        //imgDest=filtreSobel(imgDest); // applique filtre sobel et récupère résultat
        //imgDest=filtreSobelInverse(imgDest); // applique filtre sobel et récupère résultat

        //---- opérations sur les images ---
        //imgDest=additionImages(imgDest, imgSource); // additionne les 2 images
        //imgDest=soustractionImages(imgSource, imgDest); // soustrait la 2ème image à la première

        //---- gestion canaux RGB ---
        //imgDest=mixeurCanauxR(imgDest, 1, 2, -3); // application fonction mixeur canaux, sortie canal rouge
        //imgDest=monochromeCanalR(imgDest); // renvoie une image en niveaux de gris basée sur un seul canal


//xxxxxxxxxxxxxxxxxxxxxxx fonction tracé Histogramme RGB d'une image xxxxxxxxxxxxxxxxxxxxxxx
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

void histogramme (PImage imgHisto, int xRef, int yRef, int wRef, int hRef) {

// paramètres à utiliser pour affichage du résultat

  //        int xRef=0; // x coin sup gauche affiche image
  //        int yRef= height/2; // y coin sup droit affiche image

  //        int wRef=width/2; // largeur à utiliser pour affichage
  //        int hRef=height/2; // hauteur à utiliser pour affichage

  //        image( imgSource, xRef, yRef, wRef,hRef);   // affichage image

// on passe en revue les pixels et on détermine le nombre pixels pour chaque valeur

    // variables utiles
    int pas=1;

    int [] histoR = new int [256]; // tableau histogramme du canal Rouge
    int [] histoG = new int [256]; // tableau histogramme du canal Rouge
    int [] histoB = new int [256]; // tableau histogramme du canal Rouge

    //-------------- défilement pixels de l'image ----------    
    for(int x = 0; x <  (imgHisto.width); x=x+pas) { // ---- défilement des x de l'image à traiter

      for(int y = 0; y <  (imgHisto.height); y=y+pas) {// ---- défilement des y de l'image à traiter


        //---- on récupère la valeur du canal rouge du pixel courant et on incrémente la valeur de l'histogramme ayant le même indice
        int indiceR=int(red(imgHisto.pixels[ x + (y *  imgHisto.width) ])); // récupère la valeur du canal rouge
        histoR[indiceR]=histoR[indiceR]+1; // incrémente l'indice correspondant

        //---- on récupère la valeur du canal G du pixel courant et on incrémente la valeur de l'histogramme ayant le même indice
        int indiceG=int(green(imgHisto.pixels[ x + (y *  imgHisto.width) ])); // récupère la valeur du canal vert
        histoG[indiceG]=histoG[indiceG]+1; // incrémente l'indice correspondant


        //---- on récupère la valeur du canal B du pixel courant et on incrémente la valeur de l'histogramme ayant le même indice
        int indiceB=int(blue(imgHisto.pixels[ x + (y *  imgHisto.width) ])); // récupère la valeur du canal bleu
        histoB[indiceB]=histoB[indiceB]+1; // incrémente l'indice correspondant

      } // fin for y      

    } // fin for x


    // tracé de l'histogramme

      //--- coordonnée pour 1er point tracé à x=0 --
      int xTrace0=xRef+int(map(0,0,256,0,wRef)); // xTracé

      int yTraceR0=yRef+hRef-int(map(histoR[0],0,max(histoR),0,hRef)); // yTracé canal rouge
      int yTraceG0=yRef+hRef-int(map(histoG[0],0,max(histoG),0,hRef)); // yTracé canal vert
      int yTraceB0=yRef+hRef-int(map(histoB[0],0,max(histoB),0,hRef)); // yTracé canal bleu

    //for (int x=0; x<256; x++) { // défile les 256 valeurs
    for (int x=1; x<256; x++) { // défile les 256 valeurs-1 pour tracé ligne

      int xTrace=xRef+int(map(x,0,256,0,wRef)); // xTracé

      int yTraceR=yRef+hRef-int(map(histoR[x],0,max(histoR),0,hRef)); // yTracé canal rouge
      int yTraceG=yRef+hRef-int(map(histoG[x],0,max(histoG),0,hRef)); // yTracé canal vert
      int yTraceB=yRef+hRef-int(map(histoB[x],0,max(histoB),0,hRef)); // yTracé canal bleu

      //rect(xTrace,yTrace, 0,0); // trace 1 point

      if ((histoR[x]==histoG[x]) && (histoR[x]==histoB[x])) { // si niveaux de gris => trace 1 courbe

      stroke(255,255,255);
      line(xTrace0, yTraceR0, xTrace,yTraceR);
      }

      else { // trace 3 courbes

      stroke(rouge);
      line(xTrace0, yTraceR0, xTrace,yTraceR);

      stroke(vert);
      line(xTrace0, yTraceG0, xTrace,yTraceG);

      stroke(bleu);
      line(xTrace0, yTraceB0, xTrace,yTraceB);
      }

      //---- réinitialise les x de référence

      xTrace0=xTrace; // mémorise dernier x pour passage suivant

      yTraceR0=yTraceR; // mémorise dernier y pour passage suivant canal rouge
      yTraceG0=yTraceG; // mémorise dernier y pour passage suivant canal vert
      yTraceB0=yTraceB; // mémorise dernier y pour passage suivant canal bleu

    }

} // xxxxxxxxxxxxxxxx fin de la fonction histogramme


// xxxxxxxxxxxxxxxx fonction tracé histogramme cumulé d'une image ==============
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL


void histogrammeCumul (PImage imgHisto, int xRef, int yRef, int wRef, int hRef) {

//HC(x)  est  le  taux  de  pixels  dont  le  niveau  de  gris  est inférieur  à x

// paramètres à utiliser pour affichage du résultat

  //        int xRef=0; // x coin sup gauche affiche image
  //        int yRef= height/2; // y coin sup droit affiche image

  //        int wRef=width/2; // largeur à utiliser pour affichage
  //        int hRef=height/2; // hauteur à utiliser pour affichage

  //        image( imgSource, xRef, yRef, wRef,hRef);   // affichage image

// on passe en revue les pixels et on détermine le nombre pixels pour chaque valeur

    // variables utiles
    int pas=1;

    int [] histoR = new int [256]; // tableau histogramme du canal Rouge
    int [] histoG = new int [256]; // tableau histogramme du canal Rouge
    int [] histoB = new int [256]; // tableau histogramme du canal Rouge

    //----------- variable pour cumul --------------------
    int histoCumulR=0;
    int histoCumulG=0;
    int histoCumulB=0;

    //-------------- défilement pixels de l'image ----------
    for(int x = 0; x <  (imgHisto.width); x=x+pas) { // ---- défilement des x de l'image à traiter

      for(int y = 0; y <  (imgHisto.height); y=y+pas) {// ---- défilement des y de l'image à traiter


        //---- on récupère la valeur du canal rouge du pixel courant et on incrémente la valeur de l'histogramme ayant le même indice
        int indiceR=int(red(imgHisto.pixels[ x + (y *  imgHisto.width) ])); // récupère la valeur du canal rouge
        histoR[indiceR]=histoR[indiceR]+1; // incrémente l'indice correspondant

        //---- on récupère la valeur du canal G du pixel courant et on incrémente la valeur de l'histogramme ayant le même indice
        int indiceG=int(green(imgHisto.pixels[ x + (y *  imgHisto.width) ])); // récupère la valeur du canal vert
        histoG[indiceG]=histoG[indiceG]+1; // incrémente l'indice correspondant


        //---- on récupère la valeur du canal B du pixel courant et on incrémente la valeur de l'histogramme ayant le même indice
        int indiceB=int(blue(imgHisto.pixels[ x + (y *  imgHisto.width) ])); // récupère la valeur du canal bleu
        histoB[indiceB]=histoB[indiceB]+1; // incrémente l'indice correspondant

      } // fin for y      

    } // fin for x

    //-------- calcul de l'histogramme cumulé ---------------

    for (int i=0; i<256; i++) { // défile les 255 niveaux de couleur

        //-------- canal rouge ------
        histoCumulR=histoCumulR+histoR[i]; // calcul du cumul
        histoR[i]=histoCumulR; // modif valeur histo avec valeur cumulée
        histoR[i]=1000*histoR[i]/(imgHisto.width*imgHisto.height);


        //-------- canal vert ------
        histoCumulG=histoCumulG+histoG[i]; // calcul du cumul
        histoG[i]=histoCumulG; // modif valeur histo avec valeur cumulée
        histoG[i]=1000*histoG[i]/(imgHisto.width*imgHisto.height);


        //-------- canal bleu ------
        histoCumulB=histoCumulB+histoB[i]; // calcul du cumul
        histoB[i]=histoCumulB; // modif valeur histo avec valeur cumulée
        histoB[i]=1000*histoB[i]/(imgHisto.width*imgHisto.height);


    }    


    // tracé de l'histogramme

      //--- coordonnée pour 1er point tracé à x=0 --
      int xTrace0=xRef+int(map(0,0,256,0,wRef)); // xTracé

      int yTraceR0=yRef+hRef-int(map(histoR[0],0,max(histoR),0,hRef)); // yTracé canal rouge
      int yTraceG0=yRef+hRef-int(map(histoG[0],0,max(histoG),0,hRef)); // yTracé canal vert
      int yTraceB0=yRef+hRef-int(map(histoB[0],0,max(histoB),0,hRef)); // yTracé canal bleu

    //for (int x=0; x<256; x++) { // défile les 256 valeurs
    for (int x=1; x<256; x++) { // défile les 256 valeurs-1 pour tracé ligne

      int xTrace=xRef+int(map(x,0,256,0,wRef)); // xTracé

      int yTraceR=yRef+hRef-int(map(histoR[x],0,max(histoR),0,hRef)); // yTracé canal rouge
      int yTraceG=yRef+hRef-int(map(histoG[x],0,max(histoG),0,hRef)); // yTracé canal vert
      int yTraceB=yRef+hRef-int(map(histoB[x],0,max(histoB),0,hRef)); // yTracé canal bleu

      //rect(xTrace,yTrace, 0,0); // trace 1 point

      if ((histoR[x]==histoG[x]) && (histoR[x]==histoB[x])) { // si niveaux de gris => trace 1 courbe

      stroke(255,255,255);
      line(xTrace0, yTraceR0, xTrace,yTraceR);
      }

      else { // trace 3 courbes

      stroke(rouge);
      line(xTrace0, yTraceR0, xTrace,yTraceR);

      stroke(vert);
      line(xTrace0, yTraceG0, xTrace,yTraceG);

      stroke(bleu);
      line(xTrace0, yTraceB0, xTrace,yTraceB);
      }

      //---- réinitialise les x de référence

      xTrace0=xTrace; // mémorise dernier x pour passage suivant

      yTraceR0=yTraceR; // mémorise dernier y pour passage suivant canal rouge
      yTraceG0=yTraceG; // mémorise dernier y pour passage suivant canal vert
      yTraceB0=yTraceB; // mémorise dernier y pour passage suivant canal bleu

    }

} // fin de la fonction histogramme Cumul

//xxxxxxxxxxxxxxxxxxxxxx fonction calcul ET tracé égalisation histogramme xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

PImage egalisationHisto (PImage imgIn) {

//HC(x)  est  le  taux  de  pixels  dont  le  niveau  de  gris  est inférieur  à x
// formule égalisation f nouv[x,y]= (255) * HC (f[x,y]) / w*h)

    PImage imgEgalHisto;

    imgEgalHisto=imgIn.get(); // crée une copie de l'image reçue

// on passe en revue les pixels et on détermine le nombre pixels pour chaque valeur

    // variables utiles
    int pas=1;

    float [] histoR = new float [256]; // tableau histogramme du canal Rouge
    float [] histoG = new float [256]; // tableau histogramme du canal Rouge
    float [] histoB = new float [256]; // tableau histogramme du canal Rouge

    //----------- variable pour cumul --------------------
    int histoCumulR=0;
    int histoCumulG=0;
    int histoCumulB=0;

    //-------------- défilement pixels de l'image ----------
    for(int x = 0; x <  (imgEgalHisto.width); x=x+pas) { // ---- défilement des x de l'image à traiter

      for(int y = 0; y <  (imgEgalHisto.height); y=y+pas) {// ---- défilement des y de l'image à traiter


        //---- on récupère la valeur du canal rouge du pixel courant et on incrémente la valeur de l'histogramme ayant le même indice
        int indiceR=int(red(imgEgalHisto.pixels[ x + (y *  imgEgalHisto.width) ])); // récupère la valeur du canal rouge
        histoR[indiceR]=histoR[indiceR]+1; // incrémente l'indice correspondant

        //---- on récupère la valeur du canal G du pixel courant et on incrémente la valeur de l'histogramme ayant le même indice
        int indiceG=int(green(imgEgalHisto.pixels[ x + (y *  imgEgalHisto.width) ])); // récupère la valeur du canal vert
        histoG[indiceG]=histoG[indiceG]+1; // incrémente l'indice correspondant


        //---- on récupère la valeur du canal B du pixel courant et on incrémente la valeur de l'histogramme ayant le même indice
        int indiceB=int(blue(imgEgalHisto.pixels[ x + (y *  imgEgalHisto.width) ])); // récupère la valeur du canal bleu
        histoB[indiceB]=histoB[indiceB]+1; // incrémente l'indice correspondant

      } // fin for y      

    } // fin for x

    //-------- calcul de l'histogramme cumulé ---------------

    for (int i=0; i<256; i++) { // défile les 255 niveaux de couleur

        //-------- canal rouge ------
        histoCumulR=histoCumulR+int(histoR[i]); // calcul du cumul
        histoR[i]=histoCumulR; // modif valeur histo avec valeur cumulée
        //histoR[i]=histoR[i]/(imgEgalHisto.width*imgEgalHisto.height);

        //-------- canal vert ------
        histoCumulG=histoCumulG+int(histoG[i]); // calcul du cumul
        histoG[i]=histoCumulG; // modif valeur histo avec valeur cumulée
        //histoG[i]=histoG[i]/(imgEgalHisto.width*imgEgalHisto.height);

        //-------- canal bleu ------
        histoCumulB=histoCumulB+int(histoB[i]); // calcul du cumul
        histoB[i]=histoCumulB; // modif valeur histo avec valeur cumulée
        //histoB[i]=histoB[i]/(imgEgalHisto.width*imgEgalHisto.height);

    }    


    // ---- calcul de la nouvelle image ----

    //---- défilement des pixels ----

for(int x = 0; x <  (imgEgalHisto.width); x=x+1) { // ---- défilement des x de l'image à traiter

      for(int y = 0; y <  (imgEgalHisto.height); y=y+1) {// ---- défilement des y de l'image à traiter

            int i= x + (y *  imgEgalHisto.width); // indice pixel

            float r = 255 *histoR[int(red(imgEgalHisto.pixels[i]))]/(imgEgalHisto.width*imgEgalHisto.height);// la couleur rouge

            float g = 255  *histoG[int(green(imgEgalHisto.pixels[i ]))]/(imgEgalHisto.width*imgEgalHisto.height); // la couleur verte

            float b = 255  *histoB[int(blue(imgEgalHisto.pixels[ i]))]/(imgEgalHisto.width*imgEgalHisto.height); // la couleur bleue

        imgEgalHisto.pixels[ x + (y *  imgEgalHisto.width)] = color(r, g, b); // modifie le pixel en fonction

      } // fin for y      

    } // fin for x


   return (imgEgalHisto); // renvoi image modifiée


} // fin de la fonction histogramme Cumul



//xxxxxxxxxxxxxxxxxxxxxxxxx fin égalisation histogramme xxxxxxxxxxxxxxxxxxxxxxxxxx

//xxxxxxxxxxxxxxxxxxxxxx fonction de calcul ET tracé de normalisation de l'histogramme RGB xxxxxxxxxxxxx
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

PImage normalisationHisto( PImage imgIn, int Nmin, int Nmax) {

//------------- normalisation histogramme de l'image -------------
    // formule imgDest(x,y)=(imgSource(x,y)-Nmin)*(255/(Nmax-NMin))    

    //int Nmin=70;
    //int Nmax=255;

    PImage imgNormHisto;

    imgNormHisto=imgIn.get(); // crée une copie image reçue

    for(int x = 0; x <  (imgNormHisto.width); x=x+1) { // ---- défilement des x de l'image à traiter

      for(int y = 0; y <  (imgNormHisto.height); y=y+1) {// ---- défilement des y de l'image à traiter

            int i= x + (y *  imgNormHisto.width) ; // index du pixel courant

            float r = (red(imgNormHisto.pixels[i])-Nmin)*(255/(Nmax-Nmin));// la couleur rouge

            float g = (green(imgNormHisto.pixels[i])-Nmin)*(255/(Nmax-Nmin)); // la couleur verte

            float b = (blue(imgNormHisto.pixels[i])-Nmin)*(255/(Nmax-Nmin)); // la couleur bleue

        imgNormHisto.pixels[ x + (y *  imgNormHisto.width)] = color(r, g, b); // modifie le pixel en fonction

      } // fin for y      

    } // fin for x

    return(imgNormHisto); // renvoi image modifiée

} //--------------------- fin normalisation histogramme -------


//xxxxxxxxxxxxxx fonction mixeurs de canaux xxxxxxxxxxxxxxxxxxxxxxxxxxx
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL
// d'après le mixeur de canaux de The Gimp

//---------------- fonction mixeur de canaux sortie sur canal rouge ------
PImage mixeurCanauxR (PImage imgIn, float coefRouge, float coefVert, float coefBleu) {  // l'image source n'est pas modifiée

            //---- coeff à appliquer
            //float coefRouge=1; // 100% de rouge
            //float coefVert=1.5; // 80% du vert
            //float coefBleu=-2; // - 200% du bleu

          PImage imgMix;

          imgMix=imgIn.get(); // crée une copie de l'image reçue en réception

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

          for (int i = 0; i < imgMix.width*imgMix.height; i++) { // passe en revue les pixels de l'image - index 0 en premier

            float r = (red(imgMix.pixels[i])) + (green(imgMix.pixels[i])*coefVert) + (blue(imgMix.pixels[i])*coefBleu); // la couleur rouge
            //---- fonction mixeur de canaux
            //---- le canal rouge est le canal de sortie et a pour coeff 1
            //---- auquel on ajoute du vert avec coeff vert
            //---- et du bleu avec coeff bleu

            // les deux autres canaux restent inchangés
            float g = green(imgMix.pixels[i]); // la couleur verte
             //float g = green(pixels[i])*2; // la couleur verte

            float b = blue(imgMix.pixels[i]); // la couleur bleue
            //float b = blue(pixels[i])*2; // la couleur bleue

             imgMix.pixels[i] = color(r, g, b); // modifie le pixel en fonction

            }

          imgMix.updatePixels();  // met à jour les pixels de l'image  

          return (imgMix); // renvoie l'image modifiée

} //------fin  fonction mixeur de canaux sortie sur canal rouge ------

//xxxxxxxxxxxxxxxxxxxx fonction filtre SOBEL (détection contours) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL
// dérivé de : sobel edge from http://www.openprocessing.org

PImage filtreSobel (PImage imgIn) { //------------- début fonction filtre sobel -------------------

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

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

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

    //------------- définition du masque x - matrice 3 x 3 -------------  
    //  -1  0  1  
    //  -2  0  2
    //  -1  0  1

    int GX[][] = new int[3][3];

    // 3x3 Sobel Mask for X
    GX[0][0] = -1;
    GX[0][1] = 0;
    GX[0][2] = 1;
    GX[1][0] = -2;
    GX[1][1] = 0;
    GX[1][2] = 2;
    GX[2][0] = -1;
    GX[2][1] = 0;
    GX[2][2] = 1;

    //------------------ définition du masque y - matrice 3 x 3 -------------------
    //  1  2  1
    //  0  0  0
    //  -1  -2  -1

    int GY[][] = new int[3][3];

    // 3x3 Sobel Mask for Y
    GY[0][0] =  1;
    GY[0][1] =  2;
    GY[0][2] =  1;
    GY[1][0] =  0;
    GY[1][1] =  0;
    GY[1][2] =  0;
    GY[2][0] = -1;
    GY[2][1] = -2;
    GY[2][2] = -1;

    //------------- variables de canaux couleurs des pixels ------
    int sumRx = 0;
    int sumGx = 0;
    int sumBx = 0;

    int sumRy = 0;
    int sumGy = 0;
    int sumBy = 0;

    int finalSumR = 0;
    int finalSumG = 0;
    int finalSumB = 0;


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


    for(int y = 0+1; y < imgSobel.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 < imgSobel.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


              sumRx += r * GX[ i + 1][ j + 1]; // applique le masque sur le canal rouge
              sumGx += g * GX[ i + 1][ j + 1]; // applique le masque sur le canal vert
              sumBx += b * GX[ i + 1][ j + 1]; // applique le masque sur le canal bleu

            } // fin for j

          } // fin for i



          // convolution verticale

          //------- parcourt les pixels autour du pixel à évaluer - détection lignes verticales ---
          //---- 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
              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


              sumRy += r * GY[ i + 1][ j + 1]; // applique le masque sur le canal rouge
              sumGy += g * GY[ i + 1][ j + 1]; // applique le masque sur le canal vert
              sumBy += b * GY[ i + 1][ j + 1]; // applique le masque sur le canal bleu

            } // fin for j

          } // fin for i

          //------------ valeur finale canaux couleurs ---
          finalSumR = abs(sumRx) + abs(sumRy);
          finalSumG = abs(sumGx) + abs(sumGy);
          finalSumB = abs(sumBx) + abs(sumBy);

/*
          // I only want to return a black or a white value, here I determine the greyscale value,
          // and if it is above a tolerance, then set the colour to white

          float gray = (finalSumR + finalSumG + finalSumB) / 3;
          float tolerance=90;

          if(gray > tolerance)
          {
            finalSumR = 0;
            finalSumG = 0;
            finalSumB = 0;
          }
          else
          {
            finalSumR = 255;
            finalSumG = 255;
            finalSumB = 255;
          }

*/


          //------ recalcule les pixels ----
          imgSobel.pixels[ x + (y * imgSobel.width) ] = color(finalSumR, finalSumG, finalSumB);

          //--- RAZ des variables ----
          sumRx=0;
          sumGx=0;
          sumBx=0;
          sumRy=0;
          sumGy=0;
          sumBy=0;

        } // fin for x

      } // fin for y


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

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

    } //---------------- fin filtre sobel -----------------

//xxxxxxxxxxxxxxxxxxxx fonction filtre SOBEL (détection contours) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL
// dérivé de : sobel edge from http://www.openprocessing.org

PImage filtreSobelInverse (PImage imgIn) { //------------- début fonction filtre sobel inversé -------------------

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

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

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

    //------------- définition du masque x - matrice 3 x 3 -------------  
    //  -1  0  1  
    //  -2  0  2
    //  -1  0  1

    int GX[][] = new int[3][3];

    // 3x3 Sobel Mask for X
    GX[0][0] = -1;
    GX[0][1] = 0;
    GX[0][2] = 1;
    GX[1][0] = -2;
    GX[1][1] = 0;
    GX[1][2] = 2;
    GX[2][0] = -1;
    GX[2][1] = 0;
    GX[2][2] = 1;

    //------------------ définition du masque y - matrice 3 x 3 -------------------
    //  1  2  1
    //  0  0  0
    //  -1  -2  -1

    int GY[][] = new int[3][3];

    // 3x3 Sobel Mask for Y
    GY[0][0] =  1;
    GY[0][1] =  2;
    GY[0][2] =  1;
    GY[1][0] =  0;
    GY[1][1] =  0;
    GY[1][2] =  0;
    GY[2][0] = -1;
    GY[2][1] = -2;
    GY[2][2] = -1;

    //------------- variables de canaux couleurs des pixels ------
    int sumRx = 0;
    int sumGx = 0;
    int sumBx = 0;

    int sumRy = 0;
    int sumGy = 0;
    int sumBy = 0;

    int finalSumR = 0;
    int finalSumG = 0;
    int finalSumB = 0;


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


    for(int y = 0+1; y < imgSobel.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 < imgSobel.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


              sumRx += r * GX[ i + 1][ j + 1]; // applique le masque sur le canal rouge
              sumGx += g * GX[ i + 1][ j + 1]; // applique le masque sur le canal vert
              sumBx += b * GX[ i + 1][ j + 1]; // applique le masque sur le canal bleu

            } // fin for j

          } // fin for i



          // convolution verticale

          //------- parcourt les pixels autour du pixel à évaluer - détection lignes verticales ---
          //---- 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
              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


              sumRy += r * GY[ i + 1][ j + 1]; // applique le masque sur le canal rouge
              sumGy += g * GY[ i + 1][ j + 1]; // applique le masque sur le canal vert
              sumBy += b * GY[ i + 1][ j + 1]; // applique le masque sur le canal bleu

            } // fin for j

          } // fin for i

          //------------ valeur finale canaux couleurs ---
          finalSumR = 255-(abs(sumRx) + abs(sumRy));
          finalSumG = 255-(abs(sumGx) + abs(sumGy));
          finalSumB = 255-(abs(sumBx) + abs(sumBy));

/*
          // I only want to return a black or a white value, here I determine the greyscale value,
          // and if it is above a tolerance, then set the colour to white

          float gray = (finalSumR + finalSumG + finalSumB) / 3;
          float tolerance=90;

          if(gray > tolerance)
          {
            finalSumR = 0;
            finalSumG = 0;
            finalSumB = 0;
          }
          else
          {
            finalSumR = 255;
            finalSumG = 255;
            finalSumB = 255;
          }

*/


          //------ recalcule les pixels ----
          imgSobel.pixels[ x + (y * imgSobel.width) ] = color(finalSumR, finalSumG, finalSumB);

          //--- RAZ des variables ----
          sumRx=0;
          sumGx=0;
          sumBx=0;
          sumRy=0;
          sumGy=0;
          sumBy=0;

        } // fin for x

      } // fin for y


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

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

    } //---------------- fin filtre sobel Inversé -----------------

//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 -----------------

//xxxxxxxxxxxxxxxxxxxx fonction filtre Gaussien 3x3 - diminution bruit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

PImage filtreGaussien3x3 (PImage imgIn) { //------------- début fonction filtre Gaussien 3x3 -------------------

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

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

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

    //------------- définition du masque  filtre Gaussien - matrice 3 x 3 -------------  
    //          
    //          | 1  2  1 |    
    //  1/16 x  | 2  4  2 |
    //          | 1  2  1 |
    //
    // ce masque est une approximation discrète simplifiée de la fonction Gaussienne 2D
    // pour sigma = 0.8    

    int Masque[][] = new int[3][3];

    // 3x3  Mask
    Masque[0][0] = 1;
    Masque[0][1] = 2;
    Masque[0][2] = 1;
    Masque[1][0] = 2;
    Masque[1][1] = 4;
    Masque[1][2] = 2;
    Masque[2][0] = 1;
    Masque[2][1] = 2;
    Masque[2][2] = 1;

    int coeffMasque=16; //

    //------------- 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 < imgOut.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 < imgOut.width-1; x++) { // ---- défilement des x en excluant la première et dernière ligne
      // car le calcul nécessite 1 pixel autour du pixel calculé


          //---- parcourt les pixels autour 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) * Masque[ i + 1][ j + 1]/coeffMasque); // applique le masque sur le canal rouge
              sumG = sumG + (int(g) *Masque[ i + 1][ j + 1]/coeffMasque); // applique le masque sur le canal vert
              sumB = sumB + (int(b) *Masque[ i + 1][ j + 1]/coeffMasque); // applique le masque sur le canal bleu

            } // fin for j

          } // fin for i


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

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

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

        } // fin for x

      } // fin for y

          imgOut.updatePixels();  // met à jour les pixels

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

    } //---------------- fin filtre Gaussien 3x3 -----------------

//xxxxxxxxxxxxxxxxxxxx fonction filtre Gaussien 5x5 - diminution bruit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

PImage filtreGaussien5x5 (PImage imgIn) { //------------- début fonction filtre Gaussien 3x3 -------------------

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

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

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

    //------------- définition du masque  filtre Gaussien - matrice 3 x 3 -------------  
    //          
    //            | 1    7    16   7    1 |    
    //            | 7    75  164  75    7 |    
    //  1/1444 x  | 16  164  359  164  16 |
    //            | 7    75  164  75    7|
    //            | 1    7    16   7    1 |    
    //
    // ce masque est une approximation discrète simplifiée de la fonction Gaussienne 2D
    // pour sigma = 0.8    

    int Masque[][] = new int[5][5];

    // 5x5  Mask
    Masque[0][0] = 1;
    Masque[0][1] = 7;
    Masque[0][2] = 16;
    Masque[0][3] = 7;
    Masque[0][4] = 1;

    Masque[1][0] = 7;
    Masque[1][1] = 75;
    Masque[1][2] = 164;
    Masque[1][3] = 75;
    Masque[1][4] = 7;

    Masque[2][0] = 16;
    Masque[2][1] = 164;
    Masque[2][2] = 359;
    Masque[2][3] = 164;
    Masque[2][4] = 16;

    Masque[3][0] = 7;
    Masque[3][1] = 75;
    Masque[3][2] = 164;
    Masque[3][3] = 75;
    Masque[3][4] = 7;

    Masque[4][0] = 1;
    Masque[4][1] = 7;
    Masque[4][2] = 16;
    Masque[4][3] = 7;
    Masque[4][4] = 1;

    int coeffMasque=1444; //

    //------------- 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 < imgOut.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 < imgOut.width-1; x++) { // ---- défilement des x en excluant la première et dernière ligne
      // car le calcul nécessite 1 pixel autour du pixel calculé


          //---- parcourt les pixels autour pris en compte = idem taille matrice

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

            for(int j = -2; j <= 2; 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) * Masque[ i + 2][ j + 2]/coeffMasque); // applique le masque sur le canal rouge
              sumG = sumG + (int(g) *Masque[ i + 2][ j + 2]/coeffMasque); // applique le masque sur le canal vert
              sumB = sumB + (int(b) *Masque[ i + 2][ j + 2]/coeffMasque); // applique le masque sur le canal bleu

            } // fin for j

          } // fin for i


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

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

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

        } // fin for x

      } // fin for y

          imgOut.updatePixels();  // met à jour les pixels

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

    } //---------------- fin filtre Gaussien 5x5 -----------------

//xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fonctions extraction canal couleur xxxxxxxxxxxxxxxxxxxxxxxx


//----- fonction extraction du canal bleu (met à 0 le rouge et le vert ---
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL
PImage extractionCanalB(PImage imgIn) {

  PImage imgCanalB;

  imgCanalB=imgIn.get(); // copie de l'image reçue

for(int x = 0; x <  (imgCanalB.width); x=x+1) { // ---- défilement des x de l'image à traiter

      for(int y = 0; y <  (imgCanalB.height); y=y+1) {// ---- défilement des y de l'image à traiter

            float r = 0;// la couleur rouge

            float g = 0; // la couleur verte

            float b = blue(imgCanalB.pixels[ x + (y *  imgCanalB.width) ]); // la couleur bleue

        imgCanalB.pixels[ x + (y *  imgCanalB.width)] = color(r, g, b); // modifie le pixel en fonction

      } // fin for y      

    } // fin for x

    return (imgCanalB); // renvoi image modifiée


} // fin fonction extraction du canal bleu (met à 0 le rouge et le vert ---


//----- extraction du canal vert (met à 0 le rouge et le bleu ) ---
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

PImage extractionCanalV(PImage imgIn) {

  PImage imgCanalV;

  imgCanalV=imgIn.get(); // copie de l'image reçue

for(int x = 0; x <  (imgCanalV.width); x=x+1) { // ---- défilement des x de l'image à traiter

      for(int y = 0; y <  (imgCanalV.height); y=y+1) {// ---- défilement des y de l'image à traiter

            float r = 0;// la couleur rouge

            float g = green(imgCanalV.pixels[ x + (y *  imgCanalV.width) ]); // la couleur verte

            float b = 0; // la couleur bleue

        imgCanalV.pixels[ x + (y *  imgCanalV.width)] = color(r, g, b); // modifie le pixel en fonction

      } // fin for y      

    } // fin for x

        return (imgCanalV); // renvoi image modifiée

}//-- fin extraction du canal vert (met à 0 le rouge et le bleu ---


//----- fonction extraction du canal rouge (met à 0 le vert et le bleu ---
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

PImage extractionCanalR(PImage imgIn) {

  PImage imgCanalR;

  imgCanalR=imgIn.get(); // copie de l'image reçue

for(int x = 0; x <  (imgCanalR.width); x=x+1) { // ---- défilement des x de l'image à traiter

      for(int y = 0; y <  (imgCanalR.height); y=y+1) {// ---- défilement des y de l'image à traiter

            float r = red(imgCanalR.pixels[ x + (y *  imgCanalR.width) ]);// la couleur rouge

            float g = 0; // la couleur verte

            float b = 0; // la couleur bleue

        imgCanalR.pixels[ x + (y *  imgCanalR.width)] = color(r, g, b); // modifie le pixel en fonction

      } // fin for y      

    } // fin for x

        return (imgCanalR); // renvoi image modifiée

} // //--- fin fonction extraction du canal rouge (met à 0 le vert et le bleu ---

//----- fonction monochrome à partie du  canal rouge (met à 0 le vert et le bleu ) ---
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

PImage monochromeCanalR(PImage imgIn) {

  PImage imgCanalR;

  imgCanalR=imgIn.get(); // copie de l'image reçue

for(int x = 0; x <  (imgCanalR.width); x=x+1) { // ---- défilement des x de l'image à traiter

      for(int y = 0; y <  (imgCanalR.height); y=y+1) {// ---- défilement des y de l'image à traiter

            float r = red(imgCanalR.pixels[ x + (y *  imgCanalR.width) ]);// la couleur rouge

            float g = red(imgCanalR.pixels[ x + (y *  imgCanalR.width) ]); // la couleur verte = rouge

            float b = red(imgCanalR.pixels[ x + (y *  imgCanalR.width) ]); // la couleur bleue = rouge

        imgCanalR.pixels[ x + (y *  imgCanalR.width)] = color(r, g, b); // modifie le pixel en fonction  = image niveau de gris basée sur canal rouge

      } // fin for y      

    } // fin for x

        return (imgCanalR); // renvoi image modifiée

} // //--- fin fonction monochrome basé sur canal rouge ---

//----- fonction addition de 2 images ---
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

PImage additionImages(PImage imgIn1, PImage imgIn2) {

  PImage imgOut;

  imgOut=imgIn1.get(); // copie de l'image 1 reçue

for(int x = 0; x <  (imgOut.width); x=x+1) { // ---- défilement des x de l'image à traiter

      for(int y = 0; y <  (imgOut.height); y=y+1) {// ---- défilement des y de l'image à traiter

            float r = red(imgIn1.pixels[ x + (y *  imgIn1.width) ])+red(imgIn2.pixels[ x + (y *  imgIn2.width) ]);// la couleur rouge

            float g = green(imgIn1.pixels[ x + (y *  imgIn1.width) ])+green(imgIn2.pixels[ x + (y *  imgIn2.width) ]); // la couleur verte

            float b = blue(imgIn1.pixels[ x + (y *  imgIn1.width) ])+blue(imgIn2.pixels[ x + (y *  imgIn2.width) ]); // la couleur bleue

        // oblige valeurs entre 0 et 255    
        constrain (r,0,255);
        constrain (g,0,255);
        constrain (b,0,255);      

        imgOut.pixels[ x + (y *  imgOut.width)] = color(r, g, b); // modifie le pixel en fonction  = image niveau de gris basée sur canal rouge

      } // fin for y      

    } // fin for x

        return (imgOut); // renvoi image modifiée

} // //--- fin addition de 2 images ---

//----- fonction soustraction de 2 images ---
// www.mon-club-elec.fr - Par X.HINAULT - Tous droits réservés - Mai 2011 - Licence GPL

PImage soustractionImages(PImage imgIn1, PImage imgIn2) {

  PImage imgOut;

  imgOut=imgIn1.get(); // copie de l'image 1 reçue

for(int x = 0; x <  (imgOut.width); x=x+1) { // ---- défilement des x de l'image à traiter

      for(int y = 0; y <  (imgOut.height); y=y+1) {// ---- défilement des y de l'image à traiter

            float r = red(imgIn1.pixels[ x + (y *  imgIn1.width) ])-red(imgIn2.pixels[ x + (y *  imgIn2.width) ]);// la couleur rouge

            float g = green(imgIn1.pixels[ x + (y *  imgIn1.width) ])-green(imgIn2.pixels[ x + (y *  imgIn2.width) ]); // la couleur verte

            float b = blue(imgIn1.pixels[ x + (y *  imgIn1.width) ])-blue(imgIn2.pixels[ x + (y *  imgIn2.width) ]); // la couleur bleue

        // oblige valeurs entre 0 et 255    
        constrain (r,0,255);
        constrain (g,0,255);
        constrain (b,0,255);      

        imgOut.pixels[ x + (y *  imgOut.width)] = color(r, g, b); // modifie le pixel en fonction  = image niveau de gris basée sur canal rouge

      } // fin for y      

    } // fin for x

        return (imgOut); // renvoi image modifiée

} // //--- fin soustraction de 2 images ---

//int [] distributionX(PImage imgIn, int seuil, int xRef, int yRef, int wRef, int hRef) {

  void distributionX(PImage imgIn, int seuil, int xRef, int yRef, int wRef, int hRef) {
// debut fonction de calcul ET tracé de la distribution des pixels sup à valeur seuil par colonne de l'image

// pour chaque x, on compte le nombre de point  

    // variables utiles
    int pas=1;
    int [] comptX = new int [imgIn.width]; // tableau comptage des x

    for(int x = 0+1; x <  (imgIn.width-1); x=x+pas) { // ---- défilement des x de l'image à traiter - prend pas en compte premier pixel

      for(int y = 0+1; y <  (imgIn.height-1); y=y+pas) {// ---- défilement des y de l'image à traiter - prend pas en compte premier pixel


        //------------ quadrillage sur l'image dans le plan x,y = tous les points pour lesquels une droite sera tracée dans l'espace de haugh
        //rect((width/2)+x,(height/2)-y,0,0); // affiche le quadrillage utilisé pour l'image de départ - rect avec width=0 et height=0 pour avoir un point

        //------- comptage des points "positif" dans les x------------

        if (imgDest.pixels[ x + (y *  imgDest.width) ]>color(seuil,seuil,seuil)) { // si le pixel est à prendre en compte - contour en blanc
        //if (imgIn.pixels[ x + (y *  imgIn.width) ]<color(seuil,seuil,seuil)) { // si le pixel est à prendre en compte - contour en noir

          comptX[x]=comptX[x]+1; // incrémente le nombre de point dans la colonne


        } // fin if color

      } // fin for y

      } // for x

     //----------- tracé de la distribution des X -------------

    for(int x = 0+1; x <  (imgIn.width-1); x=x+pas) { // ---- défilement des x de l'image - prend pas en compte 1er et dernier au cas où filtre avant

        int xTrace=xRef+int(map(x,0,imgIn.width,0,wRef)); // xTracé

        int yTrace=yRef+hRef-int(map(comptX[x],0,imgIn.height,0,hRef)); // yTracé

        //rect(xTrace,yTrace, 0,0); // trace 1 point

        stroke (rouge); // couleur pourtour RGB      
        line(xTrace, height-hRef+imgIn.height, xTrace,height-hRef+yTrace); // trace ligne verticale correspondante

      //line (x*320/imgDest.width,height, x*320/imgDest.width, height-(comptX[x]*240/imgDest.height)); // affiche le nombre de point détecté sous forme graphique


    } // fin for x


  //return  comptX; // renvoie le tableau  

} // fin fonction distributionX