Rapport

publicité
Rapport de projet
Traitement vidéo
Sommaire
Présentation..................................................................................................................................4
Cahier des charges.........................................................................................................................5
Choix des composants....................................................................................................................5
Organisation..................................................................................................................................8
Le projet........................................................................................................................................9
La mémoire ...............................................................................................................................9
RS232 ......................................................................................................................................11
Présentation de la caméra........................................................................................................12
Récupération des données .......................................................................................................13
Traitement sur les données ......................................................................................................17
Le programme .........................................................................................................................19
Connexion entre la caméra et la carte FPGA ..............................................................................21
Etat actuel du projet....................................................................................................................22
Conclusion...................................................................................................................................22
Présentation
Dans ce rapport, nous allons voir quels étaient les objectifs du projet qui ont été fixé, son
environnement et ses étapes pour sa réalisation.
Ainsi, l’objectif de ce projet est de permettre au robot PROMOCO de suivre, de façon autonome, une
ligne tracée sur le sol et de changer son comportement selon la courbe de la ligne ou encore selon
les formes autour de cette ligne. Par exemple, si le robot détecte un carré de couleur rouge, il devra
s’arrêter. Pour cela, il faut définir quel sera le système adapté pour acquérir des images, et appliquer
des algorithmes sur ces captures pour reconnaitre la ligne ou les formes sur le sol. Ceci défini les
objectifs de ce projet.
Voici un exemple montrant une application concrète de ce projet :
Enfin, pour le traitement 3, on peut imaginer que si un rond vert est relevé, le robot devra ralentir
son allure.
Cahier des charges
Pour parvenir à ce système, l’objectif est de s’assurer que les composants qui traiteront les images
puissent être performants tout en étant évolutifs pour d’éventuels futurs algorithmes.
Le principe sera d’obtenir une image et de l’afficher sur un écran pour observer le résultat de
l’acquisition et l’effet des traitements sur cette image.
Ce système devra au moins posséder :
-
Un ARM
Un FPGA
Une caméra
La caméra sera chargée bien entendu de capturer un flux d’image et devra être configurée pour
fournir les données sur 8 bits sous le format RGB qui est le plus facile à gérer.
Le processeur ARM aura la charge de configurer la caméra à travers le protocole I2C et devra
également afficher l’image reçu sur un écran TFT/LCD.
Enfin, le FPGA aura pour rôle de récupérer l’image fourni par la caméra, d’appliquer les divers
algorithmes sur l’image reçu et d’envoyer le résultat vers le ARM via une liaison série.
On en déduit le schéma fonctionnel suivant :
Caméra
I2C
Choix des composants
Caméra ov6620
La caméra c3088 à base d’un capteur ov6620 de OmniVision fera
office de capture d’image. C’est un composant relativement
simple à mettre en place qui requière d’être configuré via le
protocole I2C. La sortie de cette caméra peut être réglée en 8 ou
16bits avec le format YCrBr ou RGB Raw.
ARM SCB2440-III
Le ARM choisi sera un ARM9 SBC 2440 de samsung. Pour faciliter sa prise en main, il a été décidé de
prendre également un kit de développement fournit par la société Embest. Ce kit est composé d’une
carte fille qui comprend le ARM9 et l’accompagne
de mémoires SDRAM 64MB qui pourront être
utiles si l’on veut stocker plusieurs images. Le choix
de ce processeur est justifié par le fait que l’INSSET
possède déjà ce matériel et qu’il correspond tout à
fait à nos besoins en plus d’alléger le coût de notre
projet.
Ce module sera monté sur la carte de
développement qui offre de nombreuses
fonctionnalités : USB, 2x RS232, connecteurs LCD
et caméra, prise RJ-45.
Son seul inconvéniant est que la carte ne possède
aucun port d’extension I/O. Nous le verrons plus
tard mais cela oblige à utiliser le port RS232 comme support de
FPGA Spartan 3
Le FPGA Spartan 3 de Xilinx permettra l’acquisition des images générées par la caméra, appliquera
différents algorithmes pour repérer les formes sur cette image et enfin enverra l’image traitée vers le
ARM9 via une liaison série RS232.
Comme précédemment, le choix de ce composant
peut se justifier par, d’une part, que ce FPGA est
déjà utilisé par l’INSSET et d’autre part, que nous
l’utilisons à travers nos divers TP.
Comme de coutume, ce FPGA est accompagné
d’un kit de développement pour une meilleure
prise en main. On y retrouve des switch, des leds,
deux banques mémoires, des afficheurs 7
segments ou encore des ports d’extensions dont
certaines entrées/sorties sont reliées aux
composants de la carte (RAM, JTAG,..)
Seuls les ports RS232, les banques mémoires et les connecteurs externes I/O numériques seront
utilisées. Cependant, il est a noté que la RAM est adressée sur 18bits et les données sur 16bits.
L’utilisation des 2 octets de données étant relativement compliquée à exploiter et par manque de
temps, nous allons considérer que chaque adresse de la mémoire contiendra un pixel sur 8 bits (Ce
qui nous fait perdre 50% de la place mémoire). En d’autres termes il sera possible de stocker dans
une banque 2^18 pixels soit 262 144 pixels. Nous le verrons plus tard dans ce rapport mais ce
nombre est assez petit et que le stockage d’une image complète avec toute s ses composantes
couleurs sera un problème.
Organisation
Pour mener à bien ce projet, une équipe de 4 étudiants a été formée :
-
Le chef de projet : Damien Wallerand qui a partagé les tâches aux divers membres de
l’équipe, a su être à l’écoute et proposer des solutions.
- Dominique Bodziani : Sa mission fut prendre en main la caméra pour que le processeur
ARM puisse la configurer, de gérer l’écran LCD ainsi que la liaison série RS232 afin
d’afficher l’image envoyer par le FPGA
- Thomas Piquet : Il fut chargé mettre en œuvre la mémoire externe du FPGA et la mémoire
externe de l’ARM
- Moi-même : Pour ma part, Damien m’a demandé de m’occuper de l’acquisition de l’image
de la caméra, de faire un traitement sur celle-ci et de l’envoyer sur le port RS232.
Ceci pose maintenant les bases pour la suite de ce rapport. En effet, comme nous venons de le voir,
ma partie fut consacrée à l’utilisation exclusive du FPGA. C’est-à-dire qu’il m’a fallu trouver un code
VHDL pour récupérer les données de la caméra, les stocker dans la mémoire RAM, trouver un
algorithme dans une zone ciblée de l’image et enfin envoyer chaque pixel sur la liaison série.
Pour atteindre les objectifs qui m’ont été fixés, il a fallu procéder de manière méthodique et
pédagogique dans le sens où il faut d’abord maîtriser les bases (écrite RAM, RS232, navigation dans
l’image,…) pour ensuite assembler le tout. Cependant, ma partie repose sur l’utilisation de la RAM et
de la caméra. Or comme nous venons de le voir, ces 2 parties ont été attribuées aux autres étudiants.
Cela implique que je devais attendre que leurs objectifs soient validés pour pouvoir commencer
concrètement mes tâches. Cela a pour conséquence qu’une grande partie de mon travail est basée
sur de la simulation.
Voici les étapes suivies chronologi quement :
-
Générer un code permettant de simuler des images noir/blanc de la caméra.
Simuler le fonctionnement théorique de la mémoire
Stocker les données simulées de la caméra dans la mémoire.
Appliquer un traitement sur l’image stockée dans la mémoire et simulation
o A ce stade, Thomas avait validé l’utilisation de la mémoire RAM du FPGA
Le projet
La mémoire
La mémoire permettra de stocker les images provenant de la caméra. Ainsi, elles pourront être
consultables à tout moment dans le programme. Elle se situe au dos de la carte FPGA et comporte
une taille de 256K*16 bits et est de type RAM : un bus de 18 bits pour les adresses et un bus de 16
bits pour les données. De plus, elle fonctionne en mode asynchrone, c’est-à-dire qu’elle ne dépend
pas d’une horloge pour fonctionner. Sur le kit de développement, le nombre de banque mémoire est
de 2.
Son utilisation est relativement simple. En effet, en plus de ses bits d’adresses et de données, il faut
compter avec 2 bits pour la lecture et l’écriture ( OE et WE), deux bits pour les octets de poids
fort/faible (UB/LB) et enfin 1 bit pour l’activation de la mémoire (CE).
Voici un schéma qui illustre la communication entre la RAM et le FPGA et les bits de contrôle :
Il est a noté également que tous les bits de
contrôle sont à logique inversée : en d’autres
termes, pour activer une banque mémoire, il
faut appliquer un 0 logique à CE. De même pour
les autres bits (OE, WE, LB et UB).
En outre, il faut préciser que certains signaux
sont partagés entre les deux SRAM : c’est le cas
pour le bus d’adresse, OE et WE.
Pour finir sur la présentation de la mémoire du
kit de développement, le port d’extension A1 de
la carte est directement reliée à certains signaux.
On peut citer les bits OE et WE, les 8 bits de
poids faibles du bus de données et le bus
Comme nous l’avons précédemment expliqué, une grande partie de mon projet fut d’établir de
nombreuses simulations. Il m’a donc été nécessaire de modéliser la mémoire pour obtenir des
résultats le plus proches possibles de la réalité (comme si le programme était dans le FPGA). Pour
cela, j’ai dû décrire mon programme de manière structurel : un bloc qui contient le code principal ,
décrit de façon comportementale et un bloc modélisant la mémoire.
Voici schématiquement comment on peut se représenter la structure du code :
Programme
Programme
Mémoire
Principal
Le bloc mémoire sera constitué d’un simple tableau que l’on pourra écrire uniquement sous
certaines conditions : si WE = 0 et OE = 1 (logique inversée). De même pour la lecture, il faudra que
OE = 0 et WE = 1. Ne gérant pas les octets de poids fort ou de poids faible, on considère que les bits
LB et UB seront toujours à 0 (donc activé). Ce bloc sera utilisé tout le long des simulations à venir et
restera par conséquent inchangé .
En revanche, le bloc correspondant au programme principal évoluera selon les tests que l’on voudra
effectuer (de la simple prise en main de la mémoire jusqu’au programme final).
RS232
Cette partie de projet fut probablement la plus rapide à réaliser. En effet, par manque de temps, il a
été décidé de développer par moi-même le code pour gérer la liaison série fournit par la carte FPGA
plutôt que de reprendre le programme qui a déjà été conçu par les Master2. Cela apporte l’avantage
d’avoir un code maitrisé et donc plus facile à intégrer au programme principal. De plus, la complexité
du code à développer est assez peu élevée.
Les paramètres de la liaison série sont les suivants :
240300bauds/s – 8 bits de données – sans parité – 1 bits de stop
Il faut rappeler que la liaison servira de communication entre le FPGA et le ARM et enverra les
données traité es via ce bus. Bien entendu, seule la partie émission a été réalisée puisque le
processeur ARM n’enverra aucune information au FPGA.
La liaison série RS232 se présente sur la carte comme montré e sur la figure suivante :
Caméra
La gestion de la caméra a été le plus difficile à mettre en œuvre. C’est pourquoi nous allons
décomposer en plusieurs parties son utilisation : nous commencerons par présenter la caméra, puis
nous verrons comment les données sont envoyées et enfin comment ces données seront traitées
dans le FPGA.
Présentation de la caméra
La caméra utilisée est une C3088 qui n’est en fait qu’une lentille montée sur un capteur OV6620 de
Omnivision et fournit un PCB (Printed Circuit Board):
Cette caméra se contrôle via le protocole SBBC, bien que celui-ci reprend les mêmes normes que le
protocole I2C. La C3088 étant composée uniquement que du capteur CMOS ov6620, on pourra donc
faire l’amalgame entre ces deux objets.
Voici quelques caractéristiques de la caméra :
-
101,376 pixels
Résolution maximum de 356x292
Mode progressif ou entrelacé
Format de données : YCrCb / RGB Raw data
Gain
Balance des blancs
Synchronisation interne et externe.
Récupération des données
Pour pouvoir obtenir les données de la caméra et les traités correctement, il est crucial de savoir
comment celles-ci sont envoyées :
-
Sous quelle forme ?
A quel moment : quand peut-on savoir qu’une nouvelle image est envoyée ?
Sous quelle forme ?
Comme nous avons pu le voir dans le paragraphe précédent, les données seront envoyées sous le
format RGB Raw data. Cela signifie que les données envoyées par la caméra correspondent à la
manière dont le capteur est organisé. En effet, l’ov6620 utilise un filtre Bayer pour capturer une
image.
Le principe d’un filtre de Bayer est le suivant : le capteur est composé d’une multitude de photo-sites
de même nature. Cependant, on en déduire que l’image qui en résultera sera en nuance de gris. Pour
obtenir de la couleur, il suffit d’appliquer un filtre de couleur qui filtrera les composantes bleu, rouge
ou vert. Cela implique maintenant que les photo-sites restituent 3 informations. Grâce à ces couleurs
primaires obtenus, on peut maintenant obte nir une image au format RGB dit brut (Raw). La
disposition des photo-sites, associées à son filtre est la suivante :
On peut voir sur cette figure que le nombre de composantes vertes est 2 fois plus grand que les
Pour revenir à la restitution de l’image par la caméra, voici comment est envoyée l’image par la
datasheet de la caméra :
Le capteur envoi l’image ligne par ligne en suivant cette séquence : BGRG, où chaque composante est
sur 8 bits (B sur 8 bits, G sur 8 bits, etc …).
Par exemple pour la première ligne la séquence serait :
-
B11 – G12 – R22 – G21 – B13 – G14 – R24 – G23 … pour la première ligne.
B31 – G32 – R22 – G21 … pour la deuxième ligne.
On remarque que pour la deuxième ligne, certains pixels de la ligne précédente sont utilisés. Cela
signifie que le nombre de pixel reçu pour constituer une image ne sera pas de 356*292 mais
356*292*2.
Pour récupérer l’image entière, les données envoyées par la caméra sont stockées en FIFO dans la
mémoire. Pour simplifier le code et la compréhension, chaque pixel sera stocké sur l’octet de poids
faible de la mémoire, le poids fort ne sera pas utilisé.
A quel moment ?
Pour connaitre si les données envoyées par le capteur dont valider et savoir quand démarre une
nouvelle image, la caméra fournie plusieurs signaux de synchronisation. On trouve donc :
-
Vsync : passe à l’état haut pour indiquer le début d’une nouvelle image. Reste à
l’etat bas pendant l’envoi des pixels.
Href : un front montant indique le début d’une nouvelle ligne. Bien sûr, un front
descendant montre la fin de celle-ci.
PCLK : La période de ce signal ne change pas quelques soit les valeurs des signaux
Vsync et Href. Pourtant, lorsque Href est à 1 et au front montant de PCLK, cela indique
que les données envoyées sont valides et donnent la valeur du pixel.
Voici un chronogramme pour un exemple plus concret :
Ne travaillant que sur des données de 8 bits dans notre cas, le signal UV[7 :0] ne doit pas être pris en
compte. Il faut également préciser que les valeurs FODD (pour le mode entrelacé) n’ont aucune
Voici une simulation montrant les différents signaux et les pixels sauvegardées dans la mémoire :
Sur cette impression d’écran, on voit très bien que l’acquisition se fait après le Vsync et que la
mémoire (MEM) commence à sauvegarder les données de la caméra (DATA_CAM) une fois que
HREF = 1.
Cependant et malgré le fait que la simulation semble correspondre tout à fait à ce que la caméra
émet comme signaux, dans la pratique, l’image final qui ressort semble confirmer le fait que
l’acquisition se fait à n’importe quel moment. Ce qui donne une image coupée horizontalement en
deux et dont le bas devrait être en haut. De plus, l’endroit où la coupure est située est aléatoire.
Traitement sur les données
Nous l’avons vu au début de ce rapport, l’objectif de ce projet est de déterminer la forme et la
couleur des objets qui se trouvent face au robot. Nous avons également vu que les données fournies
par la caméra n’étaient pas directement exploitables puisqu’elles supprime nt la notion de couleur.
Par manque de temps, seul le traitement pour reconstituer l’image en couleur a été effectuée. Pour
déterminer la couleur d’un objet ou pourra s’imaginer un traitement très simple.
Reconstitution de l’image :
A partir de ce point, nous allons supposer que l’image est entièrement enregistrée dans la mémoire.
Nous avons vu que le capteur envoyait une séquence de BG1RG2 sur chaque ligne et que pour la
deuxième ligne, on reprenait certains pixels de la première ligne. On peut donc supprimer 2
composantes et sur les 4 pixels envoyés, n’en garder que 2. Cela signifie que pour « 4 pixels réels »,
on les convertira en « 2 pixels images ».
Avant de continuer l’explication, voici une illustration de la transformation :
Comme on peut le voir, l’idée est de garder les composantes rouges et bleues mais de faire une
distinction avec la composante verte.
Le but est donc de prendre un paquet de 4 pixels de la mémoire, d’obtenir 2 pixels images et de les
envoyés directement sur le port série.
Traitement de l’image :
Seul un type de traitement a été étudié et appliqué sur l’image fournie par la caméra. Ce traitement
consiste simplement à faire un seuillage sur une des 3 composantes d’un pixel. Pour ce faire, l’idée
est la suivante : on regarde si la somme des 3 composantes est inférieure à 3 fois la composante que
l’on veut garder. Si c’est le cas, on place la valeur de 255 sur la composante que l’on veut faire
ressortir et on met à 0 les autres.
Exemple : On souhaite faire ressortir le bleu dans l’image.
Si
3* B > R + G + B
alors B = 255 et r=G=0
Sinon on ne touche pas aux composantes du pixel.
Remarque : Il est important de préciser que la division n’est pas directement synthétisable par le
FPGA. Elle ne peut être utilisée uniquement si l’on divise des entiers qui sont des multiples de 2^n
(qui se traduit pas de simples décalages).
Le programme
Le programme VHDL implanté dans le FPGA est décomposé en 2 parties mais regroupé dans un
même process : la première s’occupe de la récupération des données de la caméra et place le pixel
obtenu dans la mémoire. La deuxième partie récupère par bloc de 4 pixels l’image, ces pixels sont
ensuite reconstitués dans le format RGB, subissent un traitement quelconque et sont envoyés sur le
port série.
Afin de pas surcharger ce rapport, aucun code ne sera présenté mais seulement le fonctionnement
global du programme. Les commentaires laissés dans le fichier VHD détailleront au mieux les
algorithmes utilisés.
1ère partie :
Cette phase s’exécute uniquement sur les fronts montant de PCLK. En d’autres termes, le code qui
suit dépend de l’horloge de la caméra.
1ère étape :
- On initialise les variables utiles
- On indique que l’on souhaite obtenir une nouvelle image
2ème étape :
- On commence à récupérer l’image lorsque x fronts de VSYNC ont été sautés
- On commence à acquérir les pixels à partir du deuxième HREF
- On compte le nombre de pixel
3ième étape :
- Si le nombre de pixel attendu est atteint, on passe à la deuxième partie.
- Sinon on reste dans l’étape 2.
2ième partie :
Cette seconde phase du programme est contrôlée par l’horloge du FPGA afin d’effectuer les
traitements aussi rapidement que possible et d’évite r d’être synchronisé sur une horloge externe
non fiable (PCLK connecté via le port I/O).
Cette partie est orchestrée par une machine à état où chacun d‘entre eux (les états) va s’occuper
d’une tâche bien précise :
Etat 000 :
-
Les variables sont toutes mi sent à leur valeur par défaut.
Les signaux correspondants à l’adresse et aux données de la mémoire sont mis en haute
impédance afin que la mémoire puisse « switcher » de l’état écriture à celui de lecture.
Etat 001 :
-
On prépare la 1ère adresse pour récupérer le pixel de coordonnées p(0,0)
Etat 010 :
-
Récupération d’un bloc de 4 pixels
Récupération dans un tableau nommé RGB
Etat 011 :
-
Application d’un traitement (ici seuillage) sur une zone ciblée
Etat 100 :
-
Envoi des pixels dans l’ordre sur le port série : BG1RG2 -> RG1B, RG2B
Incrémentation des X et Y pour « repérage » dans l’image et utile pour le traitement
Lorsque l’image est envoyée, on envoie un pixel de valeur 0 pour indiquer la fin de
l’envoi au ARM
Connexion entre la caméra et la carte FPGA
Nous avons vu dans les chapitres précédents que la caméra doit fournir 11 signaux pour envoyer une
image complète (Données sur 8 bits + HREF + VSYNC + PCLK). Sachant cela, on peut en déduire que
seul les ports d’extensions A2 et B1 offrent assez de d’I/O contrairement au port A1 réservé au
contrôle de la RAM. Par souci de confort, le port A2 a été choisi car il est juste en face de la carte
ARM. Le port B1 sera tout de même utilisé pour observer les signaux VSYNC, HREF et PCLK reçus par
le FPGA pour éviter que l’oscilloscope perturbe le fonctionnement de la caméra.
Voici un tableau récapitulatif des I/O du port d’extension A2 :
Caméra
Y0
Y1
Y2
Y3
Y4
Y5
Y6
Y7
HREF
VSYNC
PCLK
Carte FPGA
port I/O
FPGA
5
D5
6
C5
7
D6
8
C6
9
E7
10
C7
11
D7
12
C8
18
A4
20
A5
22
B7
Pour le port d’extension B1 :
Carte FPGA
Etat actuel du projet
Le projet aujourd’hui est pratiquement terminé. En effet, comme nous l’avons au cours de ce
rapport, la partie communication entre le ARM et le FPGA est validée. Cependant, il faut garder à
l’esprit que la liaison série n’a été développé uniquement pour des raisons de test. La vitesse très
faible d’une liaison RS232 ne permet d’envoyer qu’une image toute les 14 secondes environ. Il faudra
prévoir dans l’avenir de la remplacer par une connexion parallèle beaucoup plus rapide pour arriver à
obtenir un débit d’image acceptable sur l’écran LCD.
L’image restituée sur le LCD est tout à fait lisible mis à part qu’elle est découpée en 2. En effet, et ce
de façon aléatoire, l’image est découpée en deux sur le plan des Y : une partie de l’image qui devrait
se trouver en haut se retrouve en bas. La zone de « découpe » est aléatoire : elle peut très bien se
situé sur le haut de l’image comme au milieu voir aucune.
Conclusion
Ce projet fut très intéressant puisqu’il m’a permis de comprendre que le traitement d’un flux vidéo
n’est pas si facile qu’il n’y parait et que le langage VHDL présente des subtilités qu’il faut apprendre à
maitriser.
Pour arriver au résultat obtenu, on peut citer de nombreux problèmes : notamment au niveau de la
CEM. En effet, le fait de raccourcir les fils entre la caméra et le FPGA ainsi que de supprimer le retour
des signaux de la caméra vers le processeur ARM a permis d’obtenir une image de bien meilleure
qualité.
Téléchargement