TrackEye: Seguimiento en tiempo real de los ojos humanos utilizando una cámara web

 Los ojos son las características más importantes de la cara humana,así que el uso eficaz de los movimientos de los ojos como una técnica de comunicación en las interfaces de usuario a la computadora puede encontrar lugar en diversas áreas de aplicación.El seguimiento de los ojos y la información proporcionada por las características de los ojos tienen el potencial de convertirse en una interesante manera de comunicarse con un ordenador en un sistema de interacción persona-ordenador (HCI). Así que con esta motivación, el diseño de un software en tiempo real de seguimiento característica del ojo es el objetivo de este proyecto.

El propósito del proyecto lideraado por zafersavas,   y publicado en CodeProject es implementar un tiempo real eye tracker-función con las siguientes capacidades:

  • Cara en tiempo real el seguimiento con la escala y la rotación invariante
  • Seguimiento de las áreas de ojos individual
  • Seguimiento características oculares
  • Ojo dirección de la mirada hallazgo
  • Control remoto mediante movimientos oculares

La segunda versión de TrackEye soporta:

  • Dos algoritmos de detección de rostros diferentes: Haar Face Tracking y CAMSHIFT
  • Dos algoritmos de detección de ojos diferentes:  Análisis de Componentes Principales Adaptativo   y comparación de plantillas
  • Algoritmos de seguimiento pueden ser seleccionados por el usuario al comienzo del proceso a través de GUI.
  • Fuente de entrada seleccionable: Cámara Web o   Archivo de vídeo

 Tenga en cuenta que TrackEye fue escrito con OpenCV Biblioteca v3.1, así que asegúrese de usar durante la reconstrucción.

Instrucciones para ejecutar y reconstruir TrackEye

A continuación los links  del ejecutable  ,así como el codigo fuente para el seguimiento en tiempo real de los ojos humanos en las secuencias de vídeo de Interacción Persona-Ordenador utilizando una cámara web:
  • Descargar ejecutable – 2,51 MB
  • Descargar el código fuente – 199.24 KB

Instrucciones De Instalación

  1. Extraer archivo TrackEye_Executable.zip. Antes de ejecutar TrackEye_636.exe, copie los dos archivosSampleHUE.jpg y SampleEye.jpg a la carpeta C: \. Estos dos archivos se utilizan para los algoritmos CAMSHIFT y Plantilla-juego.
  2. No hay otros pasos a seguir por el usuario para ejecutar el software. No hay dependencias DLL como el software fue construido con las DLL estáticamente incluidos.

Ajustes por hacer para realizar una buena Seguimiento

Ajustes de Detección de la cara y de los ojos

Bajo TrackEye Menú -> Configuración de Tracker

  • Fuente de entrada: Video
  • Haga clic en Seleccionar archivo y seleccionar .. \ Avis \ sample.avi
  • Cara algoritmo de detección: Haar algoritmo de detección de rostros
  • Marque «Track también Eyes» checkBox
  • Ojo algoritmo de detección: Adaptativo PCA
  • Desactive la opción «Comprobar Diferencia»
  • Número de la base de datos de archivo: 8
  • Número de EigenEyes: 5
  • La distancia máxima permitida desde eyespace: 1200
  • Rostro ancho / ojo anchura plantilla: 0.3
  • ColorSpace tipo para utilizar durante PCA: CV_RGB2GRAY

Configuraciones para detección del Alumno

Compruebe «ojos de pista en los detalles» y luego seleccione «Detectar también pupilas». Haga clic en el botón «Parámetros de Ajuste»:

  • Introduzca «120» como el «Valor Umbral»
  • Haga clic en «Guardar configuración» y luego haga clic en «Cerrar»

Ajustes para la serpiente

Marque «Indique ojo límite utilizando serpientes activos». Haga clic en «Configuración de la serpiente» botón:

  • Seleccione ColorSpace de usar: CV_RGB2GRAY
  • Seleccione umbralización simple e introduzca 100 como el «Valor umbral»
  • Haga clic en «Guardar configuración» y luego haga clic en «Cerrar»

Fondo

Hasta ahora no ha habido mucho trabajo en la detección de ojos y antes de que el proyecto, los métodos anteriores se estudiaron cuidadosamente para determinar el método aplicado. Podemos clasificar los estudios relacionados con el ojo en dos categorías principales que se enumeran a continuación:

Enfoques basados ​​Equipo Especial

Este tipo de estudios de usar el equipo necesario que le dará una señal de algún tipo que es proporcional a la posición del ojo en la órbita. Varios métodos que están al día en uso son Electrooculografía, Infra-Rojo oculografía, esclerales bobinas de búsqueda. Estos métodos están completamente fuera de nuestro proyecto.

Imagen basada Enfoques

Los enfoques basados ​​en la imagen realizan detecciones ojo en las imágenes. La mayoría de los métodos basados ​​imagen tratar de detectar los ojos utilizando las características de los ojos. Los métodos utilizados hasta ahora son métodos basados ​​en el conocimiento, los métodos basados ​​en características (color, gradiente), sencilla comparación de plantillas, métodos de apariencia. Otro método interesante es «comparación de plantillas deformables», que se basa en la coincidencia de una plantilla geométrica ojo en una imagen del ojo, reduciendo al mínimo la energía del modelo geométrico.

Implementación de TrackEye

El proyecto ejecutado es en tres componentes:

  1. Detección de rostros: Realiza la detección de rostros invariante escala
  2. La detección de los ojos: Ambos ojos se detectan como resultado de este paso
  3. Extracción de características de los ojos: Características de los ojos se extraen al final de este paso

Detección De Rostro

Dos métodos diferentes se llevaron a cabo en el proyecto. Ellos son:

  1. Continuamente adaptativos Medios-Shift Algoritmo
  2. Método de detección de la cara Haar
Algoritmo de continuamente adaptativo Mean-Shift 

Adaptable Mean Shift algoritmo se utiliza para el seguimiento de rostros humanos y se basa en la técnica no paramétrica robusta para escalar gradientes de densidad de encontrar el modo (pico) de las distribuciones de probabilidad llamados el algoritmo medio turno. Como caras son rastreados en secuencias de vídeo, el algoritmo de cambio media se modifica para tratar con el problema de cambiar dinámicamente las distribuciones de probabilidad color. El diagrama de bloques del algoritmo se da a continuación:

Camshift Algoritmo

Haar-Cara Método de detección

El segundo algoritmo de detección de cara se basa en un clasificador de trabajo con características Haar-gusta (a saber, una cascada de clasificadores impulsado de trabajo con características Haar-similares). Primero de todo, se entrenó con unos pocos cientos de puntos de vista de muestra de una cara. Después de un clasificador está entrenado, que puede ser aplicado a una región de interés en una imagen de entrada. El clasificador emite una «1 «si la región es probable que muestran la cara y» 0 «en caso contrario. Para buscar el objeto en toda la imagen, se puede mover la ventana de búsqueda a través de la imagen y comprobar cada ubicación utilizando el clasificador. El clasificador está diseñado de modo que pueda ser fácilmente «cambiar de tamaño» con el fin de ser capaz de encontrar los objetos de interés en diferentes tamaños, lo que es más eficiente que cambiar el tamaño de la imagen en sí.

Detección de ojos

Dos métodos diferentes se llevaron a cabo en el proyecto:

  1. Plantilla de emparejamiento
  2. Adaptable EigenEye Método
Plantilla de emparejamiento

Plantilla-Matching es un método bien conocido para la detección de objetos. En nuestro método de correspondencia de plantilla, se crea un patrón de ojo norma manualmente y se le dio una imagen de entrada, los valores de correlación con los patrones estándar se calculan para los ojos. La existencia de un ojo se determina basándose en los valores de correlación. Este enfoque tiene la ventaja de ser simple de implementar.Sin embargo, a veces puede ser inadecuada para la detección del ojo ya que no puede tratar eficazmente con la variación en escala, pose y forma.

Método Adaptativo EigenEye

