Vous êtes sur la page 1sur 5

1

ESIEE Paris
EL5E13/ R. Kachouri

Vision et traitement d'images embarqu
TP 3&4 Lire et traiter le flux dune Webcam avec
OpenCV
EL5E13_2012-2013

1. Introduction
1.1 Objectif
Lobjectif de ce TP est de prendre en main la librairie gnrale (OpenCV) de traitement dimage :
Lire et traiter le flux dune Webcam avec OpenCV
Appliquer les comptences en langage C
Programmer certains oprateurs de traitement d'image avec OpenCV
1.2 OpenCV
OpenCV est une librairie de traitement dimage qui offre un bon ventail de fonctions intgres
et puissantes. Une description dtaille de ces fonctions est disponible en ligne ladresse
suivante : http://opencv.willowgarage.com/documentation/index.html
Dans ce TP nous allons rcuprer le flux vido dune webcam tout en analysant chaque
commande pour bien comprendre leur utilit.
1.3 Ouvrir le flux dune vido / Webcam / camra
Avant de pouvoir lire un quelconque flux vido il faut dj louvrir. Dfinissez premirement la
variable qui va stocker ce flux :
CvCapture *capture;
1.3.1 Ouvrir une vido
Ouvrir une vido est chose relativement aise.
capture = cvCreateFileCapture("/chemin/de/votre/vido/test.avi");
1.3.2 Ouvrir le flux dune Webcam / Camra
De manire gnrale il est facile de lire le flux dune webcam. Si vous souhaitez utiliser une
camra analogique (non numrique) il vous faudra probablement utiliser un convertisseur pour
pouvoir la brancher en USB sur votre ordinateur.
capture = cvCreateCameraCapture( CV_CAP_ANY );
Le paramtre dans cvCreateCameraCapture() permet de dfinir quel flux vido rcuprer.
Gnralement le CV_CAP_ANY permet de prendre le premier disponible (donc par exemple
une webcam intgre votre ordinateur). Si vous avez plusieurs flux vido, la valeur 0 permet
de prendre le premier disponible. Les valeurs diffrent ensuite selon le port usb utilis.
2

ESIEE Paris
EL5E13/ R. Kachouri

1.3.3 Vrifier que le flux est bien ouvert
Il est possible quouvrir le flux vido ne se passe pas comme prvu. Pour pallier ce problme,
il est fortement conseill de raliser une petite vrification sur la variable capture .
if (!capture) {
printf("Ouverture du flux vido impossible !\n");
return 1;
}
Pour amliorer la vrification vous pourriez mme retenter louverture du flux X fois jusqu
dcider darrter (pour viter une boucle infinie). En effet dans certains cas, la webcam/camra
nest pas dtecte immdiatement.
1.4 Rcuprer une image et lafficher
Le principe du traitement vido est de procder une analyse du flux image par image. A
chaque traitement dimage termin vous affichez limage rsultante dans une fentre.
1.4.1 Crer une fentre
Ce qui est bien avec OpenCV cest que la cration dune fentre ne change pas en fonction du
systme dexploitation. Par ailleurs vous pouvez crer plusieurs fentres pour afficher dedans
plusieurs rsultats (images ou vidos). Une fentre est dfinie par un nom :
cvNamedWindow("Original", CV_WINDOW_AUTOSIZE);
Le flag CV_WINDOW_AUTOSIZE (qui est en fait un nombre entier : 0 ou 1) permet dindiquer
si la fentre doit sadapter automatiquement ou non.
1.4.2 Rcuprer une image
Une image est stocke dans une classe spcifique OpenCV : IplImage. Donc quelque part dans
votre code avant de commencer vous devez la dfinir :
IplImage *image;
Il existe deux faons de rcuprer une image du flux vido. La plus utilise est la suivante :
image = cvQueryFrame(capture);
Il faut indiquer en paramtre le flux vido utiliser pour rcuprer limage. Cela devient vital
dans le cas o vous utilisez plusieurs sources de vido !
1.4.3 Afficher une image
Une fois limage stocke dans une variable, il suffit de lafficher dans une fentre pralablement
cre.
cvShowImage("Original", image);
Notez quen gnral, avant dafficher limage, on peut effectuer des traitements sur cette
dernire. Prenez en compte que la communaut dOpenCV offre de nombreux codes en exemple.
1.5 Boucler et temporiser
Pour rcuprer les images petit petit il vous faudra crer une boucle et faire une petite pause
entre chaque image.
3

ESIEE Paris
EL5E13/ R. Kachouri

1.5.1 Faire une pause
Faire une pause dans OpenCV permet en mme temps de rcuprer une interaction clavier. Cela
permet ainsi danalyser la touche qui a subie une interaction et de procder certaines actions en
consquence.
key = cvWaitKey(10);
La commande cvWaitKey() assure une attente de X ms et renvoie linteraction clavier (sil y en a
eu une). Le temps dattente varie en fonction du framerate que vous souhaitez imposer (ici 10
ms). Par contre vous ne pourrez pas aller au-del de ce que propose votre camra. Notez par
ailleurs que mettre un temps dattente trop court peut causer un freeze plantage informatique
sur certaines versions de Linux. Mettez donc en gnral au moins 5 ms.
1.5.2 Faire une boucle
Et enfin il vous faut assembler tous les aspects prsents ci-dessus pour lire et afficher la vido.
Ici nous nous basons sur linteraction clavier pour arrter la boucle while .
// Boucle tant que l'utilisateur n'appuie pas sur la touche q (ou Q)
while(key != 'q' && key != 'Q') {
// On rcupre une image
image = cvQueryFrame(capture);
// On affiche l'image dans une fentre
cvShowImage("Original", image);
// On attend 10ms
key = cvWaitKey(10);
}
1.6 Librer la mmoire utilise
Etape trs (trs) importante, librer toute la mmoire que vous avez utilis en crant ces divers
objets.
1.6.1 Librer la fentre
Une seule fonction suffit fermer toutes les fentres :
cvDestroyAllWindows();
Toutefois dans le cas o vous ne souhaiteriez que fermer une seule et unique fentre, vous
pouvez utiliser cette dernire :
cvDestroyWindow("Original");
1.6.2 Librer la variable dimage
Lorsque vous rcuprez une image dun flux vido vous navez pas besoin de la librer dans
la boucle while, ni mme aprs. OpenCV gre ceci automatiquement et vous navez qu votre
charge de dsallouer une image cre par vos soins :
uneAutreImage = cvLoadImage("/chemin/de/votre/image/test.png",iscolor);
Le flag iscolor (qui est en fait un nombre entier : -1, 0 ou 1) permet de spcifier le type de
couleur de limage charge (iscolor > 0 l'image charge est forc d'tre une image couleur 3-
canal, iscolor = 0 l'image charge est forc d'tre une image niveaux de gris et iscolor < 0
l'image est charge telle quelle est.
Si vous veniez le faire, pensez donc faire ceci :
cvReleaseImage(&uneAutreImage);
4

ESIEE Paris
EL5E13/ R. Kachouri

1.6.3 Librer la capture vido !
Et enfin, il vous faut librer la capture vido (entre autre pour que la webcam/camra ne soit
plus utilise par le programme).
cvReleaseCapture(&capture);
1.7 Prparation
Avant de commencer il faut crer votre rpertoire de travail dans c:\temp de votre machine.
Vous n'oublierez pas de nettoyer ce rpertoire la fin de chaque TP aprs en avoir effectu une
sauvegarde sur votre compte.
Note : il n'est pas possible MS Visual Studio C++ 2010 d'accder correctement votre compte
c'est pourquoi il faut toujours travailler sur le rpertoire local c:\temp .
2. Traitement d'images
2.1 Mise en uvre du TP
1. Ouvrez une session sous Windows ; dans un rpertoire de votre choix, tlcharger les
fichiers sources dans larchive tp.rar du TP : http://www.esiee.fr/~kachourr/
2. Dcompressez larchive, il contient un projet Visual Studio C++ 2010. Ce projet est dj
paramtr pour utilisation de la librairie OpenCV.
3. Dans le rpertoire tp, cliquer sur tp.sln ce qui va ouvrir le projet en Visual Studio C++
2010. Ouvrer le fichier sources tp.cpp, il contient :
a. Les appels des fonctions pour la lecture du flux vido dune webcam ; les allocations
des images ; les appels des fonctions pour afficher des images dans des fentres
graphiques.
b. Inversion de limage commente : aprs la lecture, limage dentre est inverse et
crite dans limage de sortie laide des pointeurs data_in et data_out .

for(i=0;i<height;i++)
for(j=0;j<width;j++)
for(k=0;k<channels;k++)
{data_bg[i*step+j*channels+k]=255-
data[i*step+j*channels+k];}

4. Prise en main de lenvironnement
a. Sans dcommenter cette partie, cliquez sur le menu Gnrer et rgnrez la solution
aprs cliquer sur Dboguer et choisissez Dmarrez le dbogage . Le programme devrait se
lancer. Le programme sarrte en appuyant sur la touche q ou Q.
b. Si vous avez russi ltape 4-a ; vous pouvez dcommenter la partie de linversion de
limage et rgnrer la solution et lancer nouveau lapplication. Vous devriez voir limage
dentre dans une fentre et limage inverse dans une deuxime fentre.
5

ESIEE Paris
EL5E13/ R. Kachouri

2.2 Ralisation des oprateurs de traitement dimage
Conseil : pour la programmation, inspirez-vous de lexemple de linversion dimage, regardez
bien comment sont alloues et dclares des images, quel type de variable est utilis pour
reprsenter un pixel.
Remarque : lacquisition se fait en RGB.

1. Programmez la conversion RGB niveau de gris (Gris) et affichez le rsultat :
Gris = 0.3*R + 0.59*G + 0.11*B;
Avec, R = data_in[ i * step + j * channels + 0];
La dclaration dun nouveau pointeur image img_gray est ncessaire ainsi
quune nouvelle fentre daffichage. Pour la cration de limage niveaux de gris
img_gray , le code suivant est utilis :
img_gray = cvCreateImage(cvSize(img_in->width, img_in->height),
IPL_DEPTH_8U, 1);
La taille en octets dune ligne de limage niveaux de gris img_gray , est
calcul comme suit : step_gray = img_gray->widthStep/sizeof(uchar);
Linitialisation du pointeur donne de limage niveaux de gris img_gray , est
ralise comme suit : data_gray = (uchar *) img_gray->imageData;

2. Vrifiez le rsultat obtenu dans 1. laide de la fonction OpenCV prdfinie :
cvCvtColor(img_in, img_gray, CV_RGB2GRAY);

3. Programmez la conversion de limage niveaux de gris, obtenue au choix dans 1. ou
2., en une image binaire et affichez le rsultat.
Avec, data_bin[ i * step_gray + j ] = (Gris > 128) ? 255 : 0;
Sachant que data_bin est le champ imageData du pointeur image
img_bin ( dclarer pour contenir limage binaire rsultat).

4. Appliquez le filtre moyenneur et median sur limage niveaux de gris img_gray ,
ainsi quune rosion et une dilatation sur limage binaire img_bin et affichez
les rsultats obtenus dans deux fentres diffrentes. Les fonctions OpenCV
suivantes seront utilises :
cvSmooth( img_gray, out1, CV_BLUR, 7, 7 );
cvSmooth( img_gray, out2, CV_MEDIAN, 7, 7 );
cvErode( img_bin, out3, NULL, 1);
cvDilate( img_bin, out4, NULL, 1);
Avec, out1 , out2 , out3 , et out4 , sont des pointeurs images
dclarer.

5. En sappuyant sur les rsultats obtenus dans 4., calculez et affichez les images
ouverture et fermeture de limage binaire img_bin . Expliquez la diffrence
entre ces deux images.