Tout ce qui suit, jusqu’à la sortie de l’algorithme de Freeman, a été codé par Patrick. Je me suis chargé de la partie discrimination des objets. Il est donc possible que quelques coquilles se soient glissées dans ce texte et qu’il soit incomplet, je n’explique que ce que j’ai compris !
Bien évidemment, le plus simple est de demander (à Patrick ou à moi) des précisions si besoin.
Rentrons dans le vif du sujet : une webcam Philips est connectée au PC embarqué dans le robot, via le port USB.
Afin d’être correctement détectée et utilisable par le PC, le module pwcx est utilisé.
Nous utilisons un programme en C pour récupèrer les captures d’images (lesquelles sont envoyées dans un format YUV422Planar). Ce programme est nommé ccvt pour Colour ConVerT.
L’image est au format BVR, un octet par pixel et par couleur, soit 3 octets ou encore 24 bits par pixel. C’est à dire qu’on reçoit des suites d’octets représentant Bleu, Vert et Rouge, dans cette ordre, et non pas en RVB (ou RGB en anglais !).
Notre programme a pour premier objectif de trouver des objets de certaines couleurs dans l’image. Un algorithme nommé "Freeman" fait de la recherche de contours dans une image.
Pour chaque pixel d’une couleur donnée, il cherche dans son entourage si un autre a la même couleur. Ainsi, de proche en proche, il fait le tour d’un objet coloré, et cela, dans toute l’image. Quelques infos/exemples trouvés au hasard sur le web : http://www.tsi.enst.fr/tsi/enseigne...
Une fois son analyse terminée, l’algo renvoie une collection d’objets détectés, avec pour chacun :
– les coordonnées de son "rectangle englobant" ((x1,y1), (x2, y2))
– sa surface
– son barycentre
– sa couleur
Pour fonctionner, Freeman a besoin de connaitre les couleurs des objets qu’il doit chercher et d’avoir une image en HSV.
HSV est, comme RVB, un type d’espace de couleur. Ici, on code aussi 3 octets par pixels, mais au lieu de prendre les composantes rouge/vert/bleu, on prend teinte/saturation/valeur.
Avantage majeur : la couleur d’un pixel est entièrement définie par la composante "teinte" et pas par une combinaison RVB. On peut projeter cette teinte sur un cercle qui représente tout le spectre des couleurs, donc la teinte peut aller de 0 à 360.
Ainsi, par exemple, le rouge se trouve aux environs de 0, le vert du coté de 120 et le bleu vers 240. Sur un cercle, ces 3 couleurs sont donc parfaitement situées pour être détectées sans ambiguïté.
Pour convertir du RVB en HSV, l’algorithme est très simple et se trouve très facilement sur le net, via un moteur de recherche.
Donc, revenons à Freeman. On lui passe l’image de la caméra, convertie en HSV, les couleurs qui nous intéressent (rouge, vert et bleu) et il nous retourne un suite d’objets détectés, avec leurs caractéristiques.
C’est là que la discrimination des objets apparaît :
Pour chaque objet détecté, le programme détermine s’il s’agit :
– d’une quille debout (verte ou rouge)
– d’une quille couchée (verte ou rouge)
– d’une pile de quilles (verte ou rouge)
– d’un objet vert ou rouge mais qui n’est pas une quille.
– d’un objet qui touche un bord de l’image (donc impossible de dire précisément ce que c’est).
Pour cela, l’algorithme est simplissime. Il suffit de faire une série de comparaisons avec des ratios et des proportions. La vraie complexité a donc été de déterminer ces ratios et d’éviter qu’ils ne se "recoupent" (ex : une quille couchée qui est proche et dont on voit le dessus, de 3/4, a les bonnes proportions pour passer pour une quille debout, il faut donc utiliser la position dans l’image en plus des proportions).
Les principaux ratios utilisés ont été les suivants : * comparaison de la hauteur par rapport à la largeur de l’objet : ce ratio permet de savoir si l’objet a l’allure d’une quille debout ou d’une pile.
* comparaison de la hauteur de l’objet par rapport à sa position en Y dans l’image : permet de savoir si l’objet trouvé est suffisamment grand pour être une quille debout, une pile ou une quille couchée (l’axe Y sur l’image donne la distance par rapport au robot, plus l’objet est vu bas dans l’image, plus il est près)
* surface minimale et maximale : permet de savoir si l’objet n’est pas trop petit ou trop gros pour être une quille ou une pile.
Une fois ces calculs effectués, la suite d’objets de Freeman est mise à jour pour y indiquer pour chaque objet, ce que l’on a détecté (pile, quille, debout, couchée, objet inconnu ...).
Et là ... on sort de l’article ! Le traitement de ces information servira ensuite à déterminer la stratégie du robot (évitement, rapprochement, ...).
— -
En complément de ces opérations, une détection spéciale pour le départ est effectuée.
Certains nous ont peut-être vus, avec Patrick, en train de glisser 2 doigts en largeur entre la bordure gauche du terrain et le robot, lorsqu’on le plaçait sur la zone de départ. C’était tout simplement pour que le robot soit dans une position "identique" à chaque départ, car la vision était calibrée pour détecter les ponts.
L’algorithme de détection des ponts utilise les mêmes composants, à la seule différence près, qu’il cherche le fossé (donc du bleu) et que le seul ratio utilisé pour déterminer la position du pont est la largeur de la bande bleue détectée à gauche de l’image (plus elle est grande, plus le pont est à droite !)
La détection de pont ne fonctionne qu’une seule fois, au départ ! En fait, le robot prends une image au moment où l’on retire le jack, l’analyse à la recherche d’un pont et mémorise sa position une fois pour toute.
— -
Enfin, des développements ont été effectués ("à l’arrache" ! l’avant veille de la coupe) pour déterminer la distance d’une quille par rapport au robot (en fonction de sa position en Y dans l’image), cela a donné lieu à des tests assez impressionnants, avec une précision de l’ordre du centimètre pour un objet à 1.5 mètre sur une image capturée en 320*240.
Une expérimentation a été faite (tout autant à l’arrache !) pour détecter les socles blancs des quilles. Mais avec les reflets et les bordures, cela donnait des résultats assez mitigés. De toute façon, cela n’était plus une priorité à ce moment là.
— -
Voilà pour cette première présentation !
Tout ceci est à la fois très simple techniquement et très compliqué à mettre en oeuvre.
Une interface graphique de démonstration a été développée afin de présenter le fonctionnement de la vision lors de la Fête de la Science 2005 : Interface de démo "Vision" (2005).
Pour conclure, quelques infos pratiques/anecdotes/commentaires :
– Seule la détection des pont a été utilisée en match à la coupe.
– L’éclairage se doit d’être très intense, faute de quoi le contraste n’est pas assez élevé pour Freeman. Cela fait toute la différence avec bon nombre d’équipes, qui sont au contraire perturbées dans ces conditions.
– La détection des ponts n’a pas pu être utilisée à la coupe Med, faute d’éclairage, d’où le changement de stratégie (on ne traversait plus les ponts !).
– Julien a généré plus d’un millier d’images sous POV pour m’aider à calibrer, sinon j’y serais encore !
– Patrick m’a fait une démonstration de son code (algo de Freeman) qui était déjà en place à la fête de la science 2004, alors que je n’étais pas encore membre du club !
– Je continue de me demander s’il n’y avait pas une méthode plus simple, plus "class" et plus rapide pour arriver à discriminer les quilles, tout en n’en ayant pas trouvé !
– Dès que la caméra bougeait de 2 millimètres, tout le calibrage était à refaire ... et a été refait, en remettant la caméra là ou elle était avant 😄