Deteccion y Seguimiento de Region Ocular para Mouse Control
Este es un proyecto Titulado EyeTracking desarrollado en OpenCV enfocado para la gente que presenta alguna discapacidad física , en donde el principal objetivo que tiene este sistema es poder controlar el sistema operativo de una computadora por medio de los movimientos corporales de la región ocular por medio de la detección de patrones como Rostros y Regiones oculares.
![]()
El proyecto aun está en su fase de desarrollo , terminado en un 80 % , los avances que sean desarrollados es la detección del rostro del usuario , la detección la parte ocular , el tracking de la región ocular y la interpretación de coordenadas , aunque este último presenta algunos problemas en la calibración de las resoluciones entre cámara web y resolución de la pantalla del PC.
-
// Librerias ...
-
#include "stdafx.h"
-
#include <stdio.h>
-
#include "cv.h"
-
#include "highgui.h"
-
-
#define TPL_WIDTH 25
-
#define TPL_HEIGHT 25
-
#define WINDOW_WIDTH 50
-
#define WINDOW_HEIGHT 50
-
#define THRESHOLD 0.3
-
-
// ++++++++++++++++++++++++++ Variables Globales ++++++++++++++++++++++++++++
-
-
// Cascada de Clasificacion de Rostros
-
CvHaarClassifierCascade *cascade_f;
-
CvHaarClassifierCascade *cascade_e;
-
-
// Almacenamiento de Memoria
-
CvMemStorage *storage;
-
CvRect *r;
-
-
// Variables para la construccion de imagenes.
-
IplImage *frame , *window , *tpl , *tm , *wimdow;
-
int is_tracking = 0, x = 0 , y = 0;
-
-
// Valores de posicion tpl
-
CvPoint minloc, maxloc;
-
double minval, maxval;
-
int object_x0 , object_y0;
-
-
// Variable para almacenamiento de resultados.
-
CvSeq* faces;
-
-
// Declaracion de Metodos
-
void detectFaces();
-
void Track();
-
// +++++++++++++++++++++++++++ Metodo Principal +++++++++++++++++++++++++++++
-
int main( int argc, char** argv ) {
-
// Inicializacion de Componentes --------------------------------------
-
-
// Archivos de cascada de caracteristicas para ...
-
char *file1 = "haarcascade_frontalface_alt.xml";
-
char *file2 = "haarcascade_eye.xml"; // Deteteccion de Ojos
-
-
// Cargar Clasificador de Rostros
-
cascade_f = (CvHaarClassifierCascade*)cvLoad(file1, 0, 0, 0);
-
cascade_e = (CvHaarClassifierCascade*)cvLoad(file2, 0, 0, 0);
-
-
// Inicializar el Modulo de Memoria, Necesario para el Detector de Rostros
-
storage = cvCreateMemStorage(0);
-
-
// Creamos una Ventana , con el nombre de "Video"
-
cvNamedWindow( "Video", CV_WINDOW_AUTOSIZE ); // Con el Tamaño Automatico del Video
-
cvNamedWindow( "Face", CV_WINDOW_AUTOSIZE ); // Con el Tamaño Automatico del Video
-
cvNamedWindow( "Eye", CV_WINDOW_AUTOSIZE ); // Con el Tamaño Automatico del Video
-
// Iniciamos el Dispositivo de Captura de Video ,
-
CvCapture* capture = cvCreateCameraCapture(0);
-
-
cvWaitKey(33);
-
-
frame = cvQueryFrame( capture );
-
if ( !frame ) return 1;
-
-
tpl = cvCreateImage( cvSize( TPL_WIDTH, TPL_HEIGHT ),
-
frame->depth, frame->nChannels );
-
-
-
tm = cvCreateImage( cvSize( WINDOW_WIDTH - TPL_WIDTH + 1,
-
WINDOW_HEIGHT - TPL_HEIGHT + 1 ),
-
IPL_DEPTH_32F, 1 );
-
-
-
//-----------------------------------------------------------------------
-
// Ciclo Infinito para poder optener imagenes en tiempo real.
-
-
-
while(1) {
-
frame = cvQueryFrame( capture ); // Obtenemos Frame desde el Buffer de Video
-
if( !frame ) break; // Si no Obtenemos Frame , Entonces Finalizamos el Ciclo
-
if (is_tracking) {
-
Track();
-
} else {
-
detectFaces();
-
}
-
cvShowImage( "Video", frame ); // Desplegamos la Imagen en Pantalla
-
// Esperamos 33 milesimas de Segundo , si el usuario presiona alguna Tecla
-
char c = cvWaitKey(33);
-
if( c == 27 ) break; // Si se Preciono la Tecla ESC entonces se rompe el Ciclo
-
}
-
// Liberar Memoria
-
cvReleaseImage( &frame );
-
cvDestroyWindow( "Video" );
-
} // fin del metodo principal
-
// ++++++++++++++++++++++++++++++++++++++
-
void detectFaces() {
-
-
// Creamos imagen region
-
IplImage *Region = cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels);
-
cvCopy(frame,Region,NULL);
-
-
-
//(1) Deteccion de rostros por medio del detector.
-
faces = cvHaarDetectObjects( frame, cascade_f, storage,
-
1.1, 3, 0, cvSize(40, 40) );
-
printf( "Rostros Encontrados : %i \n", faces->total );
-
-
-
-
if (faces->total> 0) {
-
//(2) Obtener Region del rostro.
-
r = (CvRect*)cvGetSeqElem(faces, 0);
-
printf( "Dimencion del Rostro Antes : w = %i , h = %i \n", r->width , r->height);
-
-
//(3) Dibujar un Rectangulo sobre el Rostro.
-
cvRectangle(Region,
-
cvPoint(r->x, r->y),
-
cvPoint(r->x + r->width, r->y + r->height),
-
CV_RGB(255, 0, 0), 1, 8, 0);
-
-
//(4) Modificar Imagen al tamaño del rostro
-
cvSetImageROI(frame,*r);
-
cvClearMemStorage(storage);
-
-
//(5) Salida de la posicion del rostro
-
printf( "Posicion Rostro (%i,%i) \n", r->x , r->y );
-
-
x = r->x;
-
y = r->y;
-
-
-
//(6) Deteccion de la region ocular
-
CvSeq* eyes = cvHaarDetectObjects(
-
frame, cascade_e, storage,
-
1.15, 3, 0, cvSize(25, 15));
-
-
//(7)Obtenemos region y pintamos region.
-
r = (CvRect*)cvGetSeqElem( eyes, 0 );
-
cvRectangle(frame,
-
cvPoint(r->x, r->y),
-
cvPoint(r->x + r->width, r->y + r->height),
-
CV_RGB(0, 0, 255), 2, 8, 0);
-
-
cvShowImage( "Eye", frame );
-
printf( "Posicion Eye (%i,%i) \n", r->x , r->y );
-
-
// Obtener coordenadas
-
x = x + r->x;
-
y = y + r->y;
-
-
printf( "Dimension del Region1 (%i,%i) \n", Region->width , Region->height );
-
printf( "Posicion de la region1 (%i,%i) \n", x , y );
-
// -------------------------------------------------------------------------------------
-
-
object_x0 = x;
-
object_y0 = y;
-
-
-
printf( "Posicion Mouse(%i,%i) \n", object_x0 , object_y0 );
-
-
cvSetImageROI( Region,
-
cvRect( object_x0,
-
object_y0,
-
TPL_WIDTH,
-
TPL_HEIGHT ) );
-
-
printf( "Dimension del Frame2 (%i,%i) \n", frame->width , frame->height );
-
cvCopy( Region, tpl, NULL );
-
cvShowImage("Face" , tpl);
-
-
fprintf( stdout, "Region Ocular encontrada. \n" );
-
-
// -------------------------------------------------------------------------------------
-
-
is_tracking = 1;
-
// Limpiamos Memoria
-
cvClearMemStorage(storage);
-
} else {
-
return;
-
} // fin del if
-
}
-
-
void Track() {
-
-
// Determinamos la posicion del puntero sobre la ventana principal.
-
int win_x0 = object_x0 - ( ( WINDOW_WIDTH - TPL_WIDTH ) / 2 );
-
int win_y0 = object_y0 - ( ( WINDOW_HEIGHT - TPL_HEIGHT ) / 2 );
-
-
//printf( "Posicion Track(%i,%i) \n", win_x0 , win_y0 );
-
-
SetCursorPos(frame->width - win_x0 , win_y0 );
-
if (win_x0> frame->width - WINDOW_WIDTH)
-
win_x0 = frame->width - WINDOW_WIDTH;
-
if (win_x0 <0)
-
win_x0 = 0;
-
if (win_y0 <0)
-
win_y0 = 0;
-
if (win_y0> frame->height - WINDOW_HEIGHT)
-
win_y0 = frame->height - WINDOW_HEIGHT;
-
-
// Buscamos Region en la ventana
-
cvSetImageROI( frame,
-
cvRect( win_x0,
-
win_y0,
-
WINDOW_WIDTH,
-
WINDOW_HEIGHT ) );
-
cvMatchTemplate( frame, tpl, tm, CV_TM_SQDIFF_NORMED );
-
cvMinMaxLoc( tm, &minval, &maxval, &minloc, &maxloc, 0 );
-
cvResetImageROI( frame );
-
-
// Si el objeto se encontro ...
-
if( minval <= THRESHOLD ) {
-
-
// Guardar posicion actual de la region objetivo
-
object_x0 = win_x0 + minloc.x;
-
object_y0 = win_y0 + minloc.y;
-
-
// Dibujamos region
-
cvRectangle( frame,
-
cvPoint( object_x0, object_y0 ),
-
cvPoint( object_x0 + TPL_WIDTH,
-
object_y0 + TPL_HEIGHT ),
-
cvScalar( 0, 0, 255, 0 ), 1, 0, 0 );
-
} else {
-
-
// De lo contrario desplegar mensaje ...
-
fprintf( stdout, "Objeto Perdido \n" );
-
is_tracking = 0;
-
}
-
}
Blog
Foro
Codes
Feed rss