Une des opérations les plus courantes dans le traitement d’image est le prétraitement des images. Différentes étapes peuvent être réalisées pour améliorer l’image afin de faciliter les traitements ultérieurs. Parmi ces étapes, les opérations de seuillage sont régulièrement utilisés afin de pouvoir exploiter l’image plus facilement.

Regarder bien l’image suivante, combien de forme voyez-vous ? La réponse évidente est 3: un rond, un triangle et un carré. Mais en êtes-vous bien sûr ? En fait une dernière étoile se cache dans l’image. Comment la voir ? En faisant un seuillage sur les niveau de gris de cette image.

image non seuillee

Mais avant de commencer, un petit rappel sur ce qu’est une image en niveau de gris. Une image est composée de pixels. Chacun de ces pixels a une valeur comprise entre 0 et 255. Plus la valeur est proche de 0, plus le pixel est sombre et inversement, un pixel s’approchant de 255.

Le principe du seuillage est de remplacer un à un les pixels d’une image à l’aide d’une valeur seuil fixée (par exemple 125).

Seuillage binaire

Révélons donc l’étoile dans notre image :

import cv2

img=cv2.imread('image.png',cv2.IMREAD_GRAYSCALE)

_, img_seuil = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY)

cv2.imshow("image",img_seuil)
cv2.waitKey(0)

Qu’avons-nous fait ? grâce à la fonction cv2.threshold() d’OpenCV, nous avons remplacé les pixels dont la valeur est supérieure à 0 à une valeur donnée (255). C’est ce que l’on appelle un seuil binaire (il ne reste que deux valeurs : 0 et 255)

Si img(x,y) > seuil:
	img_seuil(x,y)=255
Sinon:
	img_seuil(x,y)=0
Application d'un seuillage binaire
Seuillage binaire

Le seuillage permet donc d’effectuer un traitement à une image afin de pouvoir mettre en avant certaines de ses caractéristiques.

Il peut être intéressant dans certaines applications d’obtenir le négatif de cette image, à savoir les formes en noir sur un fond blanc. Pour obtenir ce résultat, il suffit d’appliquer un seuillage binaire inverse

_, img_seuil = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV)

Comme vous pouvez vous en douter ce seuillage produit l’inverse de la méthode précédente

Si img(x,y) > seuil:
	img_seuil(x,y)=0
Sinon:
	img_seuil(x,y)=255
Application d'un seuillage binaire inverse

Seuillage tronqué

Cette méthode permet d’assigner aux pixels supérieurs à un seuil, la valeur du seuil. Il est à noter que pour ce seuillage, ainsi que pour les suivants, la valeur maximale des pixels seuillés n’est plus utilisée. Il est cependant nécessaire de garder une valeur max pour le fonctionnement de la fonction.

_,img_seuil = cv2.threshold(img, 100, 255, cv2.THRESH_TRUNC)
Si img(x,y) > seuil:
	img_seuil(x,y)=seuil
Sinon:
	img_seuil(x,y)=0
Seuillage tronqué

Ce qui donne le résultat suivant:

Seuillage à zéro

_,img_seuil = cv2.threshold(img, 100, 255, cv2.THRESH_TOZERO)

Cette méthode permet de mettre à zéro tous les pixels en dessous du seuil et de garder les valeurs des pixels supérieurs au seuil.

Si img(x,y) > seuil:
	img_seuil(x,y)=img(x,y)
Sinon:
	img_seuil(x,y)=0
Seuillage à Zéro

Bien évidemment l’inverse existe l’inverse: cv2.THRESH_TOZERO_INV

Seuillage à Zéro inversé

Les artefacts que l’on peut distinguer viennent du fait que les bordures des objets ont une « valeur de transition » entre la couleur de l’objet et le fond. Cette valeur peut alors se retrouver en dessous du seuil sélectionné, rendant les contours moins nets. Certains lecteurs ont été confronté à cette problématique lors de la reconnaissance de formes.

Les méthodes de seuillage sont régulièrement utilisé en traitement de l’image car elles permettent de faciliter l’extraction de caractéristiques, d’objets … Nous avions d’ailleurs utilisé un seuillage binaire pour extraire les dés ou pour la détection de plaques d’immatriculation


6 commentaires

DIPAMA · 20 juin 2019 à 18 h 52 min

bonjour,
j’utilise le seuillage binaire inverse sur python, mais mon programme me signale que l’objet module n’a pas d’attribut ‘thresh_binary inv’.
j’ai vraiment besoin de votre aide.
cordialement.

    Florent · 21 juin 2019 à 9 h 29 min

    Bonjour,
    Essayez de vérifier que « cv2.THRESH_BINARY_INV » est bien écrit. Il faut que ce module soit écrit en majuscules et non en minuscules.
    Est-ce que les autres fonctions de seuillage fonctionnent ?

      DIPAMA · 21 juin 2019 à 11 h 05 min

      Bonjour,
      j’ai appliquer un filtre gaussien mais cela marche.
      je travaille avec opencv 3.3.0 et il y a deux pythons installés sur ma Raspberrry; mais j’exécute le programme avec le python3.
      j’ai vérifier la syntaxe mais tout est écris en majuscule.
      j’ai toujours le même problème

DIPAMA · 21 juin 2019 à 11 h 11 min

merci monsieur,
j’avais oublié le « H » dans « THRESH »

DIPAMA · 21 juin 2019 à 11 h 23 min

maintenant, je veux détecter le contour de ma ligne et lorsque j’écris le programme suivant, il me mentionne qu’il y a trop de valeurs à compresser.
voici le programme:  » contours,hier = cv2.findContours(gb,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE).

j’ai vraiment besoin de votre aide.
merci.

    Florent · 21 juin 2019 à 12 h 29 min

    Bonjour,
    la commande que vous entrez est valable pour Opencv 4
    Pour OpenCV 3, trois variables sont renvoyées. Il faut alors remplacer contours,hier=cv2.findContours[…] par _,contours,hier=cv2.findContours[…]

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.