Opencv advanced 01-application et exemple d'histogramme cv2.calcHist()

Qu'est-ce qu'un histogramme ?

Un histogramme est une représentation graphique utilisée pour montrer la distribution de valeurs individuelles ou de plages de valeurs dans les données. Il divise les données en une série d'intervalles (également appelés "bins" ou "bins"), puis compte la fréquence (ou fréquence) des données dans chaque intervalle. Les histogrammes peuvent nous aider à mieux comprendre les caractéristiques de distribution des données, y compris la tendance centrale, la dispersion, etc.

Les principales caractéristiques des histogrammes incluent :

1. Axe horizontal (axe X) : L'axe horizontal représente la plage numérique ou l'intervalle des données. Chaque intervalle est généralement représenté par deux valeurs numériques, par exemple, 0-10, 10-20, etc.

2. Axe vertical (axe Y ) : L'axe vertical représente la fréquence (ou fréquence) des données dans chaque intervalle, c'est-à-dire le nombre de fois où les données apparaissent dans cet intervalle.

3. Graphique à barres : Le graphique de l'histogramme est composé d'une série de barres rectangulaires.La largeur de chaque barre rectangulaire représente la largeur de l'intervalle, et la hauteur représente la fréquence des données dans l'intervalle.

4. Données continues : 直方图适用于连续型数据, telles que les données de mesure, les données temporelles, etc. 对于离散型数据,柱状图可能更为适合.

Les histogrammes ont des applications importantes dans de nombreux domaines, notamment les statistiques, le traitement d'images, l'analyse de données, etc. Dans le traitement d'image, l'histogramme peut être utilisé pour analyser la distribution des valeurs de pixel de l'image, de manière à effectuer une amélioration de l'image, un réglage du contraste, une segmentation de l'image et d'autres opérations. En statistique, les histogrammes peuvent nous aider à comprendre la distribution des données, telle que la distribution normale, la distribution asymétrique, etc. En observant l'histogramme, nous pouvons mieux comprendre les caractéristiques des données, afin de prendre des décisions et des analyses plus précises.

Signification de l'histogramme dans l'image

D'un point de vue statistique, l'histogramme est une fonction entre les caractéristiques statistiques de la valeur de gris dans l'image et la valeur de gris de l'image, et l'histogramme compte le nombre d'occurrences de chaque niveau de gris dans l'image.从直方图的图形上观察,横坐标是图像中各像素点的灰度级,纵坐标是具有该灰度级(像素值)的像素个数。

Par exemple, considérons l'image illustrée à la Figure 13-1. Il n'y a que 9 pixels dans cette image, et il y a 1, 2, 3, 4, 5, un total de 5 niveaux de gris.

insérez la description de l'image ici

Comptez le nombre d'occurrences de chaque niveau de gris, comme indiqué dans le Tableau 13-1

insérez la description de l'image ici
Lors du dessin d'un histogramme, le niveau de gris est traité comme l'axe des x et le nombre d'occurrences du niveau de gris est traité comme l'axe des y, alors on peut savoir que :

  • La donnée de l'axe des abscisses est x=[1 2 3 4 5].
  • La donnée de l'axe y est y=[3 1 2 1 2].

Selon la relation ci-dessus, le graphique linéaire (image de gauche) et l'histogramme (image de droite) illustrés à la Figure 13-2 peuvent être dessinés. En général, nous nous référons au graphique en ligne droite à gauche et à l'histogramme à droite en tant qu'histogrammes.

insérez la description de l'image ici

Dans le traitement réel, l'intervalle d'axe x de l'histogramme d'image est généralement [0, 255], correspondant aux 256 niveaux de gris du bitmap 8 bits ; l'axe y correspond au nombre de pixels avec des niveaux de gris correspondants.

Par exemple, dans la Figure 13-3, l'image supérieure est une image et l'image inférieure est son histogramme correspondant. Les points sur la figure indiquent que ces pixels seront comptés dans le niveau de gris correspondant.

