Le seuillage où "threshold" en anglais, est l'une des premières choses qu'on apprend à l'université quand on commence un cursus de vision par ordinateur. Le première fois que je l'ai utilisé si je ne me trompe pas, c'était avec le logiciel pandore qui je trouve est sincèrement une super initiative française en faveur du traitement d'image. La popularité d'OpenCV en devient presque dommage du fait qu'il nous empêche de nous tourner vers des outils français.
Enfin bref, le seuillage est très probablement la première méthode de segmentation qui a été inventée, dans sa forme normale, il s'agit de la plus simple et compréhensible manière de segmenter une image. Je parle de forme normale, car il existe de multiples seuillages et de nombreuses variantes à la simple forme qui consiste à choisir une valeur de seuil et dire que tous les pixels supérieurs à cette valeur font partie du fond et le reste des objets à étudier.
Dans sa forme la plus compliquée le seuillage est multiniveau c'est-à-dire y a plusieurs seuils et est un problème d'optimisation qui ne peut être résolu qu'avec des algorithmes d'optimisation tels que les
Preuve : Optimal multi-level Thresholding based on Maximum Tsallis Entropy via an Artificial Bee Colony Approach vous n'avez qu'a télécharger et décoder cet article de recherche pour vous en rendre compte.
Le seuillage ou "threshold" en anglais est la première forme de segmentation qu'on nous apprend quand on commence des cours de traitement et d'analyse d'image. Dans sa plus simple forme, seuillage à deux niveaux, cette technique permet d'or et déjà de résoudre de nombreux problèmes industriels.
Quoi qu'il en soit let's go to study the most dump thresolding approaches !
Dans cet article, nous verrons
Comment seuiller manuellement une image avec cv2.thresold
Comment le faire automatiquement en utilisant cette même fonction
Enfin pour finir nous expérimenterons la fonction adaptative thresold d'OpenCV
Il est possible de seuiller manuellement une image en utilisant la fonction cv2.thresold d'OpenCV. Pour rappel le seuillage manuelle d'une image consiste à fixer manuellement une valeur pour laquelle les pixels supérieur à cet valeur seront considéré comme faisant parti du fond et le reste comme partis des objets d'intérêt de l'image.
Voici comment cette fonction peut être appelée
Code :
ret,th=cv2.threshold(img, seuil,couleur, option)
Le premier paramètre de cette dernière est l'image à traiter, le second la valeur du seuil que vous aurez décidé, le troisième la couleur que prendrons les objets une fois seuillé, et enfin le dernier paramètre est tout simplmene le type de seuil que vous souhaitez. Dans sa version la plus simple ( manuel ) ce paramètre vaudra cv2.THRESH_BINARY. Pour finir, la fonction retourne la valeur du seuil, et l'image seuillée. Vous en conviendrez que dans le cas d'une seulliage manuel le premier retour est bien inutile car vous l'avez au préalable passé en paramètre. Cependant quand il s'agira d'un seuillage automatique, ce dernier paramètre permettra de récupérer la valeur du seuil choisi par l'algorithme.
Seuillage Manuel
import cv2
import numpy as np
img=cv2.imread("fleur.png");
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,th=cv2.threshold(gray,150,255,cv2.THRESH_BINARY)
cv2.namedWindow('image',cv2.WINDOW_NORMAL)
cv2.imshow('image',th)
cv2.waitKey(0)
cv2.destroyAllWindows()
Comme je l'ai dit dans le titre de cette section et précédemment, que vous deviez seuiller manuellement ou automatiquement une image, vous utiliserez la même fonction cv2.thresold, seul le dernier paramètre changera et se transformera en cv2.THRESH_BINARY+cv2.THRESH_OTSU.
Pour ceux qui ne connaîtraient pas le fonctionnement d'Otsu je vais rapidement le rappeler. La méthode d'Otsu considère dès le départ que l'image est constituée de deux classes: la classe fond et la classe objet. Pour seuiller l'image, il va tester toutes les valeurs de seuil possibles, en gros de 0 à 255 pour une image 8 bits et par la suite il va calculer la variance des pixels du fond, et celle des pixels des objets . Le seuil pour lequel la somme des deux variances que j'ai citées précédemment est la plus faible est considéré comme seuil optimal et est sélectionné. L'idée derrière cela est que les valeurs du fond sont proches entre les une des autres, et probablement celle des objets aussi du coup si elles sont rassemblées, elle présente une plus faible variance que si elles sont mélangées.
L'idée est bonne pour certains types d'images tels que celle ci-dessous ou tous les pixels du fonds ont la même valeur.
exemple microscope
Ceci dit dans d'autres cas elle peut être très mauvaise. Quoi qu'il en soit, il faut dans tous les cas choisir sa méthode de segmentation avec parcimonie.
exemple imagenet
Bon, j'ai suffisamment exposé cette méthode. Passons à la pratique maintenant.
Dans l'exemple ci-dessous, je me suis permis de passer l'image au format HSV avant de faire le seuillage et de seuiller sur deux canaux le hue et le saturation et enfin d'additionner les deux. Vous remarquerez que le résultat est meilleur qu'avant. D'ailleurs c'est ce que je vous conseille, avant de seuiller une image de changer son espace de couleur. De nombreux espaces de couleur existent, mon préféré c'est le HSV mais vous pouvez tout aussi bien utiliser l'espace CIELab qui a aussi ces partisans.
import cv2
import numpy as np
img=cv2.imread ("fleur.png");
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v= cv2.split(hsv)
ret_h, th_h = cv2.threshold(h,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
ret_s, th_s = cv2.threshold(s,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
#Fusion th_h et th_s
th=cv2.bitwise_or(th_h,th_s)
cv2.imwrite("th.png",th)
import cv2img=cv2.imread ("1.png");gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)th = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,71,17)cv2.imwrite("1_th.png",th)
Quelque article de recherche sur le seuillage :