IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenCV Discussion :

Exemple de code de traitement d'images d'une webcam


Sujet :

OpenCV

  1. #1
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    50
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 50
    Points : 74
    Points
    74
    Par défaut Exemple de code de traitement d'images d'une webcam
    Salut,

    J'ai un peu galèré sous OpenCv. Cela fait 15jours que je bosse dessus. Je me suis rendu compte qu'un certain nombre de personne posait des questions concernant les webcams et le traitement des images. Voici le petit bout de code auquel je suis parvenu apres de multiples essais. Un bonne base me semble-t-il pour débuter et ECHANGER. Source a compiler en C++ ( sinon, il faut remplacer le (void *) du callback par un &
    J'ai aussi optimisé la routine d'acces au pixel de la doc officielle, mais je suis loin d'être un "gourou" du C/C++. J'èspère que ceci sera amélioré par d'autres.

    Jean-Pierre
    ps: Il y a un test de vitesse et un affichage du nombre de frames. Utile pour l'optimisation. La résolution de la webcam est de 320*240

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    #include <cv.h>
    #include <highgui.h>
    #include <stdio.h>
    #include <cvcam.h>
    //
    int frame=0;
    uchar* pixel_ptr;
     
    void callback(IplImage* img)
    {
         int x,y;
         int iwd=img->widthStep;
         char *idt=img->imageData;
     
         double t1=cvGetTickCount( );
         frame++;
         for (x=0;x<320;x++)
         {
             for (y=0;y<240;y++)
             {
                 pixel_ptr  = &((uchar*)(idt + iwd*y))[x*3];
                 pixel_ptr[0] = 0; // Pixel Bleu
                 //pixel_ptr[1] = 0; // Pixel Vert
                 //pixel_ptr[2] = 0; // Pixel Rouge
                 //if (pixel_ptr[0] >100) pixel_ptr[0] = 0 ; // Petit traitement ;-)
             }
         }
     
        printf("Temps 1 %d %f \n",frame,cvGetTickCount( )-t1);
    }
     
    int main( int argc, char** argv )
    {
        int ncams = cvcamGetCamerasCount( );
        // 0 -> Première Webcam ou perih de capture trouvé
        cvcamSetProperty(0, CVCAM_PROP_ENABLE     , CVCAMTRUE);
        cvcamSetProperty(0, CVCAM_PROP_CALLBACK   ,(void *)callback);
     
        if( !cvcamInit() ) return 0;
        cvcamStart();
     
        cvWaitKey(0); // Un Wait ici. Le traitement est effectué en tache de fond
        cvcamStop();
        cvcamExit();
    }

    Edit : Deuxième version. Beaucoup plus rapide !!! 2,5 fois.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
     //
    #include <cv.h>
    #include <highgui.h>
    #include <stdio.h>
    #include <cvcam.h>
    //
    int frame=0;
    //
    void callback(IplImage* img)
    {
         int i,j,k,x,y;
         int iwd=img->widthStep;
         char *idt=img->imageData;
         int channels  = img->nChannels;
         double t1=cvGetTickCount( );
         frame++;
         for (x=0;x<320;x++)
         {
             for (y=0;y<240;y++)
             {
    	idt[y*iwd+x*channels]=0; // Pixel Bleu
    	//idt[y*iwd+x*channels+1]=0; // Pixel Vert
    	//idt[y*iwd+x*channels+2]=0; // Pixel Rouge
             }
         }
        printf("Temps 1 %d %f \n",frame,cvGetTickCount( )-t1);
    }
     
    int main( int argc, char** argv )
    {
        int ncams = cvcamGetCamerasCount( );
        cvcamSetProperty(0, CVCAM_PROP_ENABLE     , CVCAMTRUE);
        cvcamSetProperty(0, CVCAM_PROP_CALLBACK   ,(void *)callback);
     
        if( !cvcamInit() ) return 0;
        cvcamStart();
     
        cvWaitKey(0);
        cvcamStop();
        cvcamExit();
    }
    Edit 2 : Semble plus rapide pour un acces ligne par ligne ???.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    // OPTIMISEE POUR UN ACCESS LIGNE PAR LIGNE
    #include <cv.h>
    #include <highgui.h>
    #include <stdio.h>
    #include <cvcam.h>
    //
    int frame=0;
    uchar* pixel_ptr;
     
    void callback(IplImage* img)
    {
         int channels  = img->nChannels;
         int x,y,i,j;
         int ihei=img->height;
         int iwd=img->widthStep;
         double t1=cvGetTickCount( );
     
         frame++;
     
          for(i=0; i<ihei; i+=10)
          {
                   for(j=(iwd)*i; j<(iwd)*(i+1);   j+=channels)
                   {
                        img->imageData[j]   = 255;
                        //img->imageData[j+1] = 0;
                        //img->imageData[j+2] = 0;
                   } 
          }
        printf("Temps 1 %d %f \n",frame,cvGetTickCount( )-t1);
    }
     
    int main( int argc, char** argv )
    {
        int ncams = cvcamGetCamerasCount( );
        cvcamSetProperty(0, CVCAM_PROP_ENABLE     , CVCAMTRUE);
        cvcamSetProperty(0, CVCAM_PROP_CALLBACK   ,(void *)callback);
     
        if( !cvcamInit() ) return 0;
        cvcamStart();
     
        cvWaitKey(0);
        cvcamStop();
        cvcamExit();
    }

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 129
    Points : 68
    Points
    68
    Par défaut
    Hum,
    J'ai lu dans la doc ou sur le groupe yahoo que l'utilisation de call_back ne se faisait plus trop... Pourquoi utiliser callback()
    Quel est l'avantage de cette technique par rapport a un cvcapture ?
    Merci

  3. #3
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    50
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 50
    Points : 74
    Points
    74
    Par défaut
    Franchement, c'est tout a fait par hazard que je me suis "fixé" sur les routines de CVCAM. Le traitement par CallBack m'a semblé plus simple pour le "débutant" en C/C++ que je suis. Je n'ai pas fait de tests comparatifs de performance, mais développant parfois des wrappers pour d'autres langages (PowerBasic, Blitz3D, VB6...) l'usage de CVCAM et de la DLL associée me simplifie la tache. C'est un module autonome pour ce qui est de la capture (Cam et Avi).

    De plus, je suis du genre a nager a contre-courant sans le s'avoir...C'est mon destin

    Le traitement vidéo étant mon objectif final , s'il s'avère que CvCapture est plus performant ( et rien que plus performant), je m'y interresserai de près.

    Jean-Pierre.

    Edit : Un inconvénient sans doute de CVCAM : La fenêtre de visu toujours présente car créée par défault. . Il peut parfois être nécéssaire de faire :

    1) une capture
    2) un traitement
    3) une exploitation du résultat sans visualisation aucune.

    Il me semble que cela n'est pas possible avec CVCAM. En revanche, cvCapture le permet.

    Cette fonction aussi (cvGetCaptureProperty) manque parfois.

    Bref, si les performances sont identiques, passer de l'une a l'autre des méthodes me convient en fonction de la tâche a effectuer. Car le Callback..hum..j'aime. Un appel à chaque capture, sans se "prendre la tête" sur le timing.....

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 129
    Points : 68
    Points
    68
    Par défaut
    OK ca roule.
    Est-ce que par un pure hasard tu utilise du background subtraction ou background removal dans tes codes ? Si oui, utilises-tu la methode openCV c'est a dire Gaussian ou FGD ou alors autre chose ?
    Merci

  5. #5
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    50
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 50
    Points : 74
    Points
    74
    Par défaut
    "....background subtraction ou background removal dans tes codes ....."
    Non. Pour l'heure, j'en suis aux tests d'acces des pixels. Je tâte aussi du coté de l'assembleur pour plus de vitesse.
    De plus, Le moteur 3D de Blitz3D, de Physique de Ageia ( autre dada ) et leurs adaptations sous PowerBasic me prennent du temps.

    JP

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 129
    Points : 68
    Points
    68
    Par défaut
    Apres modification de la taille d'acqusition des images de ma camera les methodes openCV se sont revele tres efficaces : parfait pour une application temps reel.
    Bien cordialement.

  7. #7
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    50
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 50
    Points : 74
    Points
    74
    Par défaut
    Cela ne me surprend pas.
    Pour l'heure j'effectue tout mes tests (OpenCV, moteurs 3D et physique ) sur un portable Sempron 3000+ avec vidéo intégré( alors que ma machine de bureau est un C2D E6600 overclocké a 3.6Ghz...... ) L'usage du portable "m'oblige" a optimiser a fond. Et les résultats sont sympas.

    Jpierre

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Acquisition caméras
    Voila je me decide enfin a poster car j'ai une question a poser...

    J'aimerai faire de l'acquisition de plusieurs cameras en meme temps et je me demande ce qui est le plus performant, cvcam ou cvcapture?

    Le truc c'est que j'utilise cvcapture mais j'ai des soucis au niveau de l'acquisition car il me propose sans arret le choix de mes cams(laquelle je veux afficher) mais ca fini par planter...

    Quelqu'un aurait-il une solution que je puisse etudier ou peut-etre une indication sur quelles fonctions me pencher pour realiser cela?

    Merci d'avance!

  9. #9
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    50
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 50
    Points : 74
    Points
    74
    Par défaut
    Sans doute avec un bout de code comme celui la. Exemple pour l'init de 3 caméras. Il faudrait aussi 3 routines de callback pour la capture et le traitement. Les routines sonts appelées a chaque capture valide. C'est sans doute un cas ou la méthode des callbacks est la plus interréssante.

    JP

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        cvcamSetProperty(0, CVCAM_PROP_ENABLE     , CVCAMTRUE);
        cvcamSetProperty(0, CVCAM_PROP_CALLBACK   ,(void *)callback);
     
        cvcamSetProperty(1, CVCAM_PROP_ENABLE     , CVCAMTRUE);
        cvcamSetProperty(1, CVCAM_PROP_CALLBACK   ,(void *)callback_cam1);
     
        cvcamSetProperty(2, CVCAM_PROP_ENABLE     , CVCAMTRUE);
        cvcamSetProperty(2, CVCAM_PROP_CALLBACK   ,(void *)callback_cam2);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void callback(IplImage* img)
    {
       // Traitement cam 0
    }
     
    void callback_cam1(IplImage* img)
    {
       // Traitement cam 1
    }
    void callback_cam2(IplImage* img)
    {
       // Traitement cam 2
    }

Discussions similaires

  1. [Débutant] aide sur un code de traitement d'image
    Par kouabenan11 dans le forum Images
    Réponses: 8
    Dernier message: 01/07/2015, 10h41
  2. Traitement d'image depuis une applet
    Par guibsou dans le forum Applets
    Réponses: 2
    Dernier message: 03/07/2011, 18h02
  3. Traitement d'image avec une Webcam ?
    Par kyoleroi dans le forum LabVIEW
    Réponses: 3
    Dernier message: 18/04/2008, 11h17
  4. Réponses: 5
    Dernier message: 14/05/2006, 12h57
  5. Rechercher une ligne vide
    Par nico-pyright(c) dans le forum Traitement d'images
    Réponses: 7
    Dernier message: 22/12/2005, 17h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo