Égalisation d'histogramme en Python

Vous vous souvenez quand vous avez vu cette image de basse qualité et que vous vous êtes senti un peu déçu? Ce n'était pas assez clair et les détails étaient un peu flous. Et si vous pouviez améliorer cette image pour une meilleure version? Ne serait-ce pas génial? Heureusement, il existe un moyen de le faire, en utilisant Python!

Une des méthodes que vous pouvez utiliser pour améliorer une image est Égalisation d'histogramme, qui améliore en particulier la contraste de l'image. Presque tous les systèmes de caméra utilisent effectivement l’égalisation des histogrammes pour améliorer la qualité de nos images. À la fin du didacticiel, vous découvrirez pourquoi il en est ainsi..

Dans la section suivante, nous approfondirons ce que l'on entend par égalisation d'histogramme et ce qu'il advient de l'image lors de l'application de la méthode. Nous verrons ensuite comment implémenter la méthode en Python. Prêt?

Égalisation d'histogramme

Supposons que vous ayez l'image pout.jpg (allez-y et téléchargez-la). Ceci est une image de démonstration utilisée dans MATLAB, d'où je l'ai obtenue, mais nous l'utilisons dans notre tutoriel ici. L'image ressemble à ceci:

Voyons comment nous pouvons accéder aux valeurs de pixels de l'image, appelées intensités. J'ai écrit ce petit script Python que nous pouvons utiliser pour cela (notez que j'utilise la bibliothèque OpenCV):

import cv2 img = cv2.imread ('pout.jpg') img_shape = img.shape hauteur = img_shape [0] width = img_shape [1] pour rangée dans la largeur (largeur): pour colonne dans la hauteur (hauteur): print (img [colonne] [rangée])

Ce que je fais ici, c'est lire notre image (pout.jpg), puis examiner la forme (taille) de l'image. img_shape retournera: (1031, 850, 3). Cela signifie que notre image est de hauteur (nombre de colonnes) 1031, et de largeur (nombre de lignes) 850, et a 3 canaux (RVB). Notez que le premier paramètre du résultat est la hauteur et le second paramètre est la largeur. Enfin, nous parcourons les rangées et les colonnes et imprimons les différentes valeurs de pixel (intensités) à chaque paire rangée / colonne..

Un exemple de la sortie est: [137 137 137]. Oui, je sais, vous vous attendiez à une valeur pour l'intensité du pixel. Nous avons en réalité la valeur de l'intensité des pixels ici, mais ce que la sortie nous montre sont les résultats du rouge, du vert et du bleu (RVB) canaux. Sachez toutefois que dans OpenCV, la commande est BGR, C'est ainsi que OpenCV charge l'image. Ainsi, l’exemple de résultat ci-dessus contient la valeur 137 pour chaque canal, dans l'ordre de B, g, et R, respectivement.

La raison de cette introduction est que l’égalisation de l’histogramme concerne en fait la modification de l'intensité des pixels pour améliorer le contraste de l'image. Ainsi, notre travail principal ici sera au niveau de l'intensité du pixel.

À ce stade, vous vous demandez peut-être quel histogramme est. Bien que parfois le terme puisse être un peu déroutant, il s’agit en réalité d’un concept très simple. L'histogramme est simplement un diagramme décrivant le nombre de pixels d'une image à chaque valeur d'intensité trouvée dans cette image..

Puisque nos pixels ont trois valeurs, une pour chacun des canaux BGR, une façon de dessiner l'histogramme consiste à avoir trois histogrammes, un pour chaque canal, où l'axe des x aura les différentes valeurs de pixel (intensités) et y -axis montrera combien de fois (fréquence) cette valeur de pixel est apparue parmi les différentes valeurs de pixel.

Par exemple, l’histogramme du canal rouge peut avoir une valeur de pixel de 137 sur l'axe des x, et l'axe des y peut indiquer le nombre de pixels ayant cette valeur pour le canal rouge, par exemple, 86. Donc, la façon dont nous lisons cela est en disant que la valeur de pixel pour le canal rouge de 137 a montré dans 86 pixels, ou a répété 86 fois à notre image.

En utilisant le code de cet article Image Histogram pour dessiner l'histogramme de notre image, nous obtenons ce qui suit:

L'histogramme est en fait pour les canaux rouge, vert et bleu. Prenons un petit échantillon de la sortie du code précédent, comme indiqué ci-dessous. Cela montre que les valeurs de canal semblent toujours être les mêmes et que les trois différentes lignes tracées auront donc les mêmes valeurs et seront tracées les unes sur les autres, sous la forme d'une seule ligne..

[94 94 94] [95 95 95] [97 97 97] [99 99 99] [100 100 100] [101 101 101] [101 101 101] [101 101 101] [100 100 100] [98 98 98] [95 95 95] [93 93 93]

Ce que la méthode d’égalisation de l’histogramme fera pour l’histogramme ci-dessus, c’est qu’elle transformera les valeurs d’intensité de manière à rendre l’histogramme flatter dans l'image résultante. En d’autres termes, l’égalisation par histogramme est une méthode qui ajuste les intensités de l’image afin d’améliorer le contraste de l’image..

L'histogramme ci-dessus semble un peu concentré vers le milieu de la figure et l'égalisation de l'histogramme consiste à répartir davantage les valeurs d'intensité des pixels pour obtenir un histogramme plus aplati..

Je pense que la question de l’égalisation de l’histogramme est suffisante pour que nous discutions ici, étant donné que nous ne voulons pas obtenir plus de mathématiques dans ce didacticiel, d’autant plus que cela concerne davantage l’implémentation de la méthode en Python. Cependant, vous pouvez vérifier ces notes qui montrent les différentes formules impliquées dans la méthode: égalisation d'histogramme. Alors maintenant, plongons dans la mise en œuvre!

Égalisation d'histogramme en Python

Dans cette section, je vais vous montrer comment implémenter la méthode d'égalisation d'histogramme en Python. Nous allons utiliser l'image ci-dessus (pout.jpg) dans nos expériences. Passons en revue le processus étape par étape. La première chose à faire est d’importer les bibliothèques OpenCV et NumPy, comme suit:

import cv2 import numpy

Après cela, nous avons simplement besoin de lire notre image, pout.jpg:

img = cv2.imread ('pout.jpg')

La bonne nouvelle est que OpenCV nous fournit une fonction grâce à laquelle nous pouvons appliquer une égalisation d'histogramme sur une image, à savoir equalizeHist (). Il est facile d’appliquer cette fonction sur une image en niveaux de gris car la méthode égalise en réalité l’histogramme d’un objet. niveaux de gris image, mais dans notre cas, nous avons trois canaux (RVB) pour chaque pixel et nous ne pouvons pas appliquer l'égalisation d'histogramme sur les trois canaux de manière séparée.

Une solution intéressante que j'ai trouvée dans le livre Python: L'apprentissage automatique dans le monde réel consiste à convertir notre image en espace couleur YUV, à égaliser les Y canal, et enfin convertir le résultat en RVB. Donc, la première chose que nous faisons est de convertir notre image en YUV. Cela peut être fait en utilisant la méthode cvtColor (), qui convertit l'image d'une couleur d'espace en une autre, comme suit:

img_to_yuv = cv2.cvtColor (img, cv2.COLOR_BGR2YUV)

Notez que nous utilisons BGR au lieu de RVB ici, puisque OpenCV (comme mentionné précédemment) charge les images dans BGR format.

Nous appliquons maintenant la méthode d’égalisation de l’histogramme sur la Y canal utilisant la méthode equalizeHist ():

img_to_yuv [:,:, 0] = cv2.equalizeHist (img_to_yuv [:,:: 0])

Enfin, nous convertissons le Y canal vers RVB (BGR OpenCV), comme suit:

hist_equalization_result = cv2.cvtColor (img_to_yuv, cv2.COLOR_YUV2BGR)

Toutes nos félicitations! Vous avez maintenant appliqué une égalisation d'histogramme à l'image. Dans la prochaine sous-section, je vais rassembler tout le code et vous montrer à quoi ressemblera notre image après l'application de l'égalisation d'histogramme..

Mettre tous ensemble

Mettons tout ce que nous avons appris ensemble. Le script Python pour appliquer l'égalisation d'histogramme sur pout.jpg se présente comme suit:

import cv2 import numpy img = cv2.imread ('pout.jpg') img_to_yuv = cv2.cvtColor (img, cv2.COLOR_BGR2YUV) img_to_yuv = cv2.cvtColor (img, cv2.COLOR_BGR2YUV) img_to_yuv = cv2.cvtColor (img, cv2.COLOR_BGR2YUV) img_to_yuv [:,:,,], cv2.equalizeHist (img_to_yuv [,, hist_equalization_result = cv2.cvtColor (img_to_yuv, cv2.COLOR_YUV2BGR) cv2.imwrite ('result.jpg', hist_equalization_result)

La sortie du script ci-dessus est l'image suivante:

Pour mieux remarquer la différence, je mettrai les deux images l'une à côté de l'autre (à gauche: image d'origine; à droite: résultat de l'égalisation de l'histogramme):

Avez-vous remarqué la différence? La bonne image est beaucoup plus claire que l'image originale. Pas étonnant que presque tous les systèmes d'imagerie effectuent l'égalisation d'histogramme!

Avant de terminer, voyons à quoi ressemble l'histogramme de notre résultat:

Si vous comparez l'histogramme de l'image obtenue à l'histogramme de l'image d'origine, vous remarquerez que l'histogramme de l'image obtenue est plus plat que l'histogramme de l'image d'origine. C'est exactement ce que fait la méthode d'égalisation de l'histogramme..

Conclusion

Dans ce tutoriel, nous avons vu comment améliorer le contraste d’une image à l’aide d’une méthode appelée Égalisation d'histogramme, et comment il est facile de l'implémenter en utilisant Python et OpenCV.

Le résultat était très intéressant car il était beaucoup plus clair que l'image d'origine et l'histogramme du résultat était plus plat que l'histogramme de l'image d'origine, montrant une meilleure répartition des valeurs d'intensité de pixels sur l'image..

Enfin, n'hésitez pas à voir ce que nous avons à vendre et à étudier sur le marché Envato, posez vos questions et transmettez vos précieux commentaires en utilisant le flux ci-dessous..