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 |

Outils > Processing

Processing – Traitement d'image : Tracé de l'histogramme cumulé d'une image

Par X. HINAULT. 11 Mai 2011

Explication

  • L'histogramme cumulé d'une image est le calcul du taux (=pourcentage) de pixels ayant une valeur inférieure à un niveau de couleur donné, pour chaque niveau de couleur (ou de gris) d'une image, et ce pour chaque canal Rouge Vert Bleu de l'image.
  • Un tel histogramme permet d'avoir une idée graphique de l'équilibre de la répartition de l'utilisation des niveaux de couleur et de voir notamment si la pleine échelle des niveaux de couleur est utilisée.
  • Il sera possible dans un second de linéariser cet histogramme cumulé pour améliorer le contraste par exemple.

Ressources utiles

Mathématiquement :

  • D'un point de vue mathématique, l'histogramme cumulé correspond à une fonction que l'on peut noter HC(x) telle que :

où :

  • H(x) est la fonction histogramme simple
  • w et h sont respectivement la largeur et la hauteur de l'image en nombre de pixels

Explication de la fonction de tracé d'histogramme

  • Définition de la fonction : void histogramme (PImage imgHisto, int xRef, int yRef, int wRef, int hRef)
  • Cette fonction reçoit les paramètres suivants :
    • int xRef : x coin sup gauche affichage histogramme
    • int yRef : y coin sup gauche affichage histogramme
    • int wRef : largeur en pixel à utiliser pour affichage histogramme
    • int hRef : hauteur en pixel à utiliser pour affichage histogramme
  • Cette fonction trace les 3 courbes d'histogramme cumulé des canaux RVB :

Mon code de fonction traçant l'histogramme d'une image

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

Voir également : Mes fonctions Processing de traitement d'image