insérez la description de l'image ici

Bien que les images 8 bits aient toutes 256 niveaux de gris (chaque pixel peut avoir 256 niveaux de gris), le nombre de pixels appartenant à différents niveaux de gris est très différent.

Par exemple, dans la Figure 13-4, on peut voir sur la figure que les histogrammes des différentes parties de l'image sont différents.
insérez la description de l'image ici

Parfois, un histogramme normalisé est également utilisé pour faciliter la présentation. Dans l'histogramme normalisé, l'axe des abscisses représente toujours des niveaux de gris, l'axe des ordonnées ne représente plus le nombre d'occurrences de niveaux de gris, mais la fréquence d'occurrences de niveaux de gris.
Par exemple, pour la Figure 13-1, la fréquence d'apparition de chaque niveau de gris est comptée :

La fréquence des occurrences en niveaux de gris = le nombre d'occurrences en niveaux de gris/nombre total de pixels

Il y a 9 pixels dans la Figure 13-1, les résultats statistiques sont donc présentés dans le Tableau 13-2.

insérez la description de l'image ici

Dans l'histogramme normalisé, la somme de la fréquence de chaque niveau de gris est 1. Par exemple, dans ce cas :

insérez la description de l'image ici
Lorsque vous dessinez un histogramme, traitez le niveau de gris comme les données de l'axe des x et la fréquence de son apparition comme les données de l'axe des y, nous pouvons alors savoir :

  • La donnée de l'axe x est x=[1 2 3 4 5]
  • La donnée de l'axe y est y=[3/9 1/9 2/9 1/9 2/9]

Selon la relation ci-dessus, l'histogramme normalisé illustré à la Figure 13-5 peut être tracé. En comparant la Figure 13-4 et la Figure 13-5, nous pouvons voir que l'histogramme normalisé et l'histogramme sont cohérents en apparence, mais que les étiquettes de l'axe des ordonnées sont différentes.

Dans cet exemple, dans l'histogramme, les étiquettes affichées sur l'axe y sont 1, 2, 3 ; dans l'histogramme normalisé, les étiquettes affichées sur l'axe y sont 1/9, 2/9, 3/9.

insérez la description de l'image ici
Sur le site officiel d'OpenCV, il y a trois concepts auxquels il faut prêter attention : DIMS, BINS et RANGE.

  • DIMS : Indique le nombre de paramètres collectés lors du tracé de l'histogramme. En général, il n'y a qu'un seul type de données collectées dans l'histogramme, qui est le niveau de gris. Par conséquent, la valeur est 1.
  • GAMME : Indique la gamme de niveaux de gris à compter, généralement [0, 255]. 0 correspond au noir et 255 correspond au blanc.
  • BINS : Nombre de sous-ensembles de paramètres. Dans le processus de traitement des données, il est parfois nécessaire de diviser un grand nombre de données en plusieurs groupes pour l'analyse.

Par exemple, pour les niveaux de gris de la figure 13-1, vous voudrez peut-être parler de deux valeurs de pixel comme un ensemble. De cette manière, toute l'échelle de gris est divisée en trois groupes, plus précisément {{1,2} , {3,4} , {5} }. La figure 13-6 montre l'histogramme avant et après division.

insérez la description de l'image ici

Les images en niveaux de gris peuvent également être divisées de la manière décrite ci-dessus. Par exemple, dans une image en niveaux de gris, les 256 niveaux de gris dans l'intervalle [0, 255] sont divisés en sous-ensembles selon chaque groupe de 16 pixels :

[0, 255] = [0, 15] ∪ [16, 31] ∪…∪[240, 255]

Selon la méthode ci-dessus, toute la gamme d'échelles de gris peut être divisée en 16 sous-ensembles, plus précisément :

Toute la gamme de niveaux de gris = bin1 ∪ bin2 ∪…∪ bin16

Une fois les sous-ensembles divisés, l'histogramme généré par une image en niveaux de gris est illustré à la Figure 13-7 (b1 dans la figure représente bin1, b2 représente bin2, etc.).

insérez la description de l'image ici
Les valeurs BINS sont discutées ci-dessous:

  • Pour la Figure 13-1, il y a 5 niveaux de gris dans l'image d'origine et sa valeur BINS est 5. Après avoir sous-ensemble un groupe avec 2 niveaux de gris, 3 sous-ensembles sont obtenus, dont la valeur BINS est 3.
  • Pour l'image en niveaux de gris, l'intervalle de niveaux de gris est [0, 255], il y a 256 niveaux de gris au total et sa valeur BINS est de 256 ; après le sous-ensemble avec 16 niveaux de gris en tant que groupe, sa valeur BINS est de 16.

Pour le dire crûment, c'est le nombre de colonnes

dessiner un histogramme

Python 的模块 matplotlib.pyplot 中的 hist()La fonction peut facilement dessiner l'histogramme, et nous utilisons généralement cette fonction pour dessiner l'histogramme directement (ceci est également utilisé dans l'apprentissage automatique). De plus, OpenCV cv2.calcHist()函数peut calculer des histogrammes statistiques et peut également
dessiner des histogrammes d'images sur cette base. Ces deux méthodes sont décrites séparément ci-dessous.

Dessiner un histogramme avec Numpy

Le module matplotlib.pyplot fournit un cadre similaire à la méthode de dessin de MATLAB, qui peut être utilisé matplotlib.pyplot.hist()函数(ci-après appelé la fonction hist()) pour dessiner des histogrammes.

La fonction de cette fonction est de dessiner un histogramme en fonction de la source de données et du groupement de niveaux de gris. Son format de syntaxe de base est :

matplotlib.pyplot.hist(X,BINS)

Les significations des deux paramètres sont les suivantes :

  • X : source de données, doit être unidimensionnelle. Les images sont généralement bidimensionnelles et vous devez utiliser la fonction ravel() pour traiter l'image en une source de données unidimensionnelle avant de l'utiliser comme paramètre.

  • BINS : La valeur spécifique de BINS, indiquant le regroupement des niveaux de gris .

La fonction de ravel() est de réduire la dimension d'un tableau à deux dimensions en un tableau à une dimension. Par exemple, il y a l'image a avec la valeur :

insérez la description de l'image ici
Utilisez la fonction ravel() pour traiter un :

b = a.ravel()

b peut être obtenu comme :
insérez la description de l'image ici

Exemple : Utilisez la fonction hist() pour dessiner un histogramme d'une image.

insérez la description de l'image ici
code afficher comme ci-dessous:

import cv2
import matplotlib.pyplot as plt
o=cv2.imread("boat.jpg")
plt.hist(o.ravel(),256)
plt.show()

résultat de l'opération :

insérez la description de l'image ici

Exemple : Après avoir utilisé la fonction hist() pour diviser le niveau de gris d'une image en 16 groupes, tracez l'histogramme de l'image.

Remplacez le 255 ci-dessus par 16

import cv2
import matplotlib.pyplot as plt
o=cv2.imread("boat.jpg")
plt.hist(o.ravel(),16)
plt.show()

insérez la description de l'image ici

Dessiner un histogramme avec OpenCV

OpenCV fournit la fonction cv2.calcHist() pour calculer l'histogramme statistique de l'image, qui peut compter le nombre de pixels dans chaque niveau de gris. En utilisant la fonction plot() dans le module matplotlib.pyplot, les résultats statistiques de la fonction cv2.calcHist() peuvent être dessinés dans un histogramme

1. Utilisez la fonction cv2.calcHist() pour compter les informations d'histogramme d'image
La fonction cv2.calcHist() est utilisée pour compter les informations d'histogramme d'image, et son format de syntaxe est :

hist = cv2.calcHist( images, channels, mask, histSize, ranges, accumulate )

Les significations de la valeur de retour et des paramètres dans la fonction sont :

  • hist : l'histogramme statistique renvoyé est un tableau unidimensionnel, et les éléments du tableau sont le nombre de pixels dans chaque niveau de gris.

  • images : images originales, qui doivent être entourées de "[ ]".

  • canaux : spécifie le numéro de canal. Le numéro de canal doit être entouré de "[ ]". Si l'image d'entrée est une image en niveaux de gris monocanal, la valeur de ce paramètre est [0]. Pour les images couleur, ses valeurs peuvent être [0], [1], [2], correspondant respectivement aux canaux B, G, R.

  • masque : image de masque. Lors du comptage de l'histogramme de l'image entière, définissez cette valeur sur Aucun. Lors du comptage de l'histogramme d'une certaine partie de l'image, une image de masque est nécessaire.

  • histSize : La valeur de BINS, qui doit être entourée de "[ ]". Par exemple, la valeur de BINS est 256, vous devez utiliser "[256]" comme valeur de paramètre.

  • gammes : la gamme de valeurs de pixels. Par exemple, une image en niveaux de gris 8 bits a des valeurs de pixels dans la plage [0, 255].

  • cumul : indicateur cumulatif (cumulatif, superposé), la valeur par défaut est False. S'il est défini sur True, l'histogramme ne sera pas effacé au début du calcul et le calcul est le résultat cumulé de plusieurs histogrammes, qui est utilisé pour calculer l'histogramme d'un groupe d'images
    . Ce paramètre permet de calculer un seul histogramme à partir de plusieurs objets ou de mettre à jour l'histogramme en temps réel. Ce paramètre est facultatif et n'a généralement pas besoin d'être défini.

Exemple : utilisez la fonction cv2.calcHist() pour calculer le résultat de l'histogramme statistique d'une image et observez les informations d'histogramme statistique obtenues.

code afficher comme ci-dessous:


import cv2
img=cv2.imread("boat.jpg")
hist = cv2.calcHist([img],[0],None,[16],[0,255])
print(type(hist))
print(hist.shape)
print(hist.size)
print(hist)

Les résultats d'exécution sont les suivants :
Notez que dans la fonction cv2.calcHist() de cet exemple :

  • Le premier paramètre "[img]" indique l'image d'origine pour dessiner l'histogramme, entre "[ ]".
  • Le deuxième paramètre indique quelle information d'histogramme de canal doit être comptée. L'img lu dans cet exemple est une image en niveaux de gris, il est donc
    représenté par "[0]".
  • Le troisième paramètre est l'image du masque, dans ce cas la valeur est "Aucun", ce qui signifie calculer l'histogramme de l'image entière.
  • Le quatrième paramètre "[16]" indique que la valeur de BINS est 16, c'est-à-dire qu'il est divisé en 16 groupes
  • Le cinquième paramètre "[0, 255]" indique que la gamme d'échelle de gris est [0, 255].
<class 'numpy.ndarray'>
(16, 1)
16
[[ 12575.]
 [ 39591.]
 [ 56651.]
 [ 38932.]
 [ 29997.]
 [ 33472.]
 [ 46033.]
 [ 74555.]
 [199718.]
 [288966.]
 [136663.]
 [ 44440.]
 [ 20355.]
 [ 20691.]
 [  5578.]
 [   344.]]

Exemple : dessiner un histogramme statistique

import cv2
from matplotlib import pyplot as plt

img=cv2.imread("boat.jpg")
hist = cv2.calcHist([img],[0],None,[16],[0,255])


plt.plot(hist,color='b')
plt.show()

résultat de l'opération :
insérez la description de l'image ici

Les fonctions ci-dessus permettent d'afficher des images dans des histogrammes. Parlons des fonctions d'application des histogrammes dans le traitement d'images.

Égalisation d'histogramme

Si une image a tous les niveaux de gris possibles et que les niveaux de gris des valeurs de pixel sont uniformément répartis, l'image a un contraste élevé et des tons de gris variables, des niveaux de gris riches et une large couverture. En apparence, ces images ont des couleurs plus riches et ne sont pas trop sombres ou lumineuses.

La figure 13-22 montre la comparaison d'une image avant et après l'égalisation de l'histogramme. L'image de gauche est l'image d'origine, qui est relativement sombre ; l'image de droite est l'image après l'égalisation, et la couleur est relativement équilibrée.

insérez la description de l'image ici

Sur le site Web officiel d'OpenCV, les histogrammes avant et après l'égalisation de l'image (c'est-à-dire l'égalisation de l'histogramme) sont comparés, comme illustré à la Figure 13-23. Parmi eux, l'image de gauche est l'histogramme de l'image d'origine. On peut voir que le niveau de gris est concentré au milieu et qu'il n'y a pas de pixels plus sombres et plus clairs dans l'image ; l'image de droite est l'histogramme après égalisation de l'original image, et la répartition des pixels est plus équilibrée. .

insérez la description de l'image ici

L'objectif principal de l'égalisation d'histogramme est de mapper uniformément le niveau de gris de l'image d'origine sur toute la plage de niveaux de gris et d'obtenir une image avec une distribution uniforme des niveaux de gris. Cette égalisation réalise non seulement l'équilibre de probabilité dans les statistiques de valeur de gris, mais réalise également l'équilibre visuel dans le système visuel humain (HVS).

Fonction d'égalisation d'histogramme

OpenCV 使用函数 cv2.equalizeHist()实现直方图均衡化. La syntaxe de cette fonction est :

dst = cv2.equalizeHist( src )

Dans la formule :

  • dst est le résultat du processus d'égalisation de l'histogramme.
  • src est une image brute monocanal 8 bits.

Exemple : Utilisez la fonction cv2.equalizeHist() pour implémenter l'égalisation d'histogramme.

Image originale :
insérez la description de l'image ici
le code est le suivant :

#-----------导入使用的模块---------------
import cv2
import matplotlib.pyplot as plt
#-----------读取原始图像---------------
img = cv2.imread('equ.bmp',cv2.IMREAD_GRAYSCALE)
#-----------直方图均衡化处理---------------
equ = cv2.equalizeHist(img)
#-----------显示均衡化前后的图像---------------
cv2.imshow("original",img)
cv2.imshow("result",equ)
#-----------显示均衡化前后的直方图---------------
plt.figure("原始图像直方图") #构建窗口
plt.hist(img.ravel(),256)
plt.figure("均衡化结果直方图") #构建新窗口
plt.hist(equ.ravel(),256)
plt.show()
#----------等待释放窗口---------------------
cv2.waitKey()
cv2.destroyAllWindows()

insérez la description de l'image ici
On peut voir sur les résultats que le contraste est évident : avant l'égalisation de l'histogramme, l'image globale est plus lumineuse
; après l'égalisation, la luminosité de l'image devient plus équilibrée. Le contraste entre les histogrammes des deux images est moins évident. Cela reflète en fait le fait que la péréquation fait référence au résultat d'un examen approfondi de la probabilité statistique et de la HVS.

insérez la description de l'image ici
insérez la description de l'image ici
Voici une explication simple :

  • L'histogramme de l'image d'origine, la plupart des valeurs de pixels sont concentrées à droite (lignes denses). Cela montre qu'il y a de nombreux pixels dans l'intervalle [200,255] dans l'image, et que l'image est relativement lumineuse.

  • Dans l'histogramme égalisé, les pixels de gauche sont plus denses et les pixels de droite sont relativement clairsemés. Cependant, en fait, l'œil humain ne peut pas percevoir clairement les différences subtiles dans les valeurs de pixel, nous pouvons donc considérer des valeurs de pixel similaires comme la même valeur de pixel, de sorte qu'un histogramme similaire à la figure 13-29 sera obtenu. A ce moment, la distribution des niveaux de gris dans l'histogramme est relativement équilibrée, et il s'agit d'un histogramme équilibré et cohérent.

Je suppose que tu aimes

Origine blog.csdn.net/hai411741962/article/details/132235279
conseillé
Classement