Adaptable EigenEye método se basa en el método conocidos EigenFaces . Sin embargo, como el método se utiliza para la detección de ojos lo nombramos como » EigenEye Método «. La idea principal es descomponer imágenes del ojo en un pequeño conjunto de características incluyen imágenes llamadas eigeneyes, que pueden ser considerados como los principales componentes de las imágenes originales. Estos eigeneyes funcionan como los vectores de la base ortogonal de un subespacio llamados eyespace. Sin embargo, sabemos que laeigenface método no es escalar invariante. Para proporcionar la invariancia de escala podemos cambiar el tamaño de la base de datos de los ojos una vez con la información obtenida por el algoritmo de detección de rostros ( EyeWidth / FaceWidth ? 0 . 35 ), podemos proporcionar una detección escala invariante utilizando sólo una base de datos.

Funciones OpenCV para el seguimiento de objetos y detección

OpenCV Biblioteca ofrece una gran cantidad de procesamiento de imágenes y de seguimiento de objetos y detección de bibliotecas. La función principal que se utiliza en estos proyectos y su uso se indican a continuación:

Código de ejemplo para el seguimiento Haar-Cara

  anular CTrackEyeDlg :: HaarFaceDetect (IplImage * img, CvBox2D * Facebox)
 {
     int escala = 2;
     IplImage * temp = cvCreateImage (cvSize (img-> ancho / 2, img-> Altura / 2), 8, 3);
     Pt1 CvPoint, pt2;
     int i;

     cvPyrDown (img, temperatura, CV_GAUSSIAN_5x5);
     WIN32 #ifdef
         cvFlip (temp, temp, 0);
     #terminara si
     cvClearMemStorage (almacenamiento);

     si (hid_cascade)
     {
         CvSeq * enfrenta = cvHaarDetectObjects (temp, hid_cascade, almacenamiento, 1. 2, 2,
                     CV_HAAR_DO_CANNY_PRUNING);

         NumOfHaarFaces = faces-> total;

         si (NumOfHaarFaces> 0)
         {
                 CvRect * r = (CvRect *) cvGetSeqElem (caras, 0, 0);
                 pt1.x = r-> x * escala;
                 pt2.x = (r-> x + r> ancho) * escala;
         WIN32 #ifdef
             pt1.y = img-> Altura - r-> escala y *;
             pt2.y = img-> Altura - (r> y + r> altura) * escala;
         #else
             pt1.y = r-> escala y *;
             pt2.y = (r> y + r> altura) * escala;
         #terminara si

         faceBox-> center.x = (float) (pt1.x + pt2.x) / 2 0.;
         faceBox-> center.y = (float) (pt1.y + pt2.y) / 2;
         faceBox-> Tamano.Width = (float) (pt2.x - pt1.x);
         faceBox-> size.height = (float) (pt1.y - pt2.y);
             }
     }
     cvShowImage ("Seguimiento", img);
     cvReleaseImage (y temporal);
 }

Código de ejemplo para CamShift Algoritmo

  // Las entradas para el algoritmo CamShift 
  IplImage * HUE = cvCreateImage (cvGetSize (SampleForHUE), IPL_DEPTH_8U, 1);
 extractHUE (SampleForHUE, HUE); // ** información HUE Extracto 

 int hist_size = 20;
 flotar rangos [] = {0, 180};
 flotar * pranges [] = {} rangos;
 hist = cvCreateHist (1, y hist_size, CV_HIST_ARRAY, pranges, 1);
 cvCalcHist (y HUE, hist); // Calcular el histograma de una parte HUE 

 hueFrame = cvCreateImage (cvGetSize (CameraFrame), IPL_DEPTH_8U, 1);
 backProject = cvCreateImage (cvGetSize (CameraFrame), IPL_DEPTH_8U, 1);
 extractHUE (CameraFrame, hueFrame);

 while (trackCONTROL! = 0)
 {
     extractHUE (CameraFrame, hueFrame);
     cvCalcBackProject (y hueFrame, backProject, hist); se forma // Probabilidad 
  // CvShowImage ("Tester2", backProject); 
  cvCamShift (backProject, SearchWin, cvTermCriteria (CV_TERMCRIT_EPS |
             CV_TERMCRIT_ITER, 15, 0 1), y un borrador, y Facebox).;
     SearchWin = comp.rect;
 }

Muestra Matching Plantilla Código

  // Coincidencia Plantilla para la detección de ojos 
  void Cara :: findEyes_TM (IplImage * faceImage, TrackingSettings * Ajustes)
 {
     CvSize faceSize;  faceSize = cvGetSize (faceImage);

     // Cargar plantilla de la base de datos de ojo 
  CString nomArchivo;
     // Nombre de la plantilla para el ojo izquierdo 
  fileName.Format ("% s \\% d.jpg ojo", Preferencias-> params-> DBdirectory, 0);
     IplImage * eyeImage_Left = cvLoadImage (nomArchivo, - 1);
     // Nombre de la plantilla para el ojo izquierdo 
  fileName.Format ("% s \\% d.jpg ojo", Preferencias-> params-> DBdirectory, 1);

     IplImage * eyeImage_Right = cvLoadImage (nomArchivo, - 1);

     IplImage * tempTemplateImg_Left;  IplImage * tempTemplateImg_Right;
     IplImage * templateImg_Left;  IplImage * templateImg_Right;

     si (eyeImage_Left == NULL || eyeImage_Right == NULL)
     {
         MessageBox (NULL, "plantillas no pueden ser cargados. \ N 
              Por favor revise su carpeta de ojo de base de datos "," Error ", MB_OK || MB_ICONSTOP);
         exit (1);
     }
     más
     {
         // Espacio Cambiar el color de acuerdo a los ajustes introducidos por el usuario 
  tempTemplateImg_Left = cvCreateImage (cvGetSize (eyeImage_Left), IPL_DEPTH_8U, 1);
         changeColorSpace (ajustes, eyeImage_Left, tempTemplateImg_Left);
         tempTemplateImg_Right =
                    cvCreateImage (cvGetSize (eyeImage_Right), IPL_DEPTH_8U, 1);
         changeColorSpace (ajustes, eyeImage_Right, tempTemplateImg_Right);

         flotar idealWidth = faceSize.width * Preferencias-> params-> relación;
         flotar conversionRatio = idealWidth / (float) tempTemplateImg_Left-> ancho;

         CvSize newSize;
         newSize.width = (int) idealWidth;
         newSize.height = (int) (tempTemplateImg_Left-> Altura * conversionRatio);

         templateImg_Left = cvCreateImage (newSize, IPL_DEPTH_8U, 1);
         cvResize (tempTemplateImg_Left, templateImg_Left, CV_INTER_LINEAR); // era NN 
  cvReleaseImage (y eyeImage_Left);
         cvReleaseImage (y tempTemplateImg_Left);

         templateImg_Right = cvCreateImage (newSize, IPL_DEPTH_8U, 1);
         cvResize (tempTemplateImg_Right, templateImg_Right, CV_INTER_LINEAR); // era NN 
  cvReleaseImage (y eyeImage_Right);
         cvReleaseImage (y tempTemplateImg_Right);
     }
     // ************************************************ ************* 
  // ************ Buscar faceImage para los ojos ************************ 
  // ************************************************ ************* 
  IplImage * GRAYfaceImage = cvCreateImage (faceSize, IPL_DEPTH_8U, 1);
     changeColorSpace (ajustes, faceImage, GRAYfaceImage);
     // CvCvtColor (faceImage, GRAYfaceImage, CV_RGB2GRAY); 
  // GRAYfaceImage-> origen = 1; 
  // ** Aviso a este origen imagen punto es la esquina inferior izquierda. 

     // ** Área de búsqueda Eye1 
  int x_left = 0;
     int y_left = 0;
     int width_left = (int) ((float) (faceSize.width / 2 0).);
     int height_left = (int) ((float) (faceSize.height));
     CvRect rect_Eye1 = cvRect (x_left, y_left, width_left, height_left);

     CvMat * Eye1Image = cvCreateMat (width_left, height_left, CV_8UC1);
     cvGetSubRect (GRAYfaceImage, Eye1Image, rect_Eye1);
     cvFlip (Eye1Image, Eye1Image, 0);

     // ** Área de búsqueda Eye2 
  int x_right = (int) ((float) (faceSize.width / 2 0).);
     int y_right = 0;
     int width_right = (int) ((float) (faceSize.width / 2 0).);
     int height_right = (int) ((float) (faceSize.height));
     CvRect rect_Eye2 = cvRect (x_right, y_right, width_right, height_right);

     CvMat * Eye2Image = cvCreateMat (width_right, height_right, CV_8UC1);
     cvGetSubRect (GRAYfaceImage, Eye2Image, rect_Eye2);
     cvFlip (Eye2Image, Eye2Image, 0);

     // OpenCV dice que el tamaño del resultado debe ser el siguiente: 
  Tamaño CvSize;
     size.height = Eye1Image-> Altura - templateImg_Left-> alto + 1;
     Tamano.Width = Eye1Image-> Ancho - templateImg_Left-> ancho + 1;
     IplImage * resultado1 = cvCreateImage (tamaño, IPL_DEPTH_32F, 1);
     IplImage * result2 = cvCreateImage (tamaño, IPL_DEPTH_32F, 1);

     // Ojo Izquierdo 
  cvMatchTemplate (Eye1Image, templateImg_Left, resultado1, Preferencias-> params-> tempMatch);
     // Ojo Derecho 
  cvMatchTemplate (Eye2Image, templateImg_Right, result2, Preferencias-> params-> tempMatch);

     // Encontrar la mejor ubicación partido - OJO IZQUIERDO 
  doble minValue1, maxValue1;
         CvPoint minLoc1, maxLoc1;
         cvMinMaxLoc (resultado1, y minValue1, y maxValue1, y minLoc1, y maxLoc1);
     cvCircle (resultado1, maxLoc1, 5, Preferencias-> programColors.colors [2], 1);
     // Transformar punto de volver a la imagen original 
  maxLoc1.x + = templateImg_Left-> Ancho / 2;
         maxLoc1.y + = templateImg_Left-> Altura / 2;
     Preferencias-> params-> eye1.coords.x = maxLoc1.x;
     Preferencias-> params-> eye1.coords.y = maxLoc1.y;
     Preferencias-> params-> eye1.RectSize.width = templateImg_Left-> ancho;
     Preferencias-> params-> eye1.RectSize.height = templateImg_Left-> altura;
     Preferencias-> params-> eye1.eyefound = true;

     // Encontrar la mejor ubicación partido - Ojo Derecho 
  doble minValue2, maxValue2;
         CvPoint minLoc2, maxLoc2;
         cvMinMaxLoc (result2, y minValue2, y maxValue2, y minLoc2, y maxLoc2);
     cvCircle (result2, maxLoc2, 5, Preferencias-> programColors.colors [2], 1);
     // Transformar punto de volver a la imagen original 
  maxLoc2.x + = templateImg_Left-> Ancho / 2;
         maxLoc2.y + = templateImg_Left-> Altura / 2;
     Preferencias-> params-> eye2.coords.x = maxLoc2.x + (int) faceSize.width / 2;
     Preferencias-> params-> eye2.coords.y = maxLoc2.y;
     Preferencias-> params-> eye2.RectSize.width = templateImg_Left-> ancho;
     Preferencias-> params-> eye2.RectSize.height = templateImg_Left-> altura;
     Preferencias-> params-> eye2.eyefound = true;

     cvCircle (Eye1Image, maxLoc1, 5, Preferencias-> programColors.colors [2], 1);
     cvCircle (Eye2Image, maxLoc2, 5, Preferencias-> programColors.colors [2], 1);
 }

Código de ejemplo de adaptación Método EigenEye

  Cara void :: findEyes (IplImage * faceImage, TrackingSettings * Ajustes)
 {
     IplImage ** imágenes = (IplImage **) malloc (sizeof (IplImage *) * numOfImages);
     IplImage ** eigens = (IplImage **) malloc (sizeof (IplImage *) * numOfImages);

     IplImage * averageImage;
     IplImage * proyección;

     CvSize faceSize;  faceSize = cvGetSize (faceImage);
     eigenSize newEigenSize;

     newEigenSize.width = faceSize.width * Preferencias-> params-> relación;

     newEigenSize.conversion = ((float) newEigenSize.width) / ((float) base de datos [0] -> ancho);
     newEigenSize.height = ((float) base de datos [0] -> altura) * newEigenSize.conversion;

     CvSize newSize;
     newSize.width = (int) newEigenSize.width;
     newSize.height = (int) newEigenSize.height;

     IplImage * tempImg = cvCreateImage (newSize, IPL_DEPTH_8U, 1);
     // ********** ********** Inicializaciones 
  for (int i = 0; i <Preferencias- /> params-> nImages; i ++)
     {
         imágenes [i] = cvCreateImage (newSize, IPL_DEPTH_8U, 1);
         cvResize (base de datos [i], imágenes [i], CV_INTER_LINEAR); // era NN 
  }
     cvShowImage ("eigen", imágenes [0]);
     cvReleaseImage (y tempImg);

     // Crear el espacio para Eigenfaces 
  for (i = 0; i <Preferencias- /> params-> nImages; i ++)
         eigens [i] = cvCreateImage (cvGetSize (imágenes [0]), IPL_DEPTH_32F, 1);

     averageImage = cvCreateImage (cvGetSize (imágenes [0]), IPL_DEPTH_32F, 1);
     proyección = cvCreateImage (cvGetSize (imágenes [0]), IPL_DEPTH_8U, 1);

     // ************************************************ ************* 
  // ************ Calcula los vectores propios y valores propios ************* 
  // ************************************************ ************* 
  Criterios CvTermCriteria;
     criteria.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
         criteria.maxIter = 13;
         criteria.epsilon = 0. 1;

     // ** N estaba presente en lugar de numOfImages 
  cvCalcEigenObjects (Preferencias-> params-> nImages, imágenes, eigens,
                         0, 0, 0, y criterios, averageImage, vals);

     // ************************************************ ************* 
  // ************ Buscar faceImage para los ojos ************************ 
  // ************************************************ ************* 
  IplImage * GRAYfaceImage = cvCreateImage (faceSize, IPL_DEPTH_8U, 1);
     changeColorSpace (ajustes, faceImage, GRAYfaceImage);
     // CvCvtColor (faceImage, GRAYfaceImage, CV_RGB2GRAY); 
  // ** Aviso a este origen imagen punto es la esquina inferior izquierda. 
  GRAYfaceImage-> origen = 1;

     int MARGEN = Preferencias-> params-> MAXERROR;
     doble mínimo = MARGEN; doble distancia = MARGEN;

     // ** Búsqueda Eye1 Espacio 
  Preferencias-> params-> eye1.xlimitLeft = 0;
     Preferencias-> params-> eye1.xlimitRight = faceSize.width / 2 0 - imágenes [0] -> ancho -. 1;
     Preferencias-> params-> eye1.ylimitUp =
              (Int) (((float) faceSize.height) * 0 - 75 imágenes [0] -> Altura - 1.);
     Preferencias-> params-> eye1.ylimitDown = faceSize.height / 2;

     // ** Búsqueda Eye2 Espacio 
  . Preferencias-> params-> eye2.xlimitLeft = faceSize.width / 2 0;
     Preferencias-> params-> eye2.xlimitRight = faceSize.width - imágenes [0] -> Ancho - 1;
     Preferencias-> params-> eye2.ylimitUp =
          (Int) (((float) faceSize.height) * 0 - 75 imágenes [0] -> Altura - 1.);
     Preferencias-> params-> eye2.ylimitDown = faceSize.height / 2;

     Preferencias-> params-> eye1.initializeEyeParameters ();
     Preferencias-> params-> eye2.initializeEyeParameters ();
     Preferencias-> params-> eye1.RectSize.width = imágenes [0] -> anchura;
     Preferencias-> params-> eye1.RectSize.height = imágenes [0] -> altura;
     Preferencias-> params-> eye2.RectSize.width = imágenes [0] -> anchura;
     Preferencias-> params-> eye2.RectSize.height = imágenes [0] -> altura;

     IplImage * Image2Comp = cvCreateImage (cvGetSize (imágenes [0]), IPL_DEPTH_8U, 1);
     int x, y;
     // ** Buscar ojo izquierdo es decir eye1 
  for (y = Preferencias-> params-> eye1.ylimitDown; y <Preferencias- />params->eye1.ylimitUp; y + = 2)
     {
         for (x = Preferencias-> params-> eye1.xlimitLeft; x <Preferencias- />params->eye1.xlimitRight; x + = 2)
         {
             cvSetImageROI (GRAYfaceImage, cvRect
                  (x, y, imágenes [0] -> anchura, imágenes [0] -> altura));
             si (Preferencias-> params-> varianceCheck == 1)
             {
                 si (calculateSTD (GRAYfaceImage) <= (doble) (Preferencias-> params-> varianza))
                 {
                     cvResetImageROI (GRAYfaceImage);
                     continuar;
                 }
             }
             cvFlip (GRAYfaceImage, Image2Comp, 0);
             cvResetImageROI (GRAYfaceImage);
             // Decidir si se trata de un ojo o no 
  cvEigenDecomposite (Image2Comp, Preferencias-> params-> nEigens,
                                 eigens, 0, 0, averageImage, pesos);
             cvEigenProjection (eigens, Preferencias-> params-> nEigens,
                        CV_EIGOBJ_NO_CALLBACK, 0, pesos, averageImage, proyección);
             distancia = cvNorm (Image2Comp, proyección, CV_L2, 0);

             si (distancia <&& distancia mínima> 0)
             {
                 Preferencias-> params-> eye1.eyefound = true;
                 mínimo = distancia;
                 Preferencias-> params-> eye1.distance = distancia;
                 Preferencias-> params-> eye1.coords.x = x;
                 Preferencias-> params-> eye1.coords.y = y;
             }
         }
     }

     mínimo = MARGEN;  distancia = MARGEN;

     // ** Buscar ojo derecho es decir eye2 
  for (y = Preferencias-> params-> eye2.ylimitDown; y <Preferencias- />params->eye2.ylimitUp; y + = 2)
     {
         for (x = Preferencias-> params-> eye2.xlimitLeft; x <Preferencias- />params->eye2.xlimitRight; x + = 2)
         {
             cvSetImageROI (GRAYfaceImage,
                   cvRect (x, y, imágenes [0] -> anchura, imágenes [0] -> altura));
             si (Preferencias-> params-> varianceCheck == 1)
             {
                 si (calculateSTD (GRAYfaceImage) <= (doble) (Preferencias-> params-> varianza))
                 {
                     cvResetImageROI (GRAYfaceImage);
                     continuar;
                 }
             }
             cvFlip (GRAYfaceImage, Image2Comp, 0);
             cvResetImageROI (GRAYfaceImage);
             // ** Decidir si se trata de un ojo o no 
  cvEigenDecomposite (Image2Comp, Preferencias-> params-> nEigens,
                                 eigens, 0, 0, averageImage, pesos);
             cvEigenProjection (eigens, Preferencias-> params-> nEigens,
                                0, 0, pesos, averageImage, proyección);
             distancia = cvNorm (Image2Comp, proyección, CV_L2, 0);

             si (distancia <&& distancia mínima> 0)
             {
                 Preferencias-> params-> eye2.eyefound = true;
                 mínimo = distancia;
                 Preferencias-> params-> eye2.distance = distancia;
                 Preferencias-> params-> eye2.coords.x = x;
                 Preferencias-> params-> eye2.coords.y = y;
             }
         }
     }
     cvReleaseImage (y Image2Comp);

     // ** Limpiar 
  cvReleaseImage (y GRAYfaceImage);
     for (i = 0; i <Preferencias- /> params-> nImages; i ++)
         cvReleaseImage (e imágenes [i]);

     for (i = 0; i <Preferencias- /> params-> nImages; i ++)
         cvReleaseImage (y eigens [i]);

     cvReleaseImage (y averageImage);
     cvReleaseImage (y proyección);

     libres (imágenes);
     libres (eigens);
 }

Licencia:Este  traduccción del artículo, junto con cualquier código y archivos fuente asociado, está licenciado bajo la licencia de código abierto del proyecto (CPOL)

 

Fuente aqui

Deja una respuesta