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 :

Problème de détection du mouvement de la main ?


Sujet :

OpenCV

  1. #1
    Membre confirmé
    Inscrit en
    Mars 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 94
    Par défaut Problème de détection du mouvement de la main ?
    Bonjour,
    J’essaye d'écrire un programme qui lit les mouvement de la main via une webcam.
    En réalité j'ai deux problèmes :
    1- Je trouve du mal à bien détecter la main (convex points et defects points).
    2- J'ai aucune idée comment détecter les mouvement de la main. C'est à dire dans l'axe des x, y et z. Parce que mon but final et de faire bouger un objet 3D via les mouvement de la main.

    j'ai longuement cherché mais en vain.

    Une aide sera la bienvenue.

    Merci.

    Voilà mon code (sous ubuntu) :
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
     
    //g++ rot.cpp -o rot `pkg-config opencv --cflags --libs
     
    #include<opencv2/opencv.hpp>
     
    #include <opencv2/core/core.hpp>
    #include <opencv2/video/background_segm.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include<iostream>
    #include <sstream>
    #include<vector>
    //#include<algorithm>
    //#include <X11/Xlib.h>
    //#include <X11/Xutil.h>
     
    /// Function header
    void thresh_callback(int, void* );
     
     
    using namespace cv;
    using namespace std;
     
     
     
     
     
     
    //Ouvreture de la caméra par défaut.
    VideoCapture camera(0);
     
     
    /**/
    void lesFenetres(void)
    {
      namedWindow("La_camera",1);
      moveWindow("La_camera", 50, 50);
      //namedWindow("Traitement de la main",1
      namedWindow( "Lecture_de_la_main", CV_WINDOW_AUTOSIZE );
      moveWindow("Lecture_de_la_main", 700, 50);
    }
     
     
    /**/
    bool detectionDeLaCamera(void)
    {
      return camera.isOpened();
    }
     
     
     
    /**/
    Mat detecterContours(Mat img )
    {
      Mat resultatCanny;
      vector<vector<Point> > contours;
      vector<Vec4i> hierarchie;
      
      /// Détecter les bords de la main avec Canny
      Canny( img, resultatCanny, 100, 200, 3 );
      
      /// Trouver les contours de la main 
      findContours( resultatCanny, contours, hierarchie, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
      
      
      /// Trouver les points convexes (convex hull)
      /// et aussi les points concaves (defects points)
      vector<vector<Point> > pointsConvexe( contours.size() );
      vector<vector<int> > pointsConvexeI(contours.size());
      vector<vector<Vec4i> > convdefect(contours.size());
      
      for( int i = 0; i < contours.size(); i++ )
      {
        convexHull( Mat(contours[i]), pointsConvexe[i], false);
        convexHull( Mat(contours[i]), pointsConvexeI[i], false);        
        if(pointsConvexeI[i].size() > 3 )
          convexityDefects(contours[i],pointsConvexeI[i],convdefect[i]);
      }
      
      /// Dessiner les contours( en bleu) et les convex hull (en rouge)
      Mat dessiner = Mat::zeros( resultatCanny.size(), CV_8UC3 );
      for( int i = 0; i< contours.size(); i++ )
      {
        size_t count = contours[i].size();
        if( count <300 )
          continue;
        
        drawContours( dessiner, contours, i, Scalar(255,0,0), 1, 8, vector<Vec4i>(), 0, Point());
        drawContours( dessiner, pointsConvexe, i, Scalar(0,0,255), 1, 8, vector<Vec4i>(), 0, Point());
      }
      
      /// Dessiner les defects points (en verts)
      for( int i = 0; i< contours.size(); i++ )
      {
        size_t count = contours[i].size();
        if( count <300 )
          continue;
        
        vector<Vec4i>::iterator d=convdefect[i].begin();
        while( d!=convdefect[i].end() )
        {
          Vec4i& v=(*d);
          int startidx=v[0]; Point ptStart( contours[i][startidx] );
          int endidx=v[1]; Point ptEnd( contours[i][endidx] );
          int faridx=v[2]; Point ptFar( contours[i][faridx] );
          float depth = v[3] / 256;
          
          line( dessiner, ptStart, ptEnd, Scalar(0,255,0), 1 );
          line( dessiner, ptStart, ptFar, Scalar(0,255,0), 1 );
          line( dessiner, ptEnd, ptFar, Scalar(0,255,0), 1 );
          circle( dessiner, ptFar,   4, Scalar(0,255,0), 2 );
          d++;
        }
      }
      
      return dessiner;
    }
     
       
      
     
    /**/
    int DetecterMouvementDeLaMain(void)
    {
      Mat frame;
      Mat imageNuanceDeGris;
     
      Mat masqueAvantScene;
      Ptr<BackgroundSubtractor> pMOG2;
      pMOG2 = new BackgroundSubtractorMOG2();
     
      int toucheSortie;
      do
      {
        //lire les frames de la caméra
        camera >> frame;
     
        if (!frame.empty())
        {
          cvtColor(frame, imageNuanceDeGris, CV_BGR2GRAY);
          blur( imageNuanceDeGris, imageNuanceDeGris, Size(3,3) );
     
          /// Supprimer le fond (arrière plan)
          pMOG2->operator()(imageNuanceDeGris, masqueAvantScene);
     
          imshow("La_camera",frame);
     
     
           Mat lesContours = detecterContours(masqueAvantScene);
     
           /*
           Mat FusionImage;
           double alpha = 0.5; double beta;
           
           beta = ( 1.0 - alpha );
           
           addWeighted( frame, alpha, lesContours, beta, 0.0, FusionImage); */
     
           imshow("Lecture_de_la_main", lesContours);
        }
     
        /// Taper Echap (ESC) pour quitter
        toucheSortie = waitKey(1);
      }while(toucheSortie != 27);
     
      return 0;
    }
     
     
    int main(void)
    {
      //Test si l'ouverture s'est bien passée.
      if (!detectionDeLaCamera())
      {
        cout<<"Problémes de caméra !!"<<endl<<"Vérifiez si votre caméra est bien branchée."<<endl<<"Vérifiez si les pilotes sont installés."<<endl;
        return -1;
      }
     
      cout<<"La caméra est détètée..."<<endl;
     
      lesFenetres();
     
      DetecterMouvementDeLaMain();
     
      return 0;
    }

  2. #2
    Membre confirmé
    Inscrit en
    Mars 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 94
    Par défaut
    Bonjour,

    Objectif du programme : Manipuler un ojbet 3D sur l'écran de l'ordinateur avec le mouvement de la main capturé via une webcam.

    J'ai réussi à écrire un programme qui tracke le mouvement de la main.
    Le programme suit la main qui bouge devant la webcam et calcule les coordonnées (x,y) d'un point de la main sur l'écran.

    Mais, comme vous savez, la main bouge dans l'espace, donc le mouvement est dans un plan 3D.

    Il me reste à calculer le mouvement de la main dans l'espace.

    Il faut chercher les coordonnées (x,y,z).

    Ici j'ai deux question :
    1- Est-ce-que les coordonnées(x,y) du point déja calculé sont les même que celles de la main lorsqu'elle est en mouvement.

    2- Supposons qu'on trouve "x" et "y", comment peut-on calculer "z"

    J'ai googlisé et j'ai trouvé ce document :
    http://en.wikipedia.org/wiki/Pinhole_camera_model

    cette méthode suppose qu'on connaît les coordonnées (x1,x2) de mouvement de ma main dans l'espace. Et aussi le mouvement de la main sur l'écran (y1,y2) et aussi la distance "f" entre la main et la caméra.

    la formule est :
    (y1,y2) = f/z * (x1,x2)

    Merci pour vos aides et votre patience.

  3. #3
    Membre éprouvé
    Inscrit en
    Mai 2012
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2012
    Messages : 65
    Par défaut
    Pour pouvoir appliquer cette formule il te faut une mire de calibrage afin de pouvoir déterminer les coordonnées dans l'espace à l'aide des paramètres intrinsèques de la caméra.

    Une autre idée est de calculer la boite englobante de la main, puis de calculer son aire, si cette-dernière est inférieure à un certain seuil que tu auras fixé (ou alors tu fais un apprentissage au début de ton programme pour déterminer la taille), c'est que ta main s'est éloigné de la caméra et si elle est supérieure c'est le contraire.

    La première méthode est plus précise, mais plus longue et plus compliquée à mettre en place, la 2e est plus rapide mais peut donner des résultats pas très convaincants (c'est l'expérience qui parle).

  4. #4
    Membre confirmé
    Inscrit en
    Mars 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 94
    Par défaut
    Merci Danny-k pour cette idée.
    J'ai opté pour le même principe mais en travaillant avec le rayon du cercle qui englobe le contour.
    Si le rayon augmente alors l'objet avance, sinon il recule.

    Bon, je suis en face d'une autre problème, le waitKey ne réponde pas.

    voilà ce que j'ai lors j’exécute mon code :
    $./p
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    La caméra est détètée...
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    VIDIOC_QUERYMENU: Invalid argument
    ^C
    normalement lorsque je tape "ESC", le programme s'arrête, mais waitKey ne lit aucune touche. Je suis obligé de faire un Ctrl+C

    C'est réglé, il faut faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ............
    char toucheSortie;
     
    do
    {
    ........
    toucheSortie = waitKey(30);
     
      }while(toucheSortie != (char)27);

Discussions similaires

  1. Problème de détection de mon réseau WIFI
    Par yaboki dans le forum Hardware
    Réponses: 6
    Dernier message: 06/07/2006, 11h43
  2. problème de détection de boutons radios
    Par boss_gama dans le forum ASP
    Réponses: 2
    Dernier message: 14/06/2006, 11h49
  3. [UBUNTU] Problème de détection souris/clavier
    Par Merlin dans le forum Ubuntu
    Réponses: 4
    Dernier message: 19/04/2006, 19h23
  4. [FAQ]problème de détection réseau.
    Par mickael777 dans le forum MFC
    Réponses: 6
    Dernier message: 13/05/2005, 14h43
  5. Problème de détection de nouveau processeur
    Par zakfa dans le forum Composants
    Réponses: 12
    Dernier message: 24/01/2005, 17h09

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