Introducción | Descripción del
Problema |
Análisis
del problema |
Diseño
de la solución |
Implementación |
Descarga |
Caso de uso 1: Registrar una persona
En este
caso el usuario
selecciono la pestaña "Registro Rostros", posteriormente ingreso
su
nombre y Rut de forma correcta, luego presiono 5 veces el botón
"Tomar
nueva foto", obteniendo
imágenes donde el sistema detecto automáticamente
el rostro dentro de la imagen y las desplego en el lado derecho de la
pantalla.
De estas 5 imágenes el usuario selecciono 3 (marcadas en
rojo) y presiono
"Ingresar Datos", y el sistema quedo nuevamente entrenado incluyendo
a la nueva persona.
Caso de uso 2: Reconocimiento facial
Donde se
desplego el
nombre, el RUT y un registro de la hora y la fecha en las cuales se ha
detectado el rostro. Hay que notar que mientras tanto, el programa
sigue buscando
y
reconociendo rostros en la imagen de la
cámara.
Dificultades:
Las principales
dificultades en el desarrollo del programa fueron:
-
Obtención de la imagen
desde la cámara web: Ya que java no tiene un modo nativo para
acceder a los
periféricos del sistema, ni de procesar el video para
desplegarlo, se requirió
de uso de
bibliotecas
externas. En un principio se pensaba usar OpenCV, y JNI
para poder acceder a los métodos de OpenCV, ya que este
está en C++, pero
finalmente, se utilizo JavaCV que es una
biblioteca para java que utiliza JNA
para hacer lo mismo que se quería lograr con JNI de una forma
mucho mas facil.
- Refresco de
la imagen
lenta: Como se explica en la sección de diseño de la
solución, la imagen en un
comienzo se veía con un refresco muy lento, llegando a 1 fps
(frames per
second). Esto
se solucionó
haciendo que cada acción se realizara en hebras
diferentes, con lo que la imagen se pudo desplegar en paralelo mientras
se
hacían los cálculos correspondiente a la detección
y
reconocimiento.
- Métodos de
clasificación: Inicialmente
el programa
tenía contemplado usar 2 métodos de clasificación
para obtener a quien
correspondía el rostro detectado, por distancia euclidiana y por
redes
neuronales, pero para lograr un mejor desempeño en redes
neuronales que por
distancia, se requería un tiempo demasiado largo de
entrenamiento, por lo que
el registro de rostros era
demasiado lento e impracticable. Finalmente se
decidió, no incluir las redes neuronales en el programa
principal, pero que de
todas formas esta quede implementada en el código.
Bugs conocidos:
-
Detección falsa de
rostros: Debido a que el método de detección de rostro
busca patrones dentro de
la imagen de entrada, es posible que en ciertas ocasiones detecte como
rostros
cosas
que no lo son, como
manchas y relieves en la muralla de fondo.
-
Reconocimiento
equivocado: Considerando que lo detectado era efectivamente un rostro,
existe
una posibilidad de que el programa se equivoque en reconocer a la
persona y lo
asocie a
otra imagen existente en el entrenamiento. El método usado tiene
una
tasa de error de 10 a 20%, por lo que es muy posible que se reconozca
mal un
rostro, aunque rápidamente el sistema
debería volver a reconocer
el rostro y
desplegar el correcto de forma casi instantánea, aunque
también puede no
ocurrir.
De forma análoga, si un rostro de una persona que no está en el set de entrenamiento pasa por la cámara, esta será detectada como alguno de las personas que están registradas, produciéndose un error relativamente grave, ya que el programa, en un par de segundos, puede registrar que pasaron todas las personas por ahí, siendo que fue alguien que simplemente no estaba registrado.
Para
implementar el
reconocimiento de rostros se uso el método PCA (Principal
Component Analysis),
el que básicamente consiste en transformar un gran
número de variables
correlacionadas,
en este
caso los pixeles, a un menor número de variables no
relacionadas, reduciendo en una gran parte las dimensiones de las
variables a
clasificar.
Para
clasificar las
proyecciones de las imágenes en el espacio vectorial
generado, se implementaron
2 métodos, comparación mediante la
mínima distancia euclidiana y clasificación
usando redes
neuronales. Debido a que esta ultima toma mucho tiempo de
entrenamiento para llegar a un resultado mejor que el primero, se
decidió dejar
la distancia euclidiana como método principal de
clasificación, sin embargo, se
puede cambiar fácilmente a red neuronal cambiando un
parámetro en el
código fuente, específicamente en el
constructor de PCA.
Para
mayor información
sobre el método, este está explicado con detalle
en este paper, sin considerar el punto 3, que corresponde a
otro método no implementado.
Por otro
lado, debido a
que se necesito capturar imágenes desde una
cámara para que el sistema sea
manipulado en tiempo real y que se detectaran los rostros dentro de la,
se
requirió el uso de
bibliotecas como OpenCV y JavaCV. Al hacer estos calculos de
forma secuencial, el tiempo desde que terminaba de reconocer un rostro
y
mostrar nuevamente la imagen era demasiado alto,
perdiendo la fluidez y el
tiempo real deseado, por lo que se utilizaron diferentes hebras o hilos
para
realizar las diferentes acciones que el programa debe realizar al mismo
tiempo,
estas son
mostrar la imagen de la
cámara, capturar la imagen, detectar un
rostro y reconocer el rostro.
Finalmente el diagrama de
clases quedó de la siguiente forma:
OpenCV
(Open Source Computer Vision) es una biblioteca para funciones de
computación visual en tiempo real. Con esta biblioteca se
realizaron las funciones básicas con la cámara
web, como tomar fotos, normalizar cada fotos, y otras funciones. Sin
embargo, esta biblioteca es para C++, por lo cual se necesita javacv. |
Esta biblioteca se utiliza como interfaz de OpenCV con Java, ya que como se explicó anteriormente, OpenCV está escrito para utilizarlo en C++. |
Biblioteca para cálculo técnicos y científicos enfocados a la ingeniería. Con esta biblioteca se realizaron fácilmente los cálculos con matrices, tales como multiplicaciones, transpuestas, etc. |
El proyecto se puede descargar desde el siguiente link:
Instalable:
Windows 95/98/NT/XP/2008
Se puede bajar e instalar
una versión instalable pre compilada de OpenCV, para la
ejecución de este se
requiere además tener instalado Microsoft Visual C++ 2008 SP1
Redistributable Package
(o alguna versión
de Visual Studio 2008).
Código fuente: Windows 95/98/NT/XP/2008 o Unix based OS
De forma alternativa, se puede obtener descargar el código fuente, en c++, y realizar la compilación. Las instrucciones de instalación se encuentran en
http://opencv.willowgarage.com/wiki/InstallGuide.
En ambos
casos se
requiere que el System PATH esté configurado para incluir a
los binarios de
OpenCV (por ejemplo C:\OpenCV2.1\bin).
- JavaCV
La
biblioteca requerida
se puede descargar desde el siguiente link, este enlace incluye la JNA 3.2.5 requerido para
el funcionamiento de JavaCV. Tras descargar, descomprimir en
algún directorio
deseado.
- Colt
La
biblioteca requerida
se puede descargar en alguno de los siguentes formatos: Zip, tar.gz. Al igual que JavaCV, descomprimir en
algún
directorio deseado.
Compilación y Ejecución:
Para la
compilación y
ejecución del programa, se requiere especificar el classpath
de tanto de JavaCV
como de los 2 archivos .jar de Colt. En el caso de que ambas
bibliotecas hayan
sido
descomprimidas en el mismo
directorio que el código fuente, tal como estas
venían en el archivo comprimido, la compilación
seria de la siguiente forma:
javac
-classpath .;
javacv.jar; colt\lib\colt.jar; colt\lib\concurrent.jar tabDemo.java
Y de
forma análoga, la
ejecución:
java -classpath .; javacv.jar; colt\lib\colt.jar; colt\lib\concurrent.jar tabDemo