jueves, 16 de mayo de 2013

Reporte Final - Detección de mentiras - python

Para este proyecto el objetivo fue detectar las iris de las personas, esto con el fin de detectar mentiras según la posición.

Liga al repo

Introducción 

Dicen que poder los gestos es algo muy bueno, sobre todo cuando se trata de negocios, estar a punto de   hacer un testamento, sabes donde exactamente estuvieron tus hijos la noche pasada, tu novia, platicar con tu maestra y preguntarle sobre el examen final.... todo esto se puede saber con las preguntas adecuadas y sabiendo interpretar el lenguaje corporal, un poco mas especifico, el lenguaje del ojo.

"Los ojos nos hablan, pero a veces sabemos interpretar lo que nos están diciendo. Con un entrenamiento adecuado podremos detectar hasta el más sutil de los detalles."

Con un entrenamiento adecuado... eso te lleva a pensar, porque gastar 5, 10, 15, 20 años de mi vida intentando detectar esos detalles si puede hacer un programa en días que haga lo mismo y con el mismo fin.

Bueno obviamente un sistema jamas sera tan perfecto como lo es el cuerpo humano, pero si nos ayuda a detectarlas mas fácil, pues porque decirles que no?




Lo primero - detectar los ojos.

En lo que tenemos que enfocarnos es en detectar ojos en una imagen o video, esto es sencillo si se trabaja con openCV y con unas cuantas cascadas(archivos XML).

CODIGO DETECTAR OJOS

Tener una cascada bien entrenada nos facilita mucho la detección; estas son algunas características de las cascadas proporcionadas por openCV:


Recortar el área que nos interesa

Una vez que tenemos los ojos detectados, en nuestra aplicación lo que nos interesa es trabajar unicamente con el area detectada esto para evitar procesamiento innecesario.

Paso 1/2 .- Hacer una copia de la imagen original porque openCV no nos permite modificarla directamente.



Paso 2/2 .-  Usar cv.SetImage(param1, param2)
Esta función recibe 2 parámetros:
param1 = es la imagen de la cual queremos sacar el recorte
param2 = son las dimensiones del rectángulo que nos interesa. Este segundo parámetro esta formado por 4 parámetros: (izquierda, arriba, ancho, alto). Los primeros dos son las coordenadas "x, y" de donde empieza tu rectángulo.

Lo que hace este metodo es recortar la imagen que se le pasa como parametro.


Ahora para nuestra aplicación no nos importa tomar el area de los DOS ojos, con que tengamos uno es suficiente para empezar hacer pruebas.



Detectar la pupila.

Ya con el área recortada, ahora nos interesa saber donde esta las pupila, para ellos usamos otra función de openCV llamada:

cv.HoughCircles(imagen, storageCir, cv.CV_HOUGH_GRADIENT, dp, minDist, param1, param2, minRadius, maxRadius)



Donde los parámetros que nos importa son:

<<Esto es un Copy-Paste de la documentación.>>

minDist = Minimum distance between the centers of the detected circles. If the parameter is too small, multiple neighbor circles may be falsely detected in addition to a true one. If it is too large, some circles may be missed
param2 The second method-specific parameter. in the case of CV_HOUGH_GRADIENT it is the accumulator threshold at the center detection stage. The smaller it is, the more false circles may be detected. Circles, corresponding to the larger accumulator values, will be returned first


Una idea excelente es hacer estos parámetros dinámicos,  porque cada combinación es unica de cada imagen o para círculos muy parecidos.

NOTA: Antes de aplicar cv.HoughCircles, la imagen tiene que pasar por filtros de todo tipo, para que su detección sea mas sencilla.


Un problema que se detecto en este punto es que la pupila tiene que ser de un radio especifico asi que si te colocabas muy cerca o muy lejos de la cámara web, había muchas posibilidades que detectara círculos falsos o no detectara nada.

Algoritmo

Con la pupila detectada... como sabremos que nos están mintiendo.

El algoritmo trata de sacar un punto promedio, este es el centro de la pupila que se obtiene de un "entrenamiento" previo(con el ojo statico), después del entrenamiento se hace una resta de punto centro de la pupila detectada menos el punto promedio y si el resultado es muy grande(sobrepasa un umbral) significa que el ojo esta en otra posición = NOS MIENTE.


Limitaciones

  • El detector de pupilas funciona mejor en lugares como habitaciones, donde la única luz que hay es la que entra por la ventanas.
  • En cuartos oscuros o a altas horas de la noche, no es muy eficiente.
  • Solo detecta pupilas de un radio determinado, así que si estas muy cerca o lejos de la cámara, no detectara la pupila.


Mejoras

  • Detectar bien los círculos(pupilas).
  • Dimensionar la imagen original para mayor velocidad de procesamiento.
  • Hacer los radios de los círculos adaptativos dependiendo del área que ocupa el “ojo” en el cuadro.
  • Detectar dilatación.

Resultados



Código Completo





Referencias


http://www710.univ-lyon1.fr/~bouakaz/OpenCV-0.9.5/docs/ref/OpenCVRef_BasicFuncs.htm#decl_cvSetImageROI

http://blogrobotica.linaresdigital.com/2011/01/mezclando-dos-imagenes-en-una-con.html

http://visionlabs.cl/blog/?p=43

http://www.isseu.com/reconocimiento-de-cara-con-opencv/

http://opencv.willowgarage.com/documentation/python/core_operations_on_arrays.html#index-5479

http://stackoverflow.com/questions/10716464/what-are-the-correct-usage-parameter-values-for-houghcircles-in-opencv-for-iris

http://opencvpython.blogspot.mx/2013/03/histograms-2-histogram-equalization.html?m=1

http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html#cv-houghcircles