Commit 10b6b9e07b699e3a57eb738db9c274de82fc6984

Authored by dtillaux
0 parents

push

Showing 4 changed files with 167 additions and 0 deletions   Show diff stats
Compte_rendu.md 0 → 100644
  1 +++ a/Compte_rendu.md
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +Compte rendu TP IHM Tillaux Damien
  2 +
  3 +Date de rendu d'après le tableau des modalités 4 mai
  4 +
  5 +Ce mini TP avait pour principe de réaliser le controle le curseur d'un ordi avec l'orientation de la tête. Dans un premier temps nous devons détecter un visage via la webcam. Grâce à openCV nous pouvons réaliser cela rapidement mais avec quelque limite: le programme detecte souvent d'autre visage qui n'en sont pas .
  6 +
  7 +Pour limiter au visage exploitable nous allons sélectionner le visage où openCV détecte 2 yeux. Cela va nous servir dans la suite pour l'orientation de la tête.
  8 +
  9 +Pour maintenant contrôler le déplacement vers la gauche ou la droite du curseur nous allons regarder la diffrence de hauteur des yeux détectés précedement. Passé une certainne limite de différence de hauteur nous pouvons déduir que l'utilisateur veut déplacer le curseur vers la gauche ou la droite. Maintenant pour le déplacement du curseur vers le haut ou le bas est un autre problème. Il n'existe pas avec openCV de manière de réaliser la différenciation de hauteur de la tête pour n'importe quelle configuration. J'ai alors trouvé une manière de faire qui posède quelque limite. Pour cela je regarde la différence de autre entre le centre du visage et la hauteur moyenne des 2 yeux s'ils ne sont pas penchés. J'ai alors trouvé expérimentalement 2 valeurs qui permettent de différencier si la tête regarde vers le haut ou le bas.
  10 +Le problème d'avoir toutes ces valeurs qui permettant de dire comment se trouve la tête de l'utilisateur, est que l'utilisateur doit se trouver à une certainne distance du la webcam pour que cela fonctionne normalement. Sinon le programme ne fonctionnera pas ou fonctionnera trop vite.
  11 +
  12 +Les limites d'openCV: la détections du visage et des yeux sont très compliqué et passé une certainne inclinaison de la tête les yeux ne sont plus détecté. Cela implique que nous ne pouvons pas inclure une vistesse de déplacement du curseur car nous ne pouvons pas savoir à quel moment openCV va décrocher.
  13 +Nous ne pouvons pas alors agir sur la vitesse de déplacement du curseur ce qui est un grand désavantage du cette technique. De plus nous ne pouvons pas avec openCV agir sur un déplacement du curseur autre que droite gauche haut bas.
0 \ No newline at end of file 14 \ No newline at end of file
compile.sh 0 → 100755
  1 +++ a/compile.sh
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +#bin/bash
  2 +g++ -I/home/damien/Documents/IHM/opencvfiles/include/opencv -I/home/damien/Documents/IHM/opencvfiles/include/ -L/home/damien/Documents/IHM/opencvfiles/lib -g -o tpIHM main.cpp -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_video -lopencv_contrib -lopencv_objdetect -lX11
  3 +
main.cpp 0 → 100644
  1 +++ a/main.cpp
@@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
  1 +#include "opencv2/opencv.hpp"
  2 +#include "opencv2/contrib/contrib.hpp"
  3 +#include "opencv2/objdetect/objdetect.hpp"
  4 +#include <X11/Xlib.h>
  5 +#include <iostream>
  6 +#include <unistd.h>
  7 +#include <stdio.h>
  8 +#include <string.h>
  9 +
  10 +using namespace cv;
  11 +
  12 +
  13 +
  14 +int main(int, char**)
  15 +{
  16 + //choisir l'ecran
  17 + Display* dpy = XOpenDisplay(0);
  18 + int scr = XDefaultScreen(dpy);
  19 + Window root_window = XRootWindow(dpy, scr);
  20 +
  21 + //calculer la taille et de l'ecran
  22 + int height = DisplayHeight(dpy, scr);
  23 + int width = DisplayWidth(dpy, scr);
  24 + std::cout << "Screen size : " << width << "x" << height << std::endl;
  25 +
  26 + //initialiser la position du curseur au milieu de l'écran
  27 + int sx,sy;
  28 + sx=width/2; sy=height/2;
  29 +
  30 + vector<Mat> images;
  31 + vector<int> labels;
  32 +
  33 + CascadeClassifier face_cascade;
  34 + CascadeClassifier eye_cascade;
  35 + CascadeClassifier nose_cascade;
  36 +
  37 + if( !face_cascade.load("./haarcascade_frontalface_default.xml") ){ printf("--(!)Error loading\n"); return -1; };
  38 + if( !eye_cascade.load("./haarcascade_eye_tree_eyeglasses.xml")){ printf("--(!)Error loading\n"); return -1; };
  39 + if( !nose_cascade.load("./haarcascade_mcs_nose.xml")){ printf("--(!)Error loading\n"); return -1; };
  40 +
  41 +
  42 + CvCapture* capture;
  43 + capture = cvCaptureFromCAM( -1 );
  44 +
  45 + Mat grImage;
  46 + namedWindow("face",1);
  47 +
  48 + for(;;)
  49 + {
  50 + Mat frame;
  51 + frame = cvQueryFrame( capture );
  52 + //cap >> frame; // get a new frame from camera
  53 + cvtColor(frame, grImage, CV_BGR2GRAY);
  54 + equalizeHist( grImage, grImage );
  55 +
  56 + vector< Rect_<int> > faces;
  57 + //face_cascade.detectMultiScale(grImage, faces);
  58 +
  59 + face_cascade.detectMultiScale( grImage, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
  60 +
  61 + for(int i = 0; i < faces.size(); i++) {
  62 +
  63 + Point center_face ( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
  64 +
  65 + Rect face_i = faces[i];
  66 + rectangle(frame, face_i, CV_RGB(0, 255,0), 1);
  67 +
  68 + Mat faceROI = grImage( faces[i] );
  69 + std::vector<Rect> eyes;
  70 + std::vector<Rect> nose;
  71 +
  72 + eye_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
  73 + nose_cascade.detectMultiScale( faceROI, nose, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
  74 +
  75 + Point tab_eye[2];
  76 + if(eyes.size() == 2){
  77 + int radius;
  78 + for( size_t j = 0; j < eyes.size(); j++ ) {
  79 + Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 );
  80 + tab_eye[j] = center;
  81 + radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 );
  82 + //circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
  83 + }
  84 +
  85 + /*Point center_nose( faces[i].x + nose[0].x + nose[0].width*0.5, faces[i].y + nose[0].y + nose[0].height*0.5 );
  86 + int radius_nose = cvRound( (nose[0].width + nose[0].height)*0.25 );
  87 +
  88 + circle( frame, center_nose, radius_nose, Scalar( 255, 0, 0 ), 4, 8, 0 );*/
  89 +
  90 + Point right;
  91 + Point left;
  92 + if(tab_eye[0].x > tab_eye[1].x){
  93 + right = tab_eye[1];
  94 + left = tab_eye[0];
  95 + }
  96 + else{
  97 + right = tab_eye[0];
  98 + left = tab_eye[1];
  99 + }
  100 +
  101 + circle( frame, right, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
  102 + circle( frame, left, radius, Scalar( 0, 0, 255 ), 4, 8, 0 );
  103 +
  104 + int incli = 15;
  105 + int Spas = 10;
  106 +
  107 + if(right.y + incli < left.y){
  108 + //printf("penche à gauche\n");
  109 + sx = sx - Spas;
  110 + if(sx < 0){
  111 + sx = 0;
  112 + }
  113 + }
  114 + else if(left.y + incli < right.y){
  115 + //printf("penche à droite\n");
  116 + sx = sx + Spas;
  117 + if(sx > width){
  118 + sx = width;
  119 + }
  120 + }
  121 + else if((center_face.y - (left.y + right.y)/2) > 29){
  122 + //printf("bas\n");
  123 + sy = sy + Spas;
  124 + if( sy > height){
  125 + sy = height;
  126 + }
  127 + }
  128 + else if((center_face.y - (left.y + right.y)/2) < 23){
  129 + //printf("haut\n");
  130 + sy = sy - Spas;
  131 + if(sy < 0){
  132 + sy = 0;
  133 + }
  134 + }
  135 + XWarpPointer(dpy, None, root_window, 0, 0, 0, 0, sx, sy);
  136 + XFlush(dpy);
  137 + usleep(50);
  138 +
  139 + //printf("diff nose eye =%d\n",center_face.y - (left.y + right.y)/2);
  140 +
  141 + }
  142 +
  143 + }
  144 +
  145 +
  146 + imshow("face", frame);
  147 + if(waitKey(30) >= 0) break;
  148 + }
  149 +
  150 + return 0;
  151 +}
tpIHM 0 → 100755
No preview for this file type