Nous avons vu dans un article précédent, que nous pouvons utiliser un classificateur de Haar pour détecter un certain nombre d’objets comme des visages, des yeux, des têtes de chats. Cependant, le nombre de classificateurs fournis avec OpenCV est limité. C’est pourquoi, nous allons voir dans cet article comment nous pouvons entraîner un nouveau classificateur afin de reconnaître des panneaux stop dans une image.

Étape 1: Préparation

Afin de pouvoir entraîner notre propre classificateur, nous avons besoin d’un grand nombre d’images contenant l’objet à détecter (images positives) et d’un nombre encore plus grand sans objet (images négatives).

Étape 1.1 : Acquisition des images négative

Pour les images négatives, je vous invite à lire cet article, où nous avons vu comment télécharger des images à partir de la base de données ImageNet.

Nous stockons toutes les images négatives dans un dossier nommé négatives. Puis nous créons un fichier texte, negatives.txt, contenant la liste de toutes les images négatives, grâce à la commande suivante :

find ./negatives/ -name '*.jpg' > negatives.txt 
Contenu du fichier negatives.txt

Étape 1.2 : Création des images positives

Passons maintenant aux images positives. Il est nécessaire pour entraîner un classificateur d’avoir d’en avoir un grand nombre. De plus, il est nécessaire pour chaque image de connaître le nombre d’occurrences de l’objet d’intérêt, ainsi que ses coordonnées dans l’image. La création manuelle d’un tel fichier est très fastidieuse.

Par chance, OpenCV propose un outil, opencv_creatsample, permettant de créer des images positives à partir d’une seule image d’entrée. De plus, cet outil permet en plus de créer le fichier descripteur associé.

Nous avons donc besoin d’une image contenant uniquement notre objet qui est dans notre cas une image d’un panneau stop. Et nous créons également un dossier positives, où nous stockerons les images générées.

stop.png

Nous sommes prêts pour appeler la fonction opencv_createsamples. Nous commençons par fournir à la fonction notre image d’entrée (-img), la liste des fichiers des images négatives que nous avons généré précédemment (-bg) et la destination du fichier contenant les informations sur les images positives (-info). L’option -pngoutput permet de sauvegarder les images générées par l’outil. Enfin l’option -num permet de définir le nombre d’images à générer.

opencv_createsamples -img stop.png -bg negatives.txt -info positives/positives.lst -pngoutput -num 600

Cette opération prend quelques secondes, et nous pouvons alors visualiser les images résultantes, ainsi que le fichier positives.lst qui a été généré.

Comment entraîner un classificateur de Haar : images positives générées
Exemples d’images positives
liste des images positives et leurs caractéristiques pour entraîner un classificateur de Haar
Contenu du fichier positives.lst : pour chaque image, nous avons le nombre d’occurrences (1) et les coordonnées de l’objet.

Étape 1.3 : Création du fichier descripteur

Maintenant que nous avons nos images positives, nous devons créer un fichier binaire rassemblant toutes les images positives, afin de les utiliser pour l’apprentissage.

L’outil opencv_createsamples nous permet facilement de générer ce fichier. Les arguments pris en compte sont la liste des images positives (-info), la destination de notre fichier de sortie (-vec), le nombre d’échantillons à prendre en compte (-num) et la taille en pixel des échantillons (-w et -h).

opencv_createsamples -info positives/positives.lst  -num 600 -w 24 -h 24 -vec positives.vec

Étape 2 : Apprentissage du classificateur

Tout est prêt, nous pouvons passer à l’apprentissage du classificateur.

Nous commençons par créer un dossier data qui contiendra notre classificateur. Puis nous appelons l’outil opencv_traincascade, qui permet, comme son nom l’indique, d’entraîner une cascade.

Cet outil prend en argument le dossier qui contiendra le classificateur entraîné (-data), notre fichier descripteur postives.vec (-vec), la liste des images négatives (-bg).

Nous indiquons également le nombre d’images positives (-numPos) et le nombre d’images négatives (-numNeg) qui seront utilisés à chaque itération. Le nombre d’images à utiliser doit être inférieur au nombre d’images disponible. Enfin, nous indiquons le nombre de itérations à entraîner (-numStages) ainsi que la taille, en pixel des échantillons (-w -h).

opencv_traincascade -data data -vec positives.vec -bg negatives.txt -numPos 550 -numNeg 600 -numStages 20 -w 24 -h 24

Entraîner un classificateur prend un certain temps : 33 minutes dans mon cas et dépend fortement du nombre d’itérations que vous avez spécifié. Pour chaque itération, un fichier stageXX.xml est créé. Cela permet de pouvoir arrêter l’apprentissage et reprendre de le reprendre à la dernière itération connue. Lorsque l’entraînement se termine un fichier cascade.xml est créé.

Apprentissage du classificateur avec OpenCV

Étape 3 : Test du classificateur

Afin de pouvoir tester notre classificateur, nous reprenons simplement le code que nous avions réalisé dans cet article et nous l’adaptons pour notre situation.

import cv2
stop_cascade = cv2.CascadeClassifier('cascade.xml')
img = cv2.imread('image.jpg')
panneaux = stop_cascade.detectMultiScale(img, scaleFactor=1.3, minNeighbors=5)
print(panneaux)
for (x,y,w,h) in panneaux:
	cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Et voilà, nous pouvons utiliser notre classificateur afin de pouvoir détecter des panneaux stops dans des images.

Nous avons vu aujourd’hui comment créer un classificateur pour détecter un panneau Stop. Pour ce faire, nous avons eu besoin d’une seule image de panneau Stop. En effet, les panneaux Stop ont toujours là même apparence. Si nous souhaitons détecter un objet dont l’apparence peut changer, il est nécessaire d’utiliser plusieurs images de l’objet pour entraîner le classificateur.


0 commentaire

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.