Le traitement d’image est une discipline qui s’intéresse à la manipulation et à l’analyse des images numériques. L’un des outils les plus puissants à la disposition des chercheurs et des professionnels est le logiciel de traitement d’image Processing. Ce logiciel permet de réaliser des opérations complexes sur des images numériques, notamment le tracé de l’histogramme cumulé d’une image. Dans cet article, nous allons examiner en détail le processus de tracé de l’histogramme cumulé d’une image avec 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
// 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
Articles similaires:
- Processing Traitement d’image : Tracé de l’histogramme d’une image
- Processing : Mes fonctions Processing de traitement d’image.
- http://web.archive.org/web/20210804223007/http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.OutilsProcessingImage
- Processing Traitement d’image : Filtre Sobel 2D (détection de contours)
- Processing Traitement d’image : Filtre Gaussien (flou, atténuation du bruit)
Articles Liés
- Processing Traitement d'image : Tracé de l'histogramme d'une image
Le traitement d'image est une discipline qui s'intéresse à la manipulation et à l'analyse des…
- Javascript : Graphique Dygraphs simple
Le Javascript est un langage de programmation très populaire et puissant qui permet aux développeurs…
- Javascript : Afficher 6 widgets graphiques fournis par une librairie graphique externe.
Le Javascript est un langage de programmation très populaire qui permet aux développeurs de créer…