Post on 19-Mar-2020
I
Escuela
Polit
écnic
a S
uperior
de L
inare
s
Universidad de Jaén Escuela Politécnica Superior de Linares
Trabajo Fin de Grado
______
DISEÑO DE UN SISTEMA DE
VISIÓN POR COMPUTADOR DE
BAJO COSTE PARA EL CONTROL
DE ASISTENCIA LABORAL
Alumno: Sergio Francisco Alcázar Ríos
Tutor: Prof. D. Silvia Satorres Martínez Depto.: Departamento de Electrónica, de
Telecomunicación y Automática
Febrero, 2015
II
Universidad de Jaén
Escuela Politécnica Superior de Linares
Departamento de
Doña Silvia Satorres Martínez, tutora del Trabajo Fin de Grado titulado: Diseño de
un Sistema de Visión por Computador de Bajo Coste para el Control de Asistencia
Laboral, que presenta Sergio Francisco Alcázar Ríos, autoriza su presentación
para defensa y evaluación en la Escuela Politécnica Superior de Linares.
Linares, Febrero de 2015
El alumno: Los tutores:
SERGIO FCO. ALCÁZAR RÍOS SILVIA SATORRES MARTÍNEZ
III
“Hoy es siempre todavía, toda la vida es ahora.
Y ahora, ahora es el momento de cumplir las promesas que nos hicimos.
Porque ayer no lo hicimos, porque mañana es tarde.
Ahora.”
Antonio Machado
Dedicado a mi familía que siempre está ahí.
A una gran amiga que nunca me falta, y a los amigos que atesoro.
Gracias por seguir ahí.
IV
Índice:
Índice de Figuras .......................................................................................................... VI
Índice de Tablas ......................................................................................................... VIII
1. RESUMEN ................................................................................................................. 1
2. INTRODUCCIÓN ....................................................................................................... 2
2.1. Motivaciones ....................................................................................................... 2
2.2. Conceptos .......................................................................................................... 2
2.2.1 Visión por computador ................................................................................. 2
2.2.2 Segmentación de la imagen ........................................................................ 3
2.2.3 Detección de caras ...................................................................................... 3
2.2.4 Características Haar-Like ............................................................................ 5
2.2.5 Algoritmo de entrenamiento y detección ...................................................... 7
2.2.6 Imagen Integral ............................................................................................ 7
2.2.7 Clasificadores en cascada ........................................................................... 8
2.2.8 Reconocimiento de caras ...........................................................................10
2.2.9 Algoritmo de reconocimiento EigenFaces ...................................................11
3. OBJETIVOS .............................................................................................................13
4. MATERIALES Y MÉTODOS .....................................................................................14
4.1. Hardware ...........................................................................................................14
4.1.1. Introducción ................................................................................................14
4.1.2. Elección de Hardware .................................................................................14
4.1.3. Características del Hardware usado ...........................................................14
4.2. Software ............................................................................................................18
4.2.1. Raspbian ....................................................................................................18
4.2.2. QT ..............................................................................................................20
4.2.3. OpenCV ......................................................................................................21
4.3 Programa de Gestión .........................................................................................32
4.3.1 Introducción ................................................................................................32
4.3.2 Diagrama de Bloques .................................................................................33
4.3.3 Módulo de Captura y Guardado de Imágenes ............................................41
4.3.4 Módulo de Reconocimiento de caras ..........................................................53
4.3.5 Gestión de información ...............................................................................66
4.3.6 Otras librerías relacionadas ........................................................................68
4.3.7 Compilación y ensamblado .........................................................................69
V
5. RESULTADOS Y DISCUSIÓN .................................................................................73
6. CONCLUSIONES .....................................................................................................82
6.1. Líneas de futuro .................................................................................................82
7. ANEXOS...................................................................................................................84
7.1. Instalación de Raspbian ....................................................................................84
7.2. Instalación de la Cámara Pi ...............................................................................90
7.3. Instalación de OpenCV y otros módulos ............................................................94
7.4. Instalación de Qt4 ..............................................................................................96
7.5. Instalación de Cliente FTP .................................................................................97
8 Bibliografía ................................................................................................................99
VI
Índice de Figuras
Figura 2.1 Característica de dos rectángulos .................................................................... 6
Figura 2.2 Característica de tres rectángulos .................................................................... 6
Figura 2.3 Característica de cuatro rectángulos ................................................................ 6
Figura 2.4 Clasificador en cascada ................................................................................... 9
Figura 4.1 Dispositivo Raspberry Pi .................................................................................15
Figura 4.2 Partes de Raspberry Pi ...................................................................................16
Figura 4.3 Pi-Cámara .......................................................................................................18
Figura 4.4 Logo de Raspbian ...........................................................................................19
Figura 4.5 Logo de Qt ......................................................................................................20
Figura 4.6 Librería OpenCV .............................................................................................21
Figura 4.7 Carpetas de trabajo ........................................................................................33
Figura 4.8 Diagrama de Bloques de Captura de Caras ....................................................34
Figura 4.9 Diagrama de Bloques de Reconocimiento de caras ........................................37
Figura 4.10 Diagrama de bloques de envío de ficheros ...................................................40
Figura 4.11 Ejecución con dos argumentos .....................................................................42
Figura 4.12 Contenido del fichero cfg.csv ........................................................................43
Figura 4.13 Contenido de ficheros.csv .............................................................................43
Figura 4.14 Ejecución con cuatro argumentos .................................................................54
Figura 4.15 Imágenes guardadas ....................................................................................54
Figura 4.16 Ficheros generados a la salida .....................................................................66
Figura 4.17 Contenido de fichero generado .....................................................................66
Figura 4.18 Ejecución de Script .......................................................................................68
Figura 4.19 Ejecución de cmake ......................................................................................71
Figura 4.20 Compilación y creación de ejecutable ...........................................................72
Figura 5.1 Proceso Guardar Imagen (existe empleado) ...................................................73
Figura 5.2 Guardar Imagen (no existe empleado) ............................................................74
Figura 5.3 Actualización del fichero cfg.csv .....................................................................74
Figura 5.4 Captura de PiCam ..........................................................................................75
Figura 5.5 Cara detectada por PiCam ..............................................................................75
Figura 5.6 Consola muestra guardado .............................................................................76
Figura 5.7 Actualización del fichero ficheros.csv ..............................................................76
Figura 5.8 Cara recortada de la imagen ...........................................................................77
Figura 5.9 Ejecución de aplicación de reconocimiento .....................................................77
Figura 5.10 Captura de PiCam ........................................................................................78
Figura 5.11 Cara detectada e identificada ........................................................................79
VII
Figura 5.12 Cara reconocida indicado por terminal ..........................................................79
Figura 5.13 Cara reconocida mediante EigenFaces ........................................................79
Figura 5.14 Cara reconocida indicado por terminal ..........................................................80
Figura 5.15 Cara guardada de empleado.........................................................................80
Figura 5.16 Cara reconocida por EigenFaces ..................................................................81
Figura 5.17 Datos incluidos de fichero de Salida .............................................................81
Figura 7.1 Inicio de Instalación ........................................................................................85
Figura 7.2 Programa de configuración .............................................................................85
Figura 7.3 Indicador de sistema expandido de archivos ...................................................86
Figura 7.4 Cambio de contraseña de usuario ..................................................................86
Figura 7.5 Activación de escritorio al iniciar .....................................................................87
Figura 7.6 Opciones de Idioma ........................................................................................87
Figura 7.7 Rastrack .........................................................................................................88
Figura 7.8 Overclock ........................................................................................................88
Figura 7.9 Opciones avanzadas ......................................................................................89
Figura 7.10 Información de raspi-config ...........................................................................90
Figura 7.11 PiCam conectada a Raspberry Pi .................................................................90
Figura 7.12 Ventana de configuración de Raspbian .........................................................91
Figura 7.13 Habilitado de CamPi .....................................................................................92
Figura 7.14 Confirmado de reinicio ..................................................................................92
Figura 7.15 Información de PiCam...................................................................................93
Figura 7.16 Imagen tomada por PiCam ...........................................................................94
Figura 7.17 Descarga de Librería.....................................................................................95
Figura 7.18 Ruta de guardado de librería .........................................................................95
Figura 7.19 Ventana de trabajo Qt ...................................................................................97
Figura 7.20 Configuración del compilador gcc .................................................................97
Figura 7.21 Instalación de paquete FTP ..........................................................................98
VIII
Índice de Tablas
Tabla 4.1 Características de Modelos de Raspberry Pi ....................................................17
RESUMEN
1
1. RESUMEN
La detección y la identificación de caras son temas que están siendo ampliamente
estudiados debido a la gran cantidad de aplicaciones que tienen y situaciones que
pueden necesitarse. Las cámaras fotográficas digitales, antes de tomar una fotografía,
detectan los rostros presentes en la escena para mejorar el enfoque y la nitidez. También
se utiliza la detección de rostros en aplicaciones de seguridad y seguimiento de
personas, entre otras. Además, podemos encontrar sistemas de reconocimiento de
rostros en páginas web de redes sociales, software de administración de fotografías,
sistemas de control de acceso, etc.
La identificación de caras tiene la ventaja que, a diferencia de otros sistemas que
utilizan para la identificación automática de personas, el uso de características físicas del
individuo o de su comportamiento como su cara, el iris de los ojos o sus huellas
dactilares, es un método que no requiere de ningún contacto físico para tomar una
muestra. De hecho, con la tecnología actual, las imágenes pueden obtenerse con muy
buena resolución y sin que se percaten de ello.
El objetivo de este trabajo es construir un sistema capaz de detectar las caras
presentes en una secuencia de vídeo y luego poder determinar la identidad de dichas
personas. Para ello, presentamos el algoritmo de detección de caras, llamado Like-Haar.
Luego, abordamos el reconocimiento de rostros utilizando un método que tiene como
fundamento a la teoría de compressed sensing, denominado EigenFaces.
MOTIVACIONES
2
2. INTRODUCCIÓN
A continuación se hará una breve descripción de los motivos que han llevado a la
creación de este proyecto y unos conceptos básicos.
2.1. Motivaciones
Anteriormente, para la identificación de personal empleado de una empresa, se ha
usado tarjetas identificadoras, ya sea por código de barras, o por banda magnética. Pero,
durante los últimos años, ha ido apareciendo mucha funcionalidad para la detección y
seguimiento de caras en movimiento, la cual nos permite una detección más segura y
efectiva.
Aparte, han ido surgiendo sistemas informáticos de muy bajo coste que ofrecen una
gran funcionalidad, donde podemos aplicar la funcionalidad anterior fácilmente. El hecho
de que sea en movimiento, nos resulta útil para poder identificar de la mejor manera a
cada individuo, y con mucha mayor precisión, aplicando las distintas técnicas existentes.
El principal problema a resolver es la dificultad para identificar con exactitud el
individuo o individuos a los cuales se realiza el seguimiento. Este problema puede
resultar trivial o difícil dependiendo de varios aspectos del entorno. Así mismo, la forma
de la cara, la inclusión de maquillaje y otros factores pueden dificultar la detección.
2.2. Conceptos
Para poder entender el trabajo fin de grado, es necesario que se expliquen aquellos
términos que se consideran importantes:
2.2.1 Visión por computador
La visión por computador, también denominada visión artificial, es un campo de la
inteligencia artificial enfocado a que las computadoras puedan extraer información útil a
partir de imágenes, consiguiendo solucionar problemas de la vida real.
El objetivo general de la visión artificial es obtener información o características de
la vida reala partir del tratamiento de las imágenes registradas por una o varias fuentes,
INTRODUCCIÓN
3
ya sean estas fuentes cámaras, videocámaras u otros aparatos. Aunque aún estamos
muy lejos de conseguir resultados a los de la percepción natural, la gran velocidad de
cálculo de los equipos informáticos actuales y los avances recientes en aspectos
prácticos y teóricos de esta disciplina, han conseguido sistemas autónomos para la
lectura de matrículas (mediante OCR), la localización de rostros o figuras en movimiento,
así como el reconocimiento de objetos.
De manera más individualizada, podemos decir que se dividen en:
La detección, segmentación, localización y reconocimiento de características u
objetos en una imagen.
La evaluación de los resultados obtenidos de dicha imagen (por ejemplo,
segmentación, registro).
Exploración de diferentes imágenes de un objeto similar, es decir, hacer concordar
un mismo objeto en diversas imágenes.
Seguimiento de una entidad en una sucesión de imágenes.
Búsqueda de imágenes digitales por su contenido.
2.2.2 Segmentación de la imagen
La segmentación de la imagen es un campo de la visión artificial, que se encarga
del proceso de separar en una imagen las partes incluidas en ella: pixeles, objetos, o
cualquier elemento destacable (una cara, una figura, etc.).
Todas las imágenes que manejemos, tanto para el entrenamiento como para la
detección, serán imágenes en escala de grises.
Su objetivo, es simplificar la imagen para que sea mucho más fácil analizarla. Nos
permitirá localizar objetos o encontrar los límites de ellos dentro de la imagen.
2.2.3 Detección de caras
CONCEPTOS
4
La detección de caras es un caso definido de detección de objetos y patrones. Este
proceso, en un computador, consigue ubicar o localizar las caras incluidas en una imagen
o vídeo. Hay que tener en cuenta que, este caso, no es tan sencillo como podría
pensarse de la visión humana. Aún así, existen diversos métodos para conseguir
detectarlos.
La detección de caras es actualmente utilizada en diversos tipos de aplicaciones.
En las cámaras digitales actuales, mientras se toma una fotografía, detectan las caras
presentes en la escena para mejorar el enfoque y la nitidez. También se utiliza la
detección de caras en aplicaciones de seguridad y seguimiento de personas. En un
sistema reconocedor de caras es imprescindible, en primera instancia, detectar las caras
en una imagen para luego poder determinar la identidad de cada uno.
La detección de caras determina la ubicación, tamaño y orientación de las caras
que se encuentran presentes en una imagen. Cuando hablamos de ubicación, nos
referimos a la posición de las caras en relación a la imagen. Además, las caras pueden
presentarse con diversos tamaños, no sólo por las diferentes contexturas físicas de
diferentes personas, sino también por la variedad de distancias de las caras respecto a la
cámara al momento de tomar la fotografía. En cuanto a la orientación, en este trabajo
solamente trataremos con caras dispuestas frontalmente, aunque no se descartarán
aquellas que presenten un leve cambio de orientación.
Existen diversos métodos para la detección de caras. Sin embargo, muchos de
ellos no son aplicables cuando se busca hacerlo en tiempo real. El método de Viola y
Jones fue el primero en ofrecer detección de caras robusta y en tiempo real. Posee dos
etapas principales: una de entrenamiento del detector, que es la que mayor tiempo de
procesamiento demanda, y otra de detección donde se emplea el detector entrenado en
la primera etapa sobre cada imagen a analizar. Esta segunda etapa es muy rápida y
permite realizar la detección en tiempo real.
Para la detección de caras, Viola y Jones analizan la imagen en busca de
características relevantes que aporten información acerca de la presencia de una cara.
En el trabajo de Viola y Jones, se utilizan clasificadores para distinguir objetos que
son cara de objetos que no lo son. Construyen los clasificadores utilizando una variante
de características conocidos como características Haar-like. Reciben este nombre ya que
su resultado es similar al de aplicar filtros de Haar sobre la imagen, solo que éstos
INTRODUCCIÓN
5
pueden calcularse más eficientemente. Están definidos por dos, tres o cuatro rectángulos
y su cálculo consiste en hallar la diferencia entre la integral de la imagen en las zonas
blancas y la integral de la imagen en las zonas negras.
2.2.4 Características Haar-Like
Las características de Haar (Haar-like features en inglés) capturan muchas de las
características presentes en una cara, por ejemplo, la zona de los ojos suele ser más
oscura que la zona superior de las mejillas y el puente nasal suele ser más claro que los
ojos.
A este tipo de características, se los llama características simples por ser muy
sencillos de calcular. Aportan poca información de manera individual, pero poseen la
particularidad de poder calcularse de forma extremadamente rápida, en orden constante,
y se pueden combinar para formar clasificadores que brinden mayor información.
La etapa de entrenamiento descrita por Viola y Jones consiste justamente en esto,
en formar clasificadores que sean capaces de discriminar entre caras y no caras,
combinando otros clasificadores muy simples construidos en base a características
simples.
La principal razón para usar características en el algoritmo es que permite hacer
una asociación entre conocimiento de lo aprendido (fase de entrenamiento) y el análisis
de los datos adquiridos. Además, la clasificación por características es mucho más rápida
que el procesado por análisis basados en píxel.
Las características de Haar permiten obtener información de una franja concreta
mediante una operación aritmética simple. Lo que nos lleva a una gran eficiencia tanto de
cálculo como espacial.
Estas características tienen la ventaja de ser invariantes a la iluminación y a la
escala, además de ser muy robustas frente al ruido de la imagen.
En concreto se suelen usar tres características de Haar que se representan en las
figuras 2.1, 2.2 y 2.3:
CONCEPTOS
6
Característica de dos rectángulos (two-rectangle feature):
Figura 2.1 Característica de dos rectángulos
Característica de tres rectángulos (three-rectangle feature):
Figura 2.2 Característica de tres rectángulos
Característica de cuatro rectángulos (four-rectangle feature):
Figura 2.3 Característica de cuatro rectángulos
Definiremos una característica simple como una función definida por la siguiente
ecuación:
INTRODUCCIÓN
7
fSF (I) = ci ∙ RecSum(I, ri)
ri∈F
Donde:
𝑐𝑖 = −1 𝑠𝑖 𝑟𝑖 𝑒𝑠 𝑏𝑙𝑎𝑛𝑐𝑜
1 𝑠𝑖 𝑟𝑖 𝑒𝑠 𝑛𝑒𝑔𝑟𝑜
(Fórmula 2.1)
Siendo F uno de las características representadas en las figuras 2.1, 2.2 y 2.3, I es
la imagen donde se evalúa las características, 𝑟𝑖 son los rectángulos que componen al
tipo F y RecSum (I,𝑟𝑖) es la función que calcula la suma de los píxeles de 𝑟𝑖 en la imagen
I.
Para obtener las características de la imagen rápidamente, debemos introducir una
representación de la imagen denominada imagen integral que se utiliza para optimizar el
cálculo de las características simples, tanto en el entrenamiento como en la detección.
2.2.5 Algoritmo de entrenamiento y detección
El método posee dos etapas principales: una de entrenamiento del detector, donde
se construyen los clasificadores que lo componen, y otra de detección, donde se emplea
el detector entrenado en la primera etapa para detectar las caras en una imagen.
Durante la etapa de entrenamiento se crean varios clasificadores fuertes (strong
classifiers) que permiten decidir qué regiones de la imagen corresponden a caras y
cuáles no. Luego se organizan los clasificadores fuertes en una estructura de cascada
que permite mejorar la eficiencia del detector, dado que los primeros niveles de la
cascada son clasificadores con una menor cantidad de clasificadores débiles que los
últimos y en consecuencia más veloces que éstos.
De esta manera se optimiza el proceso general de detección, ya que la gran
mayoría de los objetos que no son caras son filtrados en los niveles más rápidos.
2.2.6 Imagen Integral
CONCEPTOS
8
Para computar rápidamente cada uno de los rectángulos se usa una representación
de la imagen llamada “Imagen integral”. La integral de una imagen respecto a un punto
{x,y} consiste en la suma de los píxeles por arriba y a la izquierda de dicho puntos, {x,y}
incluidos.
Dada una imagen I de tamaño n×m, la imagen integral de I es una función II
definida por la siguiente ecuación:
II(x, y) = I(x′ , y′)𝑥′≤ 𝑥𝑦′≤𝑦
Para:
1 ≤ 𝑥 ≤ 𝑛, 1 ≤ 𝑦 ≤ 𝑚
(Fórmula 2.2)
La imagen integral representa en informática una manera elaborada de obtener
valores de forma eficiente. Este método permite el uso de programación dinámica, que
permite la obtención de valores dentro de la imagen a través de otros valores calculados
previamente.
2.2.7 Clasificadores en cascada
El principio básico del algoritmo de detección de caras consiste en escanear el
detector muchas veces a través de una misma imagen, en diferentes puntos de vista y a
diversas escalas. Incluso si una imagen contiene muchas caras, está claro que la
mayoría que se escaneen no contendrán ninguna cara.
Esto lleva a una nueva manera de ver el problema: En vez de encontrar las caras,
lo que el algoritmo debería hacer es descartar background (todo aquello que no es cara).
La idea recurrente a la que llegamos es que resulta más fácil descartar una imagen que
no contenga una cara que encontrar una cara en una imagen. Con esto en mente, parece
ineficiente construir un detector que contenga un solo clasificador fuerte, ya que el tiempo
de clasificación será constante sin importarnos la entrada del clasificador, porque, de este
modo el clasificador tiene que evaluar todas las características que lo forman. Aumentar
la velocidad de clasificación generalmente implica que el error de clasificación aumentará
INTRODUCCIÓN
9
inevitablemente porque para disminuir el tiempo de clasificación, se debería disminuir el
número de clasificadores simples que se utilizan. Para evitar esto, se propone una
técnica para reducir el tiempo de clasificación conservando las exigencias de rendimiento
del clasificador.
Esta técnica consiste en el uso de una cascada de clasificadores fuertes. El trabajo
en cada etapa del clasificador consiste en determinar si la sub-imagen que se analiza es
definitivamente una cara o background. Cuando esa sub-imágenes clasificada como
background en alguna de las etapas del detector, se descarta inmediatamente. En caso
contrario, si se clasifica como una posible cara, pasa a la siguiente etapa del clasificador
como puede verse en figura 2.4. Se identificará una sub-imagen como contenedora de
una cara si, y exclusivamente pasa a través de todas las etapas del detector de forma
positiva.
Figura 2.4 Clasificador en cascada
En la figura 2.4 se observa una cascada de N etapas. Cada etapa está compuesta
por un único clasificador fuerte. En caso de que, en una etapa, una sub-imagen sea
CONCEPTOS
10
detectada como background o no cara, se descarta esa sub-imagen. En caso de que sea
detectada como cara, pasa a ser evaluada por la siguiente etapa. En la última etapa, las
sub-imágenes detectadas como caras son el resultado del algoritmo de detección. Las
primeras etapas deben evaluar mayor cantidad de imágenes y por ello se diseñan los
primeros clasificadores fuertes para que tengan un costo computacional mucho menor
que los de las últimas etapas.
Si se utilizase un clasificador que tuviese un único estado, normalmente habría que
aceptar los falsos negativos para reducir la tasa de falsos positivos. Sin embargo, para
las primeras etapas del clasificador en cascada se acepta una alta tasa de falsos
positivos esperando que las etapas posteriores puedan encargarse de reducir esta tasa
mediante clasificadores más especializados. Con esto se pretende también reducir la
tasa de falsos negativos en el clasificador final, ya que una sub-imagen será clasificada
como cara sólo en el caso de que haya pasado por todas las etapas del clasificador.
2.2.8 Reconocimiento de caras
El reconocimiento de caras es una técnica biométrica para la identificación de
personas mediante características del rostro. Existen diversas aplicaciones prácticas,
abarcando numerosas disciplinas, donde puede utilizarse el reconocimiento de rostros.
Estas aplicaciones exigen a un sistema de reconocimiento de rostros a enfrentar
diferentes condiciones de capacidad de procesamiento, memoria, velocidad, sensibilidad
a cambios en la cara y variabilidad de las imágenes utilizadas, etc.
Dos problemas centrales en un sistema automático de reconocimiento de caras son
la selección de características para la representación del rostro y su clasificación basada
en la representación de las características elegidas. Dicha selección de características
puede ser afectada por variaciones en las imágenes de caras, como la iluminación,
expresión y pose.
El reconocimiento de caras es un problema de clasificación utilizando datos de alta
dimensión, por lo que para permitir un reconocimiento rápido y robusto es necesario
realizar tareas de reducción de dimensión (extracción de características), se hará durante
proceso de detección de rostros (antes de la clasificación). Los métodos de reducción de
dimensión pueden clasificarse en dos categorías principales. Una de ellas se basa en
extraer características faciales de la imagen como por ejemplo, ojos, boca, etc. El otro
INTRODUCCIÓN
11
enfoque, denominado holístico, toma toda la región de la cara como dato de entrada para
el reconocimiento. Los métodos holísticos principales son Eigenfaces y Fisherfaces.
Eigenfaces es construido sobre técnicas de Análisis de Componentes Principales
(PCA) introducido por M.A. Turk and A.P. Pentland. Las técnicas de Análisis de
Componentes Principales consiguen una reducción de la dimensión proyectando los
datos sobre la dirección que maximice la distribución total sobre todas las clases.
Fisherfaces es un método propuesto por Belhumeur en el que se utiliza PCA y el
Discriminante Lineal de Fisher (FLD) o LDA. Este método maximiza la relación entre la
distribución entre clases y la distribución entre clases y en principio más potente que el
anterior.
Hay muchos documentos que comparan ambos métodos con resultados distintos
en función de las variaciones que puedan aparecer (luz, pose, etc.). En general, se ha
demostrado que el algoritmo de Fisherfaces es mucho más efectivo tanto en variaciones
de iluminación como de pose, sobre todo en condiciones donde la luminosidad es peor.
El problema viene dado que pese a que Fisherfaces es muy superior, dicho método
resulta computacionalmente mucho más costoso y posee menos posibilidad de error.
2.2.9 Algoritmo de reconocimiento EigenFaces
Este método realiza una proyección lineal del espacio de imágenes a un espacio de
características de menor dimensión. Esta reducción se realiza utilizando la técnica PCA,
la cual toma aquella proyección lineal que maximice la dispersión de todas las imágenes
proyectadas.
En primer lugar se considera un conjunto de N imágenes con valores en el espacio
de imágenes n-dimensional.
𝑥𝑖 𝑖 = 1,2, … , 𝑁
(Fórmula 2.3)
Además se asume que cada una de estas imágenes pertenece a una de las c
clases 𝑋1 , 𝑋2 , … , 𝑋𝑐 . Asimismo, se considera una transformación lineal que lleva el
espacio de imágenes original de n dimensiones al espacio de características de
CONCEPTOS
12
dimensión m, donde m < n. Los nuevos vectores de características y k ∈ ℜ𝑚 son
definidos por la siguiente transformación lineal.
𝑦𝑘 = 𝑊𝑇𝑥𝑘 𝑘 = 1,2, … , 𝑁
(Fórmula 2.4)
Donde W ∈ ℜ𝑛𝑥𝑚 es una matriz con columnas ortonormales. Se define asimismo la
matriz de distribución total 𝑆𝑇 como:
𝑆𝑇 = 𝑥𝑘 − 𝜇 𝑥𝑘 − 𝜇 𝑇
𝑁
𝑘=1
(Fórmula 2.5)
Donde 𝜇 ∈ ℜ𝑛 es la media de todas las imágenes de la fórmula 2.3. Luego de
aplicar la transformación lineal 𝑊𝑇, la distribución de los vectores de características
𝑦1 , 𝑦2 , … , 𝑦𝑁 es 𝑊𝑇𝑆𝑇𝑊. Se toma aquella proyección 𝑊𝑜𝑝𝑡 que maximiza el determinante
de la distribución total de la matriz de las imágenes proyectos, siendo esto:
𝑊𝑜𝑝𝑡 = arg max𝑊
𝑊𝑇𝑆𝑇𝑊 = 𝑤1 𝑤2 … 𝑤𝑚
(Fórmula 2.6)
Donde 𝑤𝑖 | 𝑖 = 1,2, … , 𝑚 es el conjunto de vectores propios n-dimensionales de 𝑆𝑇
correspondiente a los mayores m vectores propios. Dichos vectores propios tienen la
misma dimensión que las imágenes originales y se les denomina EigenFaces y son los
que se usaran para un reconocimiento efectivo.
OBJETIVOS
13
3. OBJETIVOS
El principal objetivo es lograr una aplicación que detecte las caras en movimiento
en un vídeo dado. El vídeo arrancará cuando se indique, capturará la cara o caras,
identificará al personal y guardará información relativa a la entrada o salida del empleado
para tener control de la asistencia profesional. La cámara estará situada en una zona de
manera estática y conectada a un equipo de bajo coste.
Para conseguir la aplicación se pretende realizar el estudio de un algoritmo que
permite la identificación de caras en función de unos patrones. Uno de los algoritmos que
se va a implementar se denomina Haar-like, y corresponde a un algoritmo de extracción
de características.
Por lo que podemos identificar los objetivos en los siguientes:
Realización de una aplicación para el control de asistencia profesional, usando un
equipo informático de bajo coste.
Reconocimiento facial detectando la cara en movimiento y comparándola con la
BBDD para su identificación. Este proceso de identificación se realizará de
manera automática, teniendo como fuente de datos una Base de datos de
imágenes.
Gestión de datos relativos al control de asistencia para la monitorización de
horarios de entrada y salida de empleados.
HARDWARE
14
4. MATERIALES Y MÉTODOS
4.1. Hardware
4.1.1. Introducción
Actualmente existe una gran cantidad de equipos informáticos que podrían usarse
para la aplicación desarrollada funcione sin ningún tipo de problema. Las últimas mejoras
en hardware y la búsqueda de equipos pequeños de bajo coste que tengan una gran
funcionalidad están permitiendo poder acceder a una gran variedad de sistemas.
4.1.2. Elección de Hardware
Para la elección del Hardware se ha tenido en cuenta que el equipo informático
tenga el mínimo gasto posible permitiendo funcionar correctamente la aplicación. Aparte,
es interesante encontrar un equipo que ocupe el menor tamaño posible y que permita
actualizaciones de manera fácil y rápida. El hecho de tener una gran comunidad detrás
de desarrollo e innovación es un gran hándicap para posibles mejoras a corto plazo.
Por ello, se ha elegido la placa computadora “Raspberry Pi Modelo B”, como
cámara se usará la cámara Pi, además necesitaremos una tarjeta SD donde incluiremos
el sistema operativo, los módulos y las librerías de la aplicación. Para su funcionamiento
necesitará una fuente de alimentación de 5V y 2000mA por si quisiéramos añadir algún
componente más. Añadiremos un adaptador WIFI para poder enviar los datos o poder
acceder al equipo mediante SSH mediante Xming cuando sea necesario. Y, por último,
incluiremos una caja de plástico protectora. Todo por apenas 50€.
4.1.3. Características del Hardware usado
4.1.3.1. Raspberry pi
Raspberry Pi es una placa computadora (ordenador de placa reducida (SBC)) de
muy bajo costo desarrollada en Reino Unido por la Fundación Raspberry Pi con el
objetivo de estimular la enseñanza de ciencias de la computación en temas de formación
en las escuelas o universidades.
MATERIALES Y MÉTODOS
15
El diseño de la Raspberry Pi (figura 4.1) incluye un System-on-a-chip Broadcom
BCM2835, que contiene un procesador central (CPU) ARM1176JZF-S a 700 MHz (el
firmware incluye unos modos turbo para que el usuario pueda hacerle overclock de hasta
1 GHz), un procesador gráfico (GPU) VideoCore IV y 512 MB de memoria RAM, aunque
originalmente eran 256 MB. El diseño no incluye un disco duro o una unidad de estado
sólido, ya que usa una tarjeta SD para el almacenamiento permanente; tampoco incluye
fuente de alimentación o carcasa. Podemos ver cómo es la Raspberry en la figura 4.1.
El 29 de febrero de 2012 la fundación empezó a aceptar órdenes de compra del
modelo B, y el 4 de febrero de 2013 del modelo A. Las características individuales y
conjuntas de cada modelo vienen especificadas más adelante:
Figura 4.1 Dispositivo Raspberry Pi
Podemos identificar cada parte de la Raspberry en la figura 4.2:
HARDWARE
16
Figura 4.2 Partes de Raspberry Pi
(Fuente: http://www.openhardware.pe/store/raspberry_pi_model_b)
El dispositivo Raspberry Pi usado tendrá, aparte, una caja de plástico protectora
para evitar que se dañe. La escogida es transparente para tener una buena visión de
cada componente.
Tabla de Características de las distintas Raspberry Pi podemos verlo en la Tabla
4.1:
Modelo A Modelo B
Chip del Sistema Broadcom BCM2835 (CPU + GPU + DSP + SDRAM + puerto USB)
CPU ARM 1176JZF-S a 700 MHz (familia ARM11)
Juego de instrucciones RISC de 32 bits
GPU Broadcom VideoCore IV, OpenGL ES 2.0, MPEG-2 y VC-1 (con licencia),
1080p30 H.264/MPEG-4 AVC
Memoria (SDRAM) 256 MiB (compartidos con la GPU) 512 MiB (compartidos con la GPU)
Puertos USB 2.0 1 2 (vía hub USB integrado)
Entradas de vídeo Conector MIPI CSI que permite instalar un módulo de cámara
desarrollado por la RPF
Salidas de vídeo Conector RCA (PAL y NTSC), HDMI (rev1.3 y 1.4), Interfaz DSI para panel
MATERIALES Y MÉTODOS
17
LCD
Salidas de audio Conector de 3.5 mm, HDMI
Almacenamiento
integrado SD / MMC / ranura para SDIO
Conectividad de red Ninguna 10/100 Ethernet (RJ-45) vía HUB
USB
Periféricos de bajo
nivel 8 x GPIO, SPI, I2C, UART
Reloj en tiempo real Ninguno
Consumo energético 500 mA (2.5 W) 700 mA (3.5 W)
Fuente de
alimentación 5 V vía Micro USB o GPIO header
Dimensiones 85.60 mm × 53.98 mm (3.370 × 2.125 pulgadas)
Sistemas Operativos
Soportados
GNU/Linux: Debian (Raspbian), Fedora (Pidora), Arch Linux (Arch Linux
ARM), Slackware Linux. RISC OS2
Tabla 4.1 Características de Modelos de Raspberry Pi
Actualmente, ha aparecido un nuevo modelo más potente denominado modelo B+
que añade al modelo B, 2 puertos USB mas, ranura para tarjeta micro SD y nuevo
conector GPIO de 40 pines.
4.1.3.2. Pi-Cámara
La Pi-Cámara, PiCam o RaspiCam (figura 4.3), es una cámara de 5 MP (mega
píxel) la cual es capaz de capturar vídeo a 1080p (1920x1080 píxeles) y también
imágenes una vez conectada a una placa Raspberry Pi. Para utilizarla, simplemente
necesita ser conectada directamente con su cable tipo Ribbon al conector SCI (Camera
Serial Interfaz) de la Raspberry Pi.
HARDWARE
18
Figura 4.3 Pi-Cámara
La placa es muy pequeña, de 25 x 20 x 9 mm, y pesa apenas 3 gramos, por lo que
es perfecta para aplicaciones móviles o cualquier otra aplicación donde el tamaño
reducido sea muy importante.
En cuanto a imágenes, el sensor que tiene incorporado es capaz de capturar hasta
2592x1944 píxeles. Sin embargo, en modo vídeo las resoluciones soportadas son:
1080píxeles a 30fps (fotograma por segundo), 720 píxeles a 60fps y 640x480píxeles a
60/90fps.
La cámara está preparada para la captura de imágenes y vídeo pero sin sonido, por
no poseer micro incorporado.
La cámara es perfecta tanto por su tamaño, eficiencia, bajo coste y por su
compatibilidad con la Raspberry Pi.
4.2. Software
4.2.1. Raspbian
Raspbian (figura 4.4) es una distribución libre del sistema operativo GNU/Linux,
basado en “Debian Wheezy” (versión 7.0) y optimizado para funcionar con la Raspberry
Pi. Fue orientada inicialmente para la enseñanza de informática cuyo lanzamiento inicial
fue en junio de 2012.
MATERIALES Y MÉTODOS
19
Figura 4.4 Logo de Raspbian
Pese a que el sistema operativo Raspbian, es un software adaptado no oficial de
“Debían Wheezy”, se tuvo que hacer esa adaptación de Debian al no haber una versión
válida para la CPU ARMv6 que contiene el Raspberry PI. Está optimizado para realizar
cálculos en coma flotante por software, lo que permite un mayor rendimiento en diversas
situaciones, lo que la hace ideal para el computador RaspberryPi.
Raspbian usa un entorno de escritorio ligero denominado LXDE. Es bastante usable
y ligera, manteniendo una baja utilización de recursos y energía, la cual sirve
eficientemente teniendo en cuenta la memoria que dispone la Raspberry Pi. Los
componentes que la incluyen son independientes, para que pueda usarse en función de
las necesidades.
Como navegador web, tiene a Midori. Además, contiene herramientas de desarrollo
como IDLE para el lenguaje de programación Python o Scratch.
Se debe destacar el menú "raspi-config", que permite configurar el sistema
operativo sin tener que modificar archivos de configuración manualmente. Entre sus
funciones, permite expandir la partición root para que ocupe toda la tarjeta de memoria,
configurar el teclado, aplicar overclock, etc.
Incluye un servicio de venta de aplicaciones. En esta plataforma se puede poner a
disposición de todos los usuarios de Raspbian, mediante moderación y posterior
lanzamiento, contenidos gratuitos o de pago, como archivos binarios, código python,
imágenes, audio o vídeo. Además, incluye documentación acerca de la Raspberry Pi,
como revistas y tutoriales de proyectos realizados con la Raspberry Pi.
SOFTWARE
20
El hecho de usar la distribución Raspbian es debido a la gran funcionalidad que
permite a la hora de ejecutar, el bajo coste de recursos y energía, así como lo optimizado
que funciona. Añadimos que, gracias a una gran comunidad, se ha avanzado y mejorado
rápidamente su integración.
4.2.2. QT
Qt (figura 4.5) es una librería multiplataforma muy utilizada para el desarrollo de
aplicaciones con una interfaz gráfica de usuario. También es usada para el desarrollo de
programas sin interfaz gráfica, como herramientas para la línea de comandos y consolas
para servidores o procesos.
Figura 4.5 Logo de Qt
Qt es desarrollada como un software libre y de código abierto a través de Qt
Project, donde participa desarrolladores de Nokia, Digia y otras empresas, así como la
comunidad.
Qt es utilizada en KDE (equipo internacional que coopera en el desarrollo y
distribución de software libre y de código abierto para computadoras de escritorio y
portátiles), entorno de escritorio para sistemas como GNU/Linux o FreeBSD, entre otros.
Qt utiliza el lenguaje de programación C++ de forma nativa, en el cual está hecho el
código del proyecto. Adicionalmente, puede ser utilizado en varios otros lenguajes de
programación a través de bindings (adaptación de una biblioteca para ser usada en un
lenguaje de programación distinto de aquél en el que ha sido escrita). Aparte, es usada
en sistemas informáticos incrustados en temas de automoción, aeronavegación y
aparatos domésticos como microondas.
MATERIALES Y MÉTODOS
21
Funciona en la mayoría de las plataformas y tiene un gran apoyo. El API de la
biblioteca cuenta con procedimientos para poder acceder a bases de datos, ya sea
mediante SQL, así como el uso de XML, gestión de hilos, soporte de red, para una API
multiplataforma unificada para la manipulación de archivos y una multitud de otros para el
manejo de ficheros, además de estructuras de datos tradicionales.
4.2.3. OpenCV
En este sub-apartado se hará hincapié en la librería de visión por computador OpenCV.
Figura 4.6 Librería OpenCV
4.2.3.1. Introducción
OpenCV u Open Source Computer Vision Library (figura 4.6) es una librería de
código abierto para el tratamiento de imágenes que incluye varios cientos de algoritmos
de visión por computador, destinada principalmente a aplicaciones de visión por
computador en tiempo real. Esta publicada bajo una licencia BSD, lo cual permite que
sea usada libremente para propósitos comerciales y académicos. Es multiplataforma,
existiendo versiones para los sistemas operativos de Windows, GNU/Linux, Mac OSX,
iOS y Android. Además, podemos encontrar interfaces para los lenguajes C, C++, Java y
Python.
Una de las metas de OpenCV es proporcionar una infraestructura de visión por
computador, simple de usar, que ayude a la gente a construir rápidamente sofisticadas
aplicaciones de visión. La biblioteca de OpenCV contiene cerca de 500 funciones que
SOFTWARE
22
abarcan muchos campos en visión, desde la imagen médica, calibración de cámaras o
robótica.
La licencia de código abierto de OpenCV se ha realizado de forma que es posible
construir un producto comercial usando todo o parte de OpenCV. No es obligatorio
mostrar el código del producto ni las mejoras realizadas al dominio público.
OpenCV está encaminado en proveer las herramientas básicas necesarias para
resolver los problemas de la visión por computador. En algunos casos, las
funcionalidades de alto nivel en la biblioteca serán suficientes para resolver los problemas
más complejos de la visión por computador. Incluso cuando no sea el caso, los
componentes básicos en la biblioteca serán suficientes para permitir la creación de una
solución completa por parte del usuario en prácticamente cualquier problema de visión.
Posee una estructura modular, estando agrupadas la mayoría de funciones de la
biblioteca en los siguientes módulos:
CORE: donde se definen las estructuras de datos básicas que utilizan el resto
de módulos.
IMGPROC: módulo de procesamiento de imágenes, donde encontraremos
funciones para el filtrado lineal/no lineal, transformaciones afines, conversión del
espacio de color, histogramas, etc.
VIDEO: modulo de análisis de vídeo que incluye algoritmos para la estimación
del movimiento, extracción del fondo y seguimiento de objetos.
CALIB3D: Algoritmos básicos de visión múltiple como calibración de cámaras
estéreo, correspondencia o reconstrucción 3D.
FEATURES2D: detectores de características, descriptores y comparadores.
OBJDETECT: detección de objetos e instancias de las clases predefinidas,
como por ejemplo: caras, ojos, gente, coches….
HighGUI: todo lo relacionado a la interfaz grafica de OpenCV y las funciones
que permiten importar imágenes y vídeo.
MATERIALES Y MÉTODOS
23
GPU: algoritmos acelerados por hardware para distintos módulos OpenCV.
4.2.3.2. Funciones básicas
Las funciones básicas a mostrar de OpenCV estarán implementadas en C++ debido
a que el trabajo fin de grado está realizado en C++.
cvLoadImage ( pathFile ): nos permite cargar una imagen desde un fichero en
un objeto de tipo IplImage, también propio de OpenCV. Después, con ese
objeto podemos hacer las modificaciones que necesitemos para nuestra
aplicación. Reserva la memoria necesaria para la estructura de datos de la
imagen y devuelve un puntero. Este puntero se utiliza para manipular tanto la
imagen como sus datos.
cvSaveImage ( cadena.c_str(), im ): permite guardar una imagen en un fichero.
La ruta del fichero resultante se especifica con la cadena que precede al
argumento de la imagen.
cvShowImage (constchar* name, constCvArr* image ): Muestra la imagen en la
ventana especificada. Parámetros:
o name: Nombre de la ventana.
o image: Imagen a ser mostrada.
cvWaitKey (intmseg): Detiene la ejecución del programa y espera una
interrupción de teclado. Si se le pasa como argumento un número positivo, el
programa espera ese número de milisegundos y, de no producirse antes la
interrupción, sigue con la ejecución. Si el argumento es 0 o un número
negativo, el programa espera indefinidamente a que se pulse una tecla.
cvReleaseImage ( constIplImage* image ): Esta función libera la memoria
reservada para contener la estructura de datos de la imagen. Una vez realizado
esto, el puntero imagen apunta a NULL.
SOFTWARE
24
cvReleaseCapture ( CvCapture** capture ): Libera la memoria usada con la
estructura CvCapture. Esta función también cierra cualquier archivo abierto que
referencie al archivo AVI.
cvDestroyAllWindows ( ): Cierra la ventana y recolocará el uso de la memoria
asociada.
cvDestroyWindow ( constchar* name ): Cierra la ventana especificada y
recolocará el uso de la memoria asociada.
IplImage* cvCloneImage ( constIplImage* image ): Crea una copia de la imagen
que se le pasa como parámetro.
CvHistogram* cvCreateHist (intcDims, int* dims, inttype, float** ranges=0,
intuniform=1 ): crea un histograma con el tamaño especificado y devuelve un
puntero al histograma creado. Parámetros:
o cDims: Dimensiones del histograma.
o dims: Tamaño del vector del histograma.
o type: Formato para la representación del histograma. Puede ser
CV_HIST_TREE y CV_HIST_ARRAY.
o ranges: Vector de rangos para el histograma.
o uniform: Flag de uniformidad.
Int cvNamedWindow ( const char* name, int flags=CV_WINDOW_AUTOSIZE ):
crea una ventana de OpenCV. Esta ventana permite mostrar imágenes, pintar
objetos o cualquier aspecto visual que se encuentre dentro de la librería
OpenCV. Si una ventana con el mismo nombre ya existe, la función no tiene
efecto. Parámetros:
o name: Nombre de la venta que será usado como identificador y
aparece en la barra de título.
MATERIALES Y MÉTODOS
25
o Flags: El único flag soportado es CV_WINDOW_AUTOSIZE. Si se
introduce la ventana se redimensiona automáticamente en función
del tamaño de lo mostrado en la ventana.
CvCapture* cvCreateFileCapture ( constchar* filename ): Obtiene un puntero a
una estructura de datos CvCapture del vídeo cargado. Esta estructura contiene
toda la información sobre el archivo AVI que está siendo leído, incluyendo su
información de estado. El puntero apunta al principio del video.
IplImage* cvQueryFrame ( CvCapture* capture ): toma como argumento el
puntero a la estructura CvCapture. Si no se ha mostrado todavía el último
fotograma, el fotograma obtenido con cvQueryFrame() se muestra por pantalla.
Void rectangle ( Mat&img, Point pt1, Point pt2, constScalar& color,
intthickness=1, intlineType=8, intshift=0 ): Dibuja un rectángulo con el tamaño
de línea y tamaño indicado en la imagen introducida por parámetros. Muestra
los resultados de los objetos obtenidos por detectMultiScale. Parámetros:
o img: Imagen donde queremos pintar.
o pt1: Uno de los vértices del rectángulo.
o pt2: El punto opuesto a pt1 formando una de las diagonales del
rectángulo.
o color: Color del rectángulo o brillo en imagen en escala de grises.
o thickness: Grueso de la línea.
o LineType: Tipos de líneas soportadas: “8” (o omitido): 8 líneas
conectadas, “4”: 4 líneas conectadas y CV_AA: línea suavizada.
o shift: Número de bits fraccionales en las coordenadas del punto.
Ahora, vamos a incluir dos ejemplos prácticos del uso de funciones OpenCV para
abrir imagen y cargarla en pantalla y para mostrar un vídeo que se encuentre guardado
en una ruta determinada.
SOFTWARE
26
Ejemplo 1: Cargar imagen.
Programa escrito en C utilizando algunas de las herramientas proporcionadas por la
biblioteca OpenCV para crear un programa que abra una imagen y la muestre por
pantalla:
//Librería básica de C
#include <stdio.h>
//Cargamos librerías OpenCV
#include "cv.h"
#include "highgui.h"
// se define el fichero que mostraremos
char nombre[]="default.jpg";
int main()
{
//Carga la imagen
IplImage* imagen = cvLoadImage(nombre);
//Abre ventana en pantalla para contener y mostrar imagen.
//defecto es el nombre de la ventana.
cvNamedWindow( "defecto", CV_WINDOW_AUTOSIZE);
//Muestra la imagen en la ventana especificada.
cvShowImage( "defecto", imagen );
//Espera una interrupción de teclado para terminar.
cvWaitKey(0);
//Cierra la ventana y recolocará el uso de memoria asociado.
cvDestroyAllWindows();
//Libera la memoria reservada.
cvReleaseImage(&imagen);
//Salimos de ejecución.
return 0;
}
Ejemplo 2: Cargar vídeo.
Programa que abra un video almacenado en disco y lo reproduzca mostrando su
contenido por pantalla, el cual estará comentado:
MATERIALES Y MÉTODOS
27
//Cargamos librería de OpenCV
#include “highgui.h”
//Iniciamos función, e indicamos que se le pasaran parámetros
Int main(int argc, char** argv)
{
//Abre ventana en pantalla para contener y mostrar imagen.
//Ejemplo es el nombre de a ventana.
cvNamedWindow(“Ejemplo”, CV_WINDOW_AUTOSIZE);
//Obtiene un puntero a estructura CvCapture del video.
cvCapture* capture = cvCreateFileCapture(argv[1]);
//Definimos cada imagen del vídeo.
IplImage* frame;
//Indica el Nº fotograma por el que va.
Int frameIndex = 0;
//Leemos el archivvo AVI
while(1)
{
//Muestra el fotograma por el que va.
frame = cvQueryFrame(capture);
//Si llegamos al final, salimos
if(!frame) break;
//Muestra la imagen en la ventana especificada.
cvShowImage(“Ejemplo”, frame);
//Espera la pulsacíon de una tecla
char c = cvWaitKey(33);
//Si es la tecla ESC, sale de ejecución
//ESC = ASCII 27
if (c==27) break;
}
//Libera la memoria usada y cierra AVI abierto
cvReleaseCapture(&capture);
//Cierra la ventana "Ejemplo"
//Y recolocará el uso de memoria asociada.
cvDestroyWindow(“Ejemplo”);
}
SOFTWARE
28
4.2.3.3. Algoritmo Haar-Like
A continuación, se especificarán algunas de las funciones de OpenCV que integran
el algoritmo Haar-Like.
cv::CascadeClassifierface_cascade: Para llevar a cabo una clasificación de
imágenes buscando por el método de Viola-Jones algún patrón dentro de una
imagen, necesitamos un clasificador en cascada. Dentro de OpenCV podemos
declarar un clasificador cv::CascadeClassifier y después utilizarlo con algún
propósito.
face_cascade.load ( face_cascade_name ): Los clasificadores en cascada
están definidos en un formato concreto dentro de OpenCV. Este formato está
incluido dentro de ficheros XML que determinan cuántos pasos tiene el
clasificador y qué características de Haar utiliza. OpenCV incorpora dentro de
la librería algunos operadores y para utilizarlos debemos cargar el clasificador
dentro del objeto cv::CascadeClassifier indicando la ruta del fichero en el
parámetro name.
Void CascadeClassifier::detectMultiScale ( const Mat&image,
vector<Rect>&objects, doublescaleFactor=1.1, intminNeighbors=3, intflags=0,
SizeminSize=Size() ): La función detectMultiScale lleva a cabo la detección de
objetos dentro de una imagen. Los objetos encontrados son devueltos en un
vector de Rectángulos que indican la localización y el tamaño. Parámetros:
o image: Matriz de tipo CV_8U que contiene una imagen en la que se
detectan objetos.
o Objects: Vector de rectángulos que pasado por referencia retorna un
objeto detectado por cada rectángulo.
o ScaleFactor: Durante el proceso de detección el sistema prueba
diferentes tamaños para encontrar objetos dentro de las imágenes.
Este factor indica cuánto se modifica ese tamaño en cada paso de
detección.
MATERIALES Y MÉTODOS
29
o MinNeighbors: Especifica cuántos vecinos candidatos deberá tener
un rectángulo candidato para mantenerlo.
o flags: Este parámetro no se utiliza en los nuevos clasificadores en
Cascada y tiene el mismo significado que en la función
cvHaarDetectObjects que veremos en este punto. La detección de
caras está optimizada por CV_HAAR_SCALE_IMAGE más que por
el método por defecto, 0 CV_HAAR_DO_CANNY_PRUNING5.
o MinSize: El espacio mínimo posible de objeto. Objetos más
pequeños que eso serán ignorados.
IntPtrcvHaarDetectObjects ( constCvArr* image, CvHaarClassifierCascade*
cascade, vector<Rect>&storage, doublescale_factor=1.1, intmin_neighbors=3,
intflags=0, CvSizemin_size=cvSize(0,0), CvSizemax_size=cvSize(0,0) ):La
función cvHaarDetectObjects encuentra regiones rectangulares en la imagen
que pueden contener los objetos buscados, la cascada ha sido entrenada para
esas regiones, y los devuelve como una secuencia de rectángulos. La función
analiza la imagen varias veces a diferentes escalas. Cada vez que considere
regiones superpuestas en la imagen se aplican los clasificadores a las regiones
con cvRunHaarClassifierCascade. También puede aplicar un poco
razonamiento heurístico para reducir el número de regiones analizadas, tales
como podría pasar con filtro de Canny. Después del procesamiento y la
reagrupación de los rectángulos candidatos (regiones que pasan la cascada del
clasificador), se agrupan y devuelven como una secuencia de rectángulos
promedio de cada grupo lo suficientemente grande.
o image: Matriz de tipo CV_8U que contiene una imagen en la que se
detectan objetos.
o cascade: Clasificador de cascada Haar. Puede ser cargado desde un
fichero XML o YAML usando Load(). Cuando la cascada no es
necesaria, se liberará usando la función
cvReleaseHaarClassifierCascade( &cascade ).
o storage: Área de memoria utilizada para almacenar un vector de
rectángulos que retorna un objeto detectado por cada rectángulo.
SOFTWARE
30
o scaleFactor: Durante el proceso de detección el sistema prueba
diferentes tamaños para encontrar objetos dentro de las imágenes.
Este factor indica cuánto se modifica ese tamaño en cada paso de
detección.
o minNeighbors: Especifica cuántos vecinos candidatos deberá tener
un rectángulo candidato para mantenerlo.
o flags: Este parámetro no se utiliza en los nuevos clasificadores en
cascada y tiene el mismo significado que en la función
cvHaarDetectObjects.
o minSize: El espacio mínimo posible de objeto. Objetos más
pequeños que eso serán ignorados.
o maxSize: El espacio máximo posible de objeto. Objetos más grandes
que eso serán ignorados.
cvReleaseHaarClassifierCascade ( CvHaarClassifierCascade*cascade): Esta
función libera la memoria usada con la estructura CvHaarClassifierCascade.
o cascade: Clasificado de cascada Haar que será liberada.
CvHaarClassifierCascade* cvLoadHaarClassifierCascade ( constchar*
directory, CvSizeorig_window_size ):Clasificador de cascada a entrenar que se
carga desde un archivo o desde una base de datos que estará incluida en
OpenCV. Esta función está obsoleta, pero podemos usarla para pruebas.
o directory: La ruta donde estará el clasificador de cascada.
o orig_window_size: Tamaño original que tendrá el clasificador de
cascada a la hora de realizar la detección. Esta información no se
almacena en el clasificador de cascada, por lo que destacar.
cvSetImagesForHaarClassifierCascade ( CvHaarClassifierCascade* cascade,
constCvArr* sum, constCvArr* sqsum, constCvArr* tilted_sum, doublescale ):
La función cvSetImagesForHaarClassifierCascade asigna imágenes y/o
MATERIALES Y MÉTODOS
31
ventanas de escala al clasificador de cascada oculta. La función se utiliza para
preparar la cascada para la detección de objetos del tamaño concreto en la
imagen concreta. La función es llamada internamente por la
funcióncvHaarDetectObjects, pero puede ser llamado por el usuario si es
necesario en el uso de cvRunHaarClassifierCascade, visto en siguiente punto.
Esta función es equivalente a la usada en C++ denominada
CascadeClassifier::setImage.
o cascade: Clasificador en cascada de Haar oculto creada por la
funciónCreateHidHaarClassifierCascade.
o sum: Suma de las imágenes en formato entero de 32 bits. Esta
imagen, así como las dos imágenes subsiguientes se utilizan para la
evaluación rápida de características y para la normalización del brillo
y contraste. Todos ellos se pueden recuperar con la entrada de una
imagen de 8 bits o de punto flotante al usarla función Integral.
o sqsum: Imagen del cuadrado en formato de 64 bits.
o tilted_sum: Imagen inclinada en formato de 32 bits (entero).
o scale: Escala de la ventana para la cascada. Si la escala es igual a
1, se utiliza el tamaño original de la ventana (se buscan objetos de
ese tamaño) el cual es el mismo tamaño que se especifica en
LoadHaarClassifierCascade (24x24 en el caso de
default_face_cascade), si la escala es igual a 2, sería dos veces más
grande la ventana se utilizará (48x48 en el caso de la cara por
defecto en cascada).
cvRunHaarClassifierCascade ( constCvHaarClassifierCascade* cascade,
CvPoint pt, intstart_stage=0 ): La función cvRunHaarHaarClassifierCascade
ejecuta un clasificador Haar en cascada en una única localización de la
imagen. Antes de utilizar esta función las imágenes integrales y la escala
apropiada (tamaño de la ventana) deben establecerse mediante
cvSetImagesForHaarClassifierCascade, visto en punto anterior. La función
devuelve un valor positivo si los rectángulos analizados (candidatos) han
SOFTWARE
32
superado todas las etapas del clasificador y devuelve cero o un valor negativo
si no las superan.
o cascade: Clasificador de cascada Haar. Puede ser cargado desde un
fichero XML o YAML usando Load(). Cuando la cascada no es
necesaria, se liberará usando la función anteriormente indicada
cvReleaseHaarClassifierCascade ( &cascade ).
o pt: Puntero al punto de la ventana donde se calculan las
características. El tamaño de la ventana es igual al tamaño de
imágenes del entrenamiento.
o start_stage: Indica en que etapa empezará a funcionar contando
desde 0, La función asumirá que ha pasado por todas las etapas
previas.
Se puede ver que existe una gran cantidad de funciones relacionadas con el
algoritmo Haar.
4.3 Programa de Gestión
4.3.1 Introducción
Para realizar el programa de gestión se ha estructurado la programación en tres
partes, la primera de la obtención de información con la captura de las caras de los
empleados y su guardado en un fichero para tener controlado cada empleado para un
posterior detección. En segundo lugar, estará la parte, que nos ocupa principalmente el
trabajo fin de grado, para detectar el empleado, y guardado de información. Para la
identificación del empleado usaremos algunas de las librerías existentes en OpenCV y
algunas funciones que se han creado para poder trabajar con la cámara CamPi de
manera eficiente, y por último, el envío de esta información a un servidor FTP para un
posterior guardado y análisis en una base de datos.
La distribución del programa de gestión, se divide en dos carpetas, una para el
código de guardar la imagen, y otra para el reconocimiento, y de subcarpetas, la carpeta
con las imágenes de los empleados, de los ficheros de texto con la información del
control de asistencia, y los ficheros de control que podemos ver en la figura 4.7:
MATERIALES Y MÉTODOS
33
Figura 4.7 Carpetas de trabajo
A continuación, se va a incluir el diagrama de bloques de cada apartado, para pasar
a diferenciar cada apartado, indicando las variables que lo incluyen, las funciones que la
forman y los parámetros que se le pasan.
4.3.2 Diagrama de Bloques
Podemos diferenciar la aplicación en varias partes, la captura de imágenes y su
guardado, el reconocimiento de caras y la gestión de esa información.
Los diagramas de bloques a tener en cuenta para entender la estructura que se ha
seguido para la implementación de cada apartado son los siguientes:
A. Diagrama de Bloques de Captura de Caras:
El diagrama de bloques a tener en cuenta para entender el funcionamiento
que se ha seguido en el módulo de detección de caras y el guardado de
imágenes, viene representado en la figura 4.8:
PROGRAMA DE GESTIÓN
34
Figura 4.8 Diagrama de Bloques de Captura de Caras
MATERIALES Y MÉTODOS
35
A continuación se realizará una breve descripción del proceso definido en
el diagrama anterior en que el estará basada la funcionalidad que recoge las
variables y funciones de la aplicación de detección y guardado de imágenes del
empleado.
Inicio. En el comienzo de la aplicación tendrá lugar toda la creación y
asignación de variables y de librerías tanto básicas, como de
OpenCV.
Datos de Entrada. Se recogerán los datos de entrada que son el
nombre del empleado a guardar imágenes de su cara, y el
histograma.
Inicialización de Valores. Se inicializarán las variables básicas
correspondientes al tratamiento del video, y de la cámara.
Carga de Componentes. Se crea y carga los componentes de la
cámara, del modelo de detección Haar, y del decodificador de
imágenes recibidas por la PiCam.
Lectura de CSV. Se obtienen datos de los ficheros CSV como el
identificador del empleado, el cual será el que venga del fichero
cfg.csv o uno nuevo sino está. Así como el contador de imágenes
relacionado con empleado a guardar sus imágenes de cara para su
futuro reconocimiento en el proceso de control de asistencia.
Detección de Caras. Mediante el método de Haar se realiza la
detección de caras de la captura recibida desde la PiCam, necesario
para el siguiente paso. Este proceso se repetirá durante el tiempo
que este prefijado por la variable de estado. Una vez terminado,
pasará a cerrar la aplicación.
Guardado de imágenes y actualización de CSV. Una vez detectada
un rostro o cara en el paso anterior, se pasa a recortar la imagen,
recogiendo solo la cara, y en función de los datos de empleado, se
PROGRAMA DE GESTIÓN
36
guardará la imagen y actualizará los ficheros csv. Las imágenes
recogerán solo la cara y de manera redimensionada, que es como
necesita el algoritmo de reconocimiento tener los rostros.
Cierre de aplicación. Una vez terminada la captura desde la PiCam al
terminar tiempo de espera, se pasa a mostrar información sobre el
visionado y a cerrar la aplicación.
B. Diagrama de Bloques de Reconocimiento de Caras:
El diagrama de bloques a tener en cuenta para entender el funcionamiento
que se ha seguido en el módulo de reconocimiento de caras y el guardado de
datos de control relacionados, viene representado en la figura 4.9:
MATERIALES Y MÉTODOS
37
Figura 4.9 Diagrama de Bloques de Reconocimiento de caras
PROGRAMA DE GESTIÓN
38
A continuación se realizará una breve descripción del proceso definido en
el diagrama anterior en que el estará basada la funcionalidad que recoge las
variables y funciones de la aplicación de detección, reconocimiento del
empleado que aparece en la captura de PiCam y el guardado del fichero de
control de asistencia:
Inicio. En el comienzo de la aplicación tendrá lugar toda la creación y
asignación de variables y de librerías tanto básicas, como de
OpenCV.
Datos de Entrada. Se recogerán los datos de entrada que son el
fichero de configuración de empleados, el fichero de rutas de las
imágenes, el histograma y el umbral de predicción.
Inicialización de Valores. Se inicializarán las variables básicas
correspondientes al tratamiento del video, y de la cámara.
Carga de Componentes. Creamos y se cargará los componentes de
la cámara, del modelo de detección Haar, y del decodificador de
imágenes recibidas por la PiCam.
Lectura de CSV. Se obtienen datos del fichero csv con la ruta de las
imágenes y el identificador de empleado, los cuales se usarán para
guardar las imágenes y sus identificadores en una serie de vectores
para el futuro reconocimiento de caras por el método de EigenFaces.
Detección de Caras. Mediante el método de Haar se realiza la
detección de caras de la captura recibida desde la PiCam, necesario
para el siguiente paso. Este proceso se repetirá durante el tiempo
que este prefijado por la variable de estado. Una vez terminado,
pasará a cerrar la aplicación.
Reconocimiento de EigenFaces. Una vez se ha detectado rostros o
caras en el paso anterior, y se hayan redimensionado, se pasará a
comprobar con el algoritmo de EigenFaces, si alguno de los rostros
MATERIALES Y MÉTODOS
39
capturados se corresponde con alguno de los guardados en los
vectores que se cargaron en el apartado de lectura de CSV. Si es así
se guardará información relativa al empleado para el control de
asistencia definido en el siguiente apartado.
Guardado de Datos de empleado para el control de asistencia. Se
guardaran los datos relativos al empleado, siendo estos la fecha y
hora, el empleado y el identificador de empleado.
Cierre de Aplicación. Una vez terminada la captura desde la PiCam
al terminar tiempo de espera, pasaremos a mostrar información
sobre el visionado y a cerrar la aplicación.
C. Gestión de la información:
El diagrama de bloques a tener en cuenta para entender el funcionamiento
que se ha seguido en el módulo de gestión de información (figura 4.10), es el
siguiente:
PROGRAMA DE GESTIÓN
40
Figura 4.10 Diagrama de bloques de envío de ficheros
A continuación se realizará una breve descripción del proceso definido en
el diagrama anterior en que el estará basada la funcionalidad que se conecta
MATERIALES Y MÉTODOS
41
con un script a FTP y le envía los ficheros del control de asistencia de los
empleados:
Inicio. Se identifica al comienzo el tipo de programa que es para
que reconozca el sistema que es un script de BASH y pueda
lanzarse sin problemas.
Datos de Conexión. Se definen los datos de conexión, siendo la
dirección del servidor FTP, el usuario y la contraseña asociada.
Conexión FTP. Se realiza la conexión FTP al servidor.
Envío de Ficheros y cierre de conexión. Se prepara los ficheros
FTP para enviar, se envían y se cierra conexión.
Cierre de Aplicación. Se muestra información del proceso y si el
proceso de envío ha ido bien, se renombran los ficheros enviados
para evitar que se reenvíen en un futuro proceso.
4.3.3 Módulo de Captura y Guardado de Imágenes
El módulo de captura y guardado de caras, viene definido su código en el archivo
guardar_imagen.cpp, durante la ejecución necesitará para un funcionamiento correcto
una serie de argumentos básicos. La aplicación espera dos argumentos en total (figura
4.11), siendo estos:
Histograma, con dos valores posibles, 0 o 1, aunque por defecto será 0 para
hacer la ecualización de la imagen de color a blanco y negro para un
procesado más rápido.
Datos del empleado, cadena de caracteres (String) con el nombre de
empleado al que se guardaran las imágenes de su cara capturada desde la
PiCam, e información relacionada a ella en un fichero plano (cfg.csv).
PROGRAMA DE GESTIÓN
42
Figura 4.11 Ejecución con dos argumentos
Su funcionamiento será conectarse a la PiCam, abrir una ventana de visión de lo
que captura, localizar las caras de lo que se encuentra en los fotogramas capturados y
por último, en función del parámetro de entrada que indica el nombre del empleado,
generará las imágenes relacionadas al empleado y guardara en los ficheros de control
(cfg.csv y ficheros.csv), la información relacionada al empleado, ruta de las imágenes,
identificador de empleado y nombre de empleado. Se añadirá un nuevo empleado a
cfg.csv (figura 4.12) si no existía uno previamente, y si existía, obtendrá el identificador de
empleado y el contador de imagen de ese empleado de los ficheros de entrada (figura
4.13) desde ficheros.csv.
MATERIALES Y MÉTODOS
43
Figura 4.12 Contenido del fichero cfg.csv
Figura 4.13 Contenido de ficheros.csv
Este módulo, tendrá las siguientes variables, estructuras y funciones:
Variables y estructuras:
DATOS_PERSONAL: Es una variable de tipo String (cadena de caracteres),
que se obtiene como argumento de entrada, e identifica el nombre del
empleado al que van a guardarse las imágenes de su cara obtenidas por la
PiCam. Se usará también para guardar información relacionada entre el
PROGRAMA DE GESTIÓN
44
nombre del empleado y su identificador de empleado en los ficheros planos
ya existentes que serán usados por el programa reconocimiento.cpp.
idPersonal: Es una variable de tipo entero, que contendrá el identificador del
empleado, si el empleado ya viene definido en los ficheros planos, en vez de
crear uno nuevo, recogerá el que le relaciona.
contador: Es una variable de tipo entero que identifica el número de imagen
del empleado nuevo que se generará. Si el empleado ya apareciera en el
fichero plano cfg.csv, buscaría en ficheros.csv cuál es la numeración que
debe seguir. Si fuera un empleado nuevo, empezaría por el 1.
TRACE: Es de tipo constante y se usará para indicar si se mostrarán o no
trazas durante ejecución, será utilizado principalmente para pruebas, o para
informar a usuario de ciertos detalles.
DEBUG_MODE: Es de tipo constante y si este valor vale 1, estará en modo
debug, a 0 estará deshabilitado dicho modo.
DEBUG: En función del valor anterior, entrará o no en modo debug.
face_cascade: Objeto de la clase CascadeClassifier para detectar objetos
en una secuencia de vídeo. Utilizará dos funciones. "load" para cargar un
clasificador de un archivo XML, el cual puede ser un Haar o una clasificador
LBP. Se usará el de tipo Haar que se instaló previamente, e incluido en la
ruta "/usr/share/opencv/lbpcascades/lbpcascade_frontalface.xml". Y para
llevar a cabo la detección se usará "detectMultiScale”.
fn_haar: Es una variable de tipo cadena de caracteres (String), y recogerá la
ruta y fichero que incluye el clasificador de cascada Haar perteneciente a
OpenCV.
faces: Es un vector de claseRect, que pertenece a OpenCV y permite definir
un rectángulo de enteros mediante sus valores de ancho y alto. Lo usamos
para guardar las caras que se van detectando por cada captura de una
imagen en el que puede haber más de una persona. Será necesario a
MATERIALES Y MÉTODOS
45
posteriori redimensionar imagen, para realizar la comparación mediante los
métodos expuestos anteriormente de forma más eficiente.
bHisto: Es una variable de tipo entero y será usado para saber si se va a
realizar una ecualización del histograma de color. Es un valor que se obtiene
como argumento de entrada y que en principio estará deshabilitado y se
cogerá el valor por defecto que se asigna al lanzar la función default_status.
im_anchura: Es una variable de tipo entero y define la anchura de las
imágenes que tenemos guardadas. Como todas deben tener la misma
anchura, a la hora de obtener este valor, solo necesitaremos sacarlo de uno.
im_altura: Es una variable de tipo entero y define la altura de las imágenes
que tenemos guardadas. Como todas deben tener la misma altura, a la hora
de obtener este valor, solo necesitaremos sacarlo de uno.
key: Es una variable de tipo char que recogerá la tecla que se ha pulsado,
usado para pruebas a la hora de esperar que se pulse una tecla específica
para poder continuar con programa.
MMAL_CAMERA_VIDEO_PORT: Es de tipo constante y representa el
puerto estándar del componente de la cámara de video CamPi.
MMAL_CAMERA_CAPTURE_PORT: Es de tipo constante y representa el
puerto estándar de captura del componente de la cámara de video CamPi.
VIDEO_FRAME_RATE_NUM: Es de tipo constante y representa
información de formato de video. La tasa de fotogramas máxima por
segundos.
VIDEO_FRAME_RATE_DEN: Es de tipo constante y representa información
de formato de video. La densidad de fotogramas por segundo.
VIDEO_OUTPUT_BUFFERS_NUM: Es de tipo constante y representa el
numero de buffers que usará.
PROGRAMA DE GESTIÓN
46
nCount: Es una variable de tipo entero que utilizaremos de contador para
indicar el número de fotogramas que se han mostrado en total.
py: Es un variable de tipo IplImage, el cual es una estructura que contiene
los datos de imagen en sí, más información como el tamaño, profundidad de
color, etc., de una imagen. Representa el componente Y del modelo YUV,
también conocido como YCbCr para la codificación digital de todo el
fotograma.
pu: Es un variable de tipoIplImage, el cual es una estructura que contiene
los datos de imagen en sí, más información como el tamaño, profundidad de
color, etc., de una imagen. Representa el componente U (o Cb) del modelo
YUV, también conocido como YCbCr para la codificación digital de una
pequeña porción del fotograma.
pv: Es un variable de tipo IplImage, el cual es una estructura que contiene
los datos de imagen en sí, más información como el tamaño, profundidad de
color, etc., de una imagen. Representa el componente V (o Cr)del modelo
YUV, también conocido como YCbCr para la codificación digital de una
pequeña porción del fotograma.
pu_big: Es un variable de tipo IplImage, el cual es una estructura que
contiene los datos de imagen en sí, más información como el tamaño,
profundidad de color, etc., de una imagen. Representa el componente U (o
Cb) del modelo YUV, también conocido como YCbCr para la codificación
digital de todo el fotograma.
pv_big: Es un variable de tipo IplImage, el cual es una estructura que
contiene los datos de imagen en sí, más información como el tamaño,
profundidad de color, etc., de una imagen. Representa el componente V (o
Cr) del modelo YUV, también conocido como YCbCr para la codificación
digital de todo el fotograma.
image: Es un variable de tipo IplImage, el cual es una estructura que
contiene los datos de imagen en sí, más información como el tamaño,
profundidad de color, etc., de una imagen. Representa la imagen final que
se muestra en tipo RGB. Usado para detección de cara en color.
MATERIALES Y MÉTODOS
47
dstImage: Es una variable de tipo IplImage, el cual es una estructura que
contiene los datos de la imagen en sí, como el tamaño, profundidad de
color, y otro tipo de información. Representa la transformación de la imagen
final que se mostraba en el tipo YCbCr desde RGB. Usado para detección
de cara en color.
gray: Es una variable de tipo Mat que recibirá la imagen final capturada
desde la cámara en función de que se use escala de grises o en color, por
defecto será en escala de grises. Previamente se transformará la imagen de
tipo IplImage a Mat con una función, siendo este tipo IplImage uno de los
anteriores.
face: Es una variable de tipo Mat que recibirá la imagen de cara recibida
(encontrada en la imagen) en escala de grises.
face_resized: Es una variable de tipo Mat que recibirá la imagen de cara
recibida (encontrada en la imagen) en escala de grises redimensionada a un
tamaño para poder usarla en el método de reconocimiento.
RASPIVID_STATE: Es una estructura que contiene todos la información de
estado para la situación normal de ejecución que contiene los siguientes
elementos:
timeout: Es una variable de tipo entero que representa el tiempo
necesario durante el cual está esperando respuesta en la cámara y la
aplicación termina. La unidad es en milisegundos.
width: Es una variable de tipo entero que representa la anchura
requerida de la imagen.
height: Es una variable de tipo entero que representa la altura requerida
de la imagen.
bitrate: Es una variable de tipo entero que representa la tasa de bit
requerida.
PROGRAMA DE GESTIÓN
48
framerate: Es una variable de tipo entero que representa la tasa de
fotogramas por segundo requerido (fps).
graymode: Es una variable de tipo entero que indica si captura se
realizara en escala de grises o no.
immutableInput: Es una variable de tipo entero que representa un flag
(bandera) para especificar si codificador trabaja en el lugar o crea un
nuevo buffer. El resultado es preliminar puede mostrar ya sea la salida
de la cámara o de la salida del codificador (con artefactos de
compresión).
preview_parameters: Es de tipo RASPIPREVIEW_PARAMETERS, y
representa los parámetros por defecto de configuración.
camera_parameters: Es de tipo RASPICAM_CAMERA_PARAMETERS
y representa los parámetros de configuración de cámara.
camera_component: Es un puntero al componente de la cámara.
encoder_component: Es un puntero al componente del codificador.
preview_connection: Es un puntero a la conexión de la cámara por
defecto.
encoder_connection: Es un puntero a la conexión de la cámara a
codificar.
video_pool: Es un puntero a la colección de buffers usados por el puerto
de salida del codificador.
PORT_USERDATA: Es una estructura usada para pasar información en el
puerto del codificador de los datos de usuario devueltos que contiene los
siguientes elementos:
file_handle: Es un puntero "inteligente" a memoria para escribir datos en
el buffer.
MATERIALES Y MÉTODOS
49
complete_semaphore: Es un semáforo el cual es activado cuando
lleguemos al final (indica el final de la captura o fallo).
pstate: Es un puntero a nuestro estado (RASPIVID_STATE) en caso de
requerir respuesta.
Funciones:
Función trace. Esta función es la encargada de escribir una traza por
consola. No devuelve nada.
Cabecera:
void trace (string s).
Parámetros de paso:
s: Es una variable de tipo string (cadena de caracteres), que contendrá
el mensaje a escribir por consola.
Función leer_csv. Esta función es la encargada de en función del nombre
de empleado incluido en DATOS_PERSONAL, buscar en cfg.csv, si el
empleado existe, si existe encontrar el identificar de ese empleado
(idEmpleado), y averiguar cuál es el valor de la numeración de la última
imagen guardada de este empleado que se guardará en contador. Si es un
empleado nuevo, se añadirá una línea en cfg.csv con dicho empleado, el
idEmpleado será nuevo y contador pasará a ser 1.
Cabecera:
Static void read_csv (char separator = ';').
Parámetros de paso:
PROGRAMA DE GESTIÓN
50
separator: Es un parámetro el cual es un carácter, en este caso por
defecto es “;” que se usará para separar en cada línea del fichero la ruta
de la imagen y el identificador del empleado.
Función default_status. Esta función es la encargada de establecer los
valores por defecto del video de captura y de las variables contenidas en la
estructura RASPIVID_STATE.
Cabecera:
Static void default_status (RASPIVID_STATE *state).
Parámetros de paso:
state: Es la estructura RASPIVID_STATE que se pasa para ponerlos a 0
siempre que este vacío, si tiene algún dato, se deja como estaba.
Función video_buffer_callback. Esta función es la encargada de hacer
todo el proceso de localización de caras y su guardado. Primero obteniendo
en un buffer lo que va apareciendo desde el puerto de la cámara, para
después detectar las caras, incluyendo en el video un rectángulo para
localizarlos, y pasar a guardar las imágenes relacionadas al empleado
(DATOS_EMPLEADO), así como la actualización del fichero plano
ficheros.csv con los datos de la ruta de guardado, y el identificador del
empleado (idEmpleado).
Cabecera:
static void video_buffer_callback (MMAL_PORT_T *port,
MMAL_BUFFER_HEADER_T *buffer).
Parámetros de paso:
port: Es el puntero al puerto de la cámara desde donde aparecerán las
imágenes.
buffer: Puntero al buffer MMAL que se usará para pasarle el fotograma.
MATERIALES Y MÉTODOS
51
Función create_camera_component. Esta función es la encargada de
configurar los parámetros de la cámara, y con la configuración de video
definida en state, crea el componente de la cámara, y termina configurando
los puertos.
Cabecera:
static MMAL_COMPONENT_T *create_camera_component
(RASPIVID_STATE *state).
Parámetros de paso:
state: Es la estructura RASPIVID_STATE con los datos de configuración
necesarios para crear el componente de la cámara.
Función destroy_camera_component. Esta función es la encargada de
destruir el componente de la cámara, usado principalmente al terminar
proceso o cuando se produce algún tipo de error de conexión.
Cabecera:
static void destroy_camera_component (RASPIVID_STATE *state).
Parámetros de paso:
state: Es la estructura RASPIVID_STATE con los datos de configuración
de la cámara, y se usará para ponerlos vacíos para liberar recursos.
Función destroy_encoder_component. Esta función es la encargada de
destruir el componente codificador de la cámara, usado principalmente al
terminar proceso o cuando se produce algún tipo de error de conexión.
Cabecera:
static void destroy_encoder_component (RASPIVID_STATE *state).
PROGRAMA DE GESTIÓN
52
Parámetros de paso:
state: Es la estructura RASPIVID_STATE con los datos de
configuración de la cámara, y se usará para destruir los buffers y el
componente encoder_component a nulo.
Función connect_ports. Esta función es la encargada de conectar los
puertos de entrada y salida de la cámara a partir de una conexión ya
establecida. Da como salida el resultado de la operación.
Cabecera:
static MMAL_STATUS_T connect_ports (MMAL_PORT_T
*output_port, MMAL_PORT_T *input_port, MMAL_CONNECTION_T
**connection).
Parámetros de paso:
output_port: Puntero al puerto de salida de la cámara.
input_port: Puntero al puerto de entrada de la cámara.
connection: Puntero a un punto de conexión MMAL, reasignado si la
función tiene éxito.
Función check_disable_port. Esta función es la encargada que comprobar
si el puerto especificado es válido y está habilitado, para en ese caso,
deshabilitarlo. Se usará sobre puertos que no se usan.
Cabecera:
static void check_disable_port(MMAL_PORT_T *port)
Parámetros de paso:
port: Puntero a un puerto. Usado para deshabilitar todos los puertos que
no están apuntando a la conexión.
MATERIALES Y MÉTODOS
53
Función signal_handler. Esta función es la encargada de comprobar el
estado de la señal, y si hay algún problema, sale de todo.
Cabecera:
static void signal_handler (intsignal_number)
Parámetros de paso:
signal_number: Es una variable que tendrá el identificador de la señal
entrante.
Una vez terminado el proceso, se habrán guardado las imágenes del empleado
capturadas y reconocidas desde la cámara CamPi y actualizado los ficheros si fueran
necesarios (cfg.csv y ficheros.csv) que estarán en la ruta del programa
reconocimiento.cpp.
4.3.4 Módulo de Reconocimiento de caras
El módulo de reconocimiento de caras, viene definido su código en el archivo
reconocimiento.cpp, durante la ejecución necesitará para un funcionamiento correcto una
serie de argumentos básicos. La aplicación espera cuatro argumentos en total (figura
4.14), siendo estos:
Fichero de entrada con la ruta de las imágenes y el identificador que lo
relaciona. El que se usa se llama ficheros.csv.
Fichero de entrada con la relación entre el identificador, relacionado con el
fichero anterior, y el nombre del empleado que lo relaciona. El que se usa se
llama cfg.csv.
Histograma, con dos valores posibles, 0 o 1, aunque por defecto será 0 para
hacer la ecualización de la imagen de color a blanco y negro para un
procesado más rápido.
Umbral de predicción para reconocimiento de cara.
PROGRAMA DE GESTIÓN
54
Figura 4.14 Ejecución con cuatro argumentos
Su funcionamiento será conectarse a la PiCam, abrir una ventana de visión de lo
que captura, localizar las caras de lo que se encuentra en los fotogramas capturados y
por último, en función de las caras que tenemos guardas por el programa
guardar_imagen.cpp (figura 4.15) y mediante el uso del método EigenFaces, reconocer al
empleado y guardar información referente a él, como el horario de entrada o salida.
Figura 4.15 Imágenes guardadas
MATERIALES Y MÉTODOS
55
Este módulo, tendrá las siguientes variables, estructuras y funciones:
Variables y estructuras:
MAX_PEOPLE: Es de tipo constante y se define como el número máximo de
empleados que se pueden tener. Utilizada para definir ciertas listas a las
que hay que definir su tamaño especifico. Se reservará dicho espacio para
todo lo que pueda venir.
MAX_PEOPLE_F: Es de tipo entero, y se utilizará para obtener el valor real
de personal que tenemos guardado para revisar en la tienda. Se rellenará
durante el inicio del programa.
TRACE: Es de tipo constante y se usará para indicar si se mostrarán o no
trazas durante ejecución, será utilizado principalmente para pruebas, o para
informar a usuario de ciertos detalles.
DEBUG_MODE: Es de tipo constante y si este valor vale 1, estará en modo
debug, a 0 estará deshabilitado dicho modo.
DEBUG: En función del valor anterior, entrará o no en modo debug.
face_cascade: Objeto de la clase CascadeClassifier para detectar objetos
en una secuencia de vídeo. Utilizará dos funciones. "load" para cargar un
clasificador de un archivo XML, el cual puede ser un Haar o una clasificador
LBP. Se usará el de tipo Haar que se instaló previamente, e incluido en la
ruta "/usr/share/opencv/lbpcascades/lbpcascade_frontalface.xml". Y para
llevar a cabo la detección se usará "detectMultiScale”.
model: Objeto de la clase Eigenfaces que recoge los datos relacionados con
las caras obtenidas de las imágenes capturadas de la cámara y las que hay
guardadas en local y mediante el algoritmo de Eigenfaces realiza el
reconocimiento de las caras. Usara dos funciones, “predict” para tratar de
detectarla, y “train”, para entrenar las imágenes que hay en local.
PROGRAMA DE GESTIÓN
56
fn_haar: Es una variable de tipo cadena de caracteres (String), y recogerá la
ruta y fichero que incluye el clasificador de cascada Haar perteneciente a
OpenCV.
fn_csv: Es una variable de tipo cadena de caracteres (String), y recogerá la
ruta de los ficheros con caras para entrenamiento recibido como argumento
del programa de reconocimiento. Incluirá la ruta y su identificador de
empleado.
fn_cfg: Es una variable de tipo cadena de caracteres (String), y recogerá la
ruta del fichero de configuración con la relación entre el identificador del
empleado y el nombre del empleado.
images: Es un vector de clase Mat, que pertenece a OpenCV y representa
una matriz n-dimensional de canal numérico o multicanal, el cual es utilizado
para almacenar: los vectores y matrices reales o valores complejos, ya sea
en escala de grises o imágenes en color; campos vectoriales, nubes de
puntos, tensores o histogramas. Aquí se guardaran las imágenes que
teníamos guardadas en el equipo y que vienen la ruta incluida en la variable
fn_csv. Es compatible con CvMat e IplImage, que usaremos después.
labels: Es un vector de tipo entero, y es usado para incluir los identificadores
de cada imagen que se ha guardado en images. Este identificador aparece
en el fichero que se encuentra en la variable fn_csv.
arguments: Es un vector de tipo String (cadena de caracteres) que incluye
los datos del empleado, como el nombre y/o apellidos para poder
identificarlo.
idarguments: Es un vector de tipo entero que incluye identificador del
empleado, relacionado con el vector arguments.
faces: Es un vector de claseRect, que pertenece a OpenCV y permite definir
un rectángulo de enteros mediante sus valores de ancho y alto. Lo usamos
para guardar las caras que se van detectando por cada captura de una
imagen en el que puede haber más de una persona. Una vez incluidas en
este vector las imágenes, será necesario redimensionarlas para que estén
MATERIALES Y MÉTODOS
57
preparadas para su comparación mediante los métodos expuestos
anteriormente de forma más eficiente.
bHisto: Es una variable de tipo entero y será usado para saber si se va a
realizar una ecualización del histograma de color. Es un valor que se obtiene
como argumento de entrada y que en principio estará deshabilitado y se
cogerá el valor por defecto que se asigna al lanzar la función default_status.
im_width: Es una variable de tipo entero y define la anchura de las imágenes
que tenemos guardadas. Como todas deben tener la misma anchura, a la
hora de obtener este valor, solo necesitaremos sacarlo de uno.
im_height: Es una variable de tipo entero y define la altura de las imágenes
que tenemos guardadas. Como todas deben tener la misma altura, a la hora
de obtener este valor, solo necesitaremos sacarlo de uno.
key: Es una variable de tipo char que recogerá la tecla que se ha pulsado,
usado para pruebas a la hora de esperar que se pulse una tecla específica
para poder continuar con programa.
PREDICTION_SEUIL: Es una variable tipo entero que se obtiene como
argumento de entrada, e identifica el valor de umbral de predicción sobre el
que se hará caso a la hora de realizar el método de reconocimiento.
People: Es una lista de tipo string (cadena de caracteres), que servirá para
identificar a el personal que tenemos guardado en el fichero fn_cfg.
nPictureById: Es una lista de tipo string (cadena de caracteres), que servirá
para identificar el número de imágenes aprendidas por cada persona.
MMAL_CAMERA_VIDEO_PORT: Es de tipo constante y representa el
puerto estándar del componente de la cámara de video CamPi.
MMAL_CAMERA_CAPTURE_PORT: Es de tipo constante y representa el
puerto estándar de captura del componente de la cámara de video CamPi.
PROGRAMA DE GESTIÓN
58
VIDEO_FRAME_RATE_NUM: Es de tipo constante y representa
información de formato de video. La tasa de fotogramas máxima por
segundos.
VIDEO_FRAME_RATE_DEN: Es de tipo constante y representa información
de formato de video. La densidad de fotogramas por segundo.
VIDEO_OUTPUT_BUFFERS_NUM: Es de tipo constante y representa el
numero de buffers que usará.
nCount: Es una variable de tipo entero que utilizaremos de contador para
indicar el número de fotogramas que se han mostrado en total.
py: Es un variable de tipo IplImage, el cual es una estructura que contiene
los datos de imagen en sí, más información como el tamaño, profundidad de
color, etc., de una imagen. Representa el componente Y del modelo YUV,
también conocido como YCbCr para la codificación digital de todo el
fotograma.
pu: Es un variable de tipoIplImage, el cual es una estructura que contiene
los datos de imagen en sí, más información como el tamaño, profundidad de
color, etc., de una imagen. Representa el componente U (o Cb) del modelo
YUV, también conocido como YCbCr para la codificación digital de una
pequeña porción del fotograma.
pv: Es un variable de tipo IplImage, el cual es una estructura que contiene
los datos de imagen en sí, más información como el tamaño, profundidad de
color, etc., de una imagen. Representa el componente V (o Cr)del modelo
YUV, también conocido como YCbCr para la codificación digital de una
pequeña porción del fotograma.
pu_big: Es un variable de tipo IplImage, el cual es una estructura que
contiene los datos de imagen en sí, más información como el tamaño,
profundidad de color, etc., de una imagen. Representa el componente U (o
Cb) del modelo YUV, también conocido como YCbCr para la codificación
digital de todo el fotograma.
MATERIALES Y MÉTODOS
59
pv_big: Es un variable de tipo IplImage, el cual es una estructura que
contiene los datos de imagen en sí, más información como el tamaño,
profundidad de color, etc., de una imagen. Representa el componente V (o
Cr) del modelo YUV, también conocido como YCbCr para la codificación
digital de todo el fotograma.
image: Es un variable de tipo IplImage, el cual es una estructura que
contiene los datos de imagen en sí, más información como el tamaño,
profundidad de color, etc., de una imagen. Representa la imagen final que
se muestra en tipo RGB. Usado para detección de cara en color.
dstImage: Es una variable de tipo IplImage, el cual es una estructura que
contiene los datos de la imagen en sí, como el tamaño, profundidad de
color, y otro tipo de información. Representa la transformación de la imagen
final que se mostraba en el tipo YCbCr desde RGB. Usado para detección
de cara en color.
gray: Es una variable de tipo Mat que recibirá la imagen final capturada
desde la cámara en función de que se use escala de grises o en color, por
defecto será en escala de grises. Previamente se transformará la imagen de
tipo IplImage a Mat con una función, siendo este tipo IplImage uno de los
anteriores.
face: Es una variable de tipo Mat que recibirá la imagen de cara recibida
(encontrada en la imagen) en escala de grises.
face_resized: Es una variable de tipo Mat que recibirá la imagen de cara
recibida (encontrada en la imagen) en escala de grises redimensionada a un
tamaño para poder usarla con el método de EigenFaces.
RASPIVID_STATE: Es una estructura que contiene todos la información de
estado para la situación normal de ejecución que contiene los siguientes
elementos:
timeout: Es una variable de tipo entero que representa el tiempo
necesario durante el cual está esperando respuesta y la aplicación
termina. La unidad es en milisegundos.
PROGRAMA DE GESTIÓN
60
width: Es una variable de tipo entero que representa la anchura
requerida de la imagen.
height: Es una variable de tipo entero que representa la altura requerida
de la imagen.
bitrate: Es una variable de tipo entero que representa la tasa de bit
requerida.
framerate: Es una variable de tipo entero que representa la tasa de
fotogramas por segundo requerido (fps).
graymode: Es una variable de tipo entero que indica si captura se
realizara en escala de grises o no.
immutableInput: Es una variable de tipo entero que representa un flag
(bandera) para especificar si codificador trabaja en el lugar o crea un
nuevo buffer. El resultado es preliminar puede mostrar ya sea la salida
de la cámara o de la salida del codificador (con artefactos de
compresión).
preview_parameters: Es de tipo RASPIPREVIEW_PARAMETERS, y
representa los parámetros por defecto de configuración.
camera_parameters: Es de tipo RASPICAM_CAMERA_PARAMETERS
y representa los parámetros de configuración de cámara.
camera_component: Es un puntero al componente de la cámara.
encoder_component: Es un puntero al componente del codificador.
preview_connection: Es un puntero a la conexión de la cámara por
defecto.
encoder_connection: Es un puntero a la conexión de la cámara a
codificar.
MATERIALES Y MÉTODOS
61
video_pool: Es un puntero a la colección de buffers usados por el puerto
de salida del codificador.
PORT_USERDATA: Es una estructura usada para pasar información en el
puerto del codificador de los datos de usuario devueltos que contiene los
siguientes elementos:
file_handle: Es un puntero "inteligente" a memoria para escribir datos en
el buffer.
complete_semaphore: Es un semáforo el cual es activado cuando
lleguemos al final (indica el final de la captura o fallo).
pstate: Es un puntero a nuestro estado (RASPIVID_STATE) en caso de
requerir respuesta.
Funciones:
Función trace. Esta función es la encargada de escribir una traza por
consola. No devuelve nada.
Cabecera:
void trace (string s).
Parámetros de paso:
s: Es una variable de tipo string (cadena de caracteres), que contendrá
el mensaje a escribir por consola.
Función read_csv. Esta función es la encargada de leer un fichero de texto
plano y obtiene las imágenes referenciadas en el fichero añadiéndolo a un
vector de objetos de clase Mat llamado images, y obtiene el identificador de
esa imagen correspondiente al empleado asociado.
Cabecera:
PROGRAMA DE GESTIÓN
62
Static void read_csv (conststring&filename, vector<Mat>&images,
vector<int>&labels, char separator = ';').
Parámetros de paso:
filename: Es una variable de tipo String (cadena de caracteres) que
representa la concatenación de la ruta y nombre de fichero que tiene la
lista de imágenes guardadas con las caras del personal.
images: Es un parámetro de paso de tipo vector de objetos
pertenecientes a la clase Mat que rellenaremos con las imágenes que
teníamos guardadas en el equipo en función del fichero anterior.
labels: Es un parámetro de paso de tipo vector de enteros que recoge el
identificador relacionado con cada imagen del vector anterior.
separator: Es un parámetro el cual es un carácter, en este caso por
defecto es “;” que se usará para separar en cada línea del fichero la ruta
de la imagen y el identificador del empleado.
Función default_status. Esta función es la encargada de establecer los
valores por defecto del video de captura y de las variables contenidas en la
estructura RASPIVID_STATE.
Cabecera:
Static void default_status (RASPIVID_STATE *state).
Parámetros de paso:
state: Es la estructura RASPIVID_STATE que se pasa para ponerlos a 0
siempre que este vacío, si tiene algún dato, se deja como estaba.
Función video_buffer_callback. Esta función es la encargada de hacer
todo el proceso de reconocimiento de caras, primero obteniendo en un
buffer lo que va apareciendo desde el puerto de la cámara, para después
MATERIALES Y MÉTODOS
63
detectar las caras, incluyendo en el video un rectángulo para localizarlos, y
pasar a detectar mediante el proceso de Haar, y pasar a comparar con las
imágenes que teníamos guardados en los vectores en función del umbral de
predicción.
Cabecera:
static void video_buffer_callback (MMAL_PORT_T *port,
MMAL_BUFFER_HEADER_T *buffer).
Parámetros de paso:
port: Es el puntero al puerto de la cámara desde donde aparecerán las
imágenes.
buffer: Puntero al buffer MMAL que se usará para pasarle el fotograma.
Función create_camera_component. Esta función es la encargada de
configurar los parámetros de la cámara, y con la configuración de video
definida en state, crea el componente de la cámara, y termina configurando
los puertos.
Cabecera:
static MMAL_COMPONENT_T *create_camera_component
(RASPIVID_STATE *state).
Parámetros de paso:
state: Es la estructura RASPIVID_STATE con los datos de configuración
necesarios para crear el componente de la cámara.
Función destroy_camera_component. Esta función es la encargada de
destruir el componente de la cámara, usado principalmente al terminar
proceso o cuando se produce algún tipo de error de conexión.
Cabecera:
PROGRAMA DE GESTIÓN
64
static void destroy_camera_component (RASPIVID_STATE *state).
Parámetros de paso:
state: Es la estructura RASPIVID_STATE con los datos de configuración
de la cámara, y se usará para ponerlos vacíos para liberar recursos.
Función destroy_encoder_component. Esta función es la encargada de
destruir el componente codificador de la cámara, usado principalmente al
terminar proceso o cuando se produce algún tipo de error de conexión.
Cabecera:
static void destroy_encoder_component (RASPIVID_STATE *state).
Parámetros de paso:
state: Es la estructura RASPIVID_STATE con los datos de
configuración de la cámara, u se usará para destruir los buffers y el
componente encoder_component a nulo.
Función connect_ports. Esta función es la encargada de conectar los
puertos de entrada y salida de la cámara a partir de una conexión ya
establecida. Da como salida el resultado de la operación.
Cabecera:
static MMAL_STATUS_T connect_ports (MMAL_PORT_T
*output_port, MMAL_PORT_T *input_port, MMAL_CONNECTION_T
**connection).
Parámetros de paso:
output_port: Puntero al puerto de salida de la cámara.
input_port: Puntero al puerto de entrada de la cámara.
MATERIALES Y MÉTODOS
65
connection: Puntero a un punto de conexión MMAL, reasignado si la
función tiene éxito.
Función check_disable_port. Esta función es la encargada que comprobar
si el puerto especificado es válido y está habilitado, para en ese caso,
deshabilitarlo. Se usará sobre puertos que no se usan.
Cabecera:
static void check_disable_port(MMAL_PORT_T *port)
Parámetros de paso:
port: Puntero a un puerto. Usado para deshabilitar todos los puertos que
no están apuntando a la conexión.
Función signal_handler. Esta función es la encargada de comprobar el
estado de la señal, y si hay algún problema, sale de todo.
Cabecera:
static void signal_handler (intsignal_number)
Parámetros de paso:
signal_number: Es una variable que tendrá el identificador de la señal
entrante.
Una vez terminado el proceso, como fichero de salida se generará un archivo plano
en donde se almacenará la información del personal que se ha localizado con la CamPi
(figuras 4.16 y 4.17). Este fichero será necesario para el apartado siguiente, se
encontrará en la carpeta “detectado”, y se llamara detect_YYYYMMDDHmS.txt, siendo
“YYYY” el año, “MM” el mes, “DD” el día, “H” las horas, “m” los minutos y “S” los
segundos actuales. El fichero tendrá la lista de empleados que se han encontrado
durante la captura, incluyendo el nombre de empleado, el identificador de empleado y la
fecha de inicio de la captura.
PROGRAMA DE GESTIÓN
66
Figura 4.16 Ficheros generados a la salida
Figura 4.17 Contenido de fichero generado
4.3.5 Gestión de información
La gestión de información, trata sobre el proceso de subida de los ficheros
generados en el paso anterior a un servidor de FTP para su posterior guardado en una
Base de datos para su posterior análisis o control de asistencia.
Para la subida de ficheros se ha creado un script bash que con la interpretación de
órdenes, nos permite de manera muy cómoda enviar los ficheros a una dirección de FTP
donde estarán incluidas el horario de entrada y salida de los empleados de las tiendas.
Esta aplicación no necesita de parámetros de entrada, solo necesita que se hayan
generado ficheros en el apartado anterior y la existencia de un cliente FTP (instalación
indicada en el anexo 7.5).
El código de BASH que se ha utilizado es muy simple, se ha comentado cada punto
para entender su funcionamiento:
#!/bin/bash
MATERIALES Y MÉTODOS
67
# Este código al inicio es vital para que GNU/Linux reconozca que es un script
echo "Conectando y autenticando con el servidor de FTP"
# Todo lo que tiene "echo" informa al usuario lo que el script esta haciendo.
FECHA=`date +%Y-%m-%d`
# $FECHA, será para colocar el año-mes+día
echo $FECHA
DESTINO=’ftp.servidorftp.es’
USUARIO=’nombre_usuario’
PASSWORD=’contraseña’
# datos que corresponden para poder conectarse,
# la dirección del servidor (DESTINO),
# el usuario (USUARIO) y su contraseña (PASSWORD)
cd /home/pi/reconocimiento/detectado
# Se indica cual es la carpeta local donde estan archivos que se
echo "Enviando ficheros"
ftp -n $DESTINO << FIN_SCRIPT
quote USER $USUARIO
quote PASS $PASSWORD
binary
# comandos a ejecutarse durante el programa de FTP
# si se envia correctamente, pasa a FIN_SCRIPT
put detect*.txt
quit
# se ejecuta el comando para enviar el archivo, que es el "put",
# y para luego desconectarse y cerrar "quit"
FIN_SCRIPT
mv detect*.txt *.old
# se cambia la extensión de lo enviado
echo “Archivo enviado correctamente”
echo “FIN”
El proceso que sigue para el envío de ficheros, es el comentado en el diagrama del
segundo punto de este apartado, donde primero se realiza la identificación con los datos
de usuario y contraseña, después se pasa a conectarse al servidor identificado, justo
después se pasan los ficheros de extensión DAT al servidor de FTP, y por último, se
cambia la extensión a OLD para que en el futuro no se vuelvan a pasar.
PROGRAMA DE GESTIÓN
68
Este proceso se realizará de manera automática tras la ejecución del apartado
anterior, si por alguna razón no funcionase correctamente, durante siguiente ejecución se
subirían los ficheros.
Si quisiéramos ejecutarlo de manera normal, sería como se indica en la figura 4.18:
Figura 4.18 Ejecución de Script
4.3.6 Otras librerías relacionadas
Para un funcionamiento correcto del código, aparte de necesitar las librerías de
OpenCV, también se han utilizado librerías para la configuración y comunicación con la
cámara conectada a la Raspberry Pi, llamada CamPi, así como pequeña funcionalidad
para partes importantes.
Siendo estos:
RaspiCli.c: Código para el manejo de parámetros de línea de comandos.
RaspiPreview.c: Funcionalidad para la cámara conectada a la Raspberry Pi.
RaspiCamControl.c: Creará el componente de pre-visualización y establece
sus puertos.
MATERIALES Y MÉTODOS
69
RaspiTex.c: Un sencillo framework para ampliar una aplicación MMAL para
hacer buffers vía OpenGL.
RaspiTexUtil.c: Proporciona implementaciones por defecto para las
funciones raspitex_scene_ops y otras funciones necesarias.
RaspiStillYUV.c: Programa de línea de comandos para capturar una imagen
fija y volcarla sin comprimir. También mostrará opcionalmente una vista
previa de lo que hay a la entrada de la cámara actual.
RaspiVid.c: Programa de línea de comandos para capturar una secuencia
de vídeo de la cámara y codificarlo en un archivo. También mostrará
opcionalmente una vista previa de lo que hay a la entrada de la cámara
actual.
Tga.c: Funcionalidad y objetos de TGA, el cual es un formato de fichero
digital para imágenes en píxeles o de mapas de bits.
La carpeta gl_scenes, incluye los ficheros mirror.c, models.c, sobel.c,
square.c, teapot.c y yuv.c para los efectos que se apliquen a la cámara, ya
sea de dibujado de lo mostrado, o retoque.
4.3.7 Compilación y ensamblado
Aunque la compilación y ejecución se puede hacer dentro de Qt, a veces se hace
útil realizar la compilación y ejecución desde consola. Para realizarlo, se crean unos
ficheros denominados makefile que nos permitirá realizar el compilado y ensamblado del
ejecutable del programa.
Para que se genere el makefile, necesitaremos dos cosas un programa llamado
cmake, que aparece por defecto con raspbian, siendo éste, un sistema make de código
abierto utilizado para controlar el proceso de compilación de software utilizando archivos
de configuración independiente de la plataforma y del compilador independiente simples.
Estos archivos de configuración son CMakeList.txt y CMakeCache.txt.
PROGRAMA DE GESTIÓN
70
Siendo CMakeList.txt el que recoge el listado de archivos referenciados por el
código y las variables de entorno, se incluirán referencias a librerías externas
relacionadas, así como nombre de ejecutable y otras relaciones
Y en CMakeCache.txt se guardan los ajustes de compilación de manera que no
tienen que repetirse cada vez que CMake se ejecuta. Algunos valores son fijos y por
defecto, y otros eran en función del código.
Para el código C++ que se ha realizado, los ficheros CMakeList.txt y
CMakeCache.txt son muy parecidos, cambiando la ruta y el fichero relacionado con el
programa (guardar_imagen o reconocimiento). Siendo estos, los siguientes:
#CMakeList.txt
cmake_minimum_required(VERSION 2.8)
project(reconocimiento)
SET(COMPILE_DEFINITIONS -Werror)
#OPENCV
find_package( OpenCV REQUIRED )
#libfacerec para reconocimiento de caras
link_directories( /home/pi/libfacerec )
include_directories(/opt/vc/userland/host_applications/linux/libs/bcm_host/in
clude)
include_directories(/opt/vc/userland/interface/vcos)
include_directories(/opt/vc/userland)
include_directories(./gl_scenes)
include_directories(.)
include_directories(/opt/vc/userland/interface/vcos/pthreads)
include_directories(/opt/vc/userland/interface/vmcs_host/linux)
include_directories(/opt/vc/userland/interface/khronos/include)
include_directories(/opt/vc/userland/interface/khronos/common)
add_executable(reconocimiento RaspiCamControl.c RaspiCLI.c
RaspiPreview.c reconocimiento.cpp RaspiTex.c RaspiTexUtil.c tga.c
gl_scenes/teapot.c gl_scenes/models.c gl_scenes/square.c gl_scenes/mirror.c
gl_scenes/yuv.c gl_scenes/sobel.c)
target_link_libraries(reconocimiento /opt/vc/lib/libmmal_core.so
/opt/vc/lib/libmmal_util.so /opt/vc/lib/libmmal_vc_client.so /opt/vc/lib/libvcos.so
MATERIALES Y MÉTODOS
71
/opt/vc/lib/libbcm_host.so /opt/vc/lib/libGLESv2.so /opt/vc/lib/libEGL.so
/home/pi/libfacerec/libopencv_facerec.a ${OpenCV_LIBS})
#CMakeCache.txt
#Aparece solo aquellas lineas relacionadas con OpenCV y el programa.
#Abriendo fichero aparecerá completo.
//Directorio que contiene fichero de configuracion de CMake para OpenCV.
OpenCV_DIR:PATH=/usr/share/OpenCV
//El valor reconstruido por CMake
reconocimiento_BINARY_DIR:STATIC=/home/pi/reconocimiento
//El valor reconstruido por CMake
reconocimiento_SOURCE_DIR:STATIC=/home/pi/reconocimiento
Para que se genere el fichero makefile, deberemos ejecutar cmake, como aparece
en la figura 4.19:
Figura 4.19 Ejecución de cmake
Una vez generado el fichero makefile, se procederá a compilar y ensamblar el
ejecutable como aparece en la figura 4.20:
PROGRAMA DE GESTIÓN
72
Figura 4.20 Compilación y creación de ejecutable
A partir de aquí, ya se podría pasar a realizar las ejecuciones, pertinentes, incluso si
se modificase código, ya solo habría que ejecutar make (“make makefile” por defecto), y
compilaría solo la parte modificada con lo anterior ya compilado.
RESULTADOS Y DISCUSIÓN
73
5. RESULTADOS Y DISCUSIÓN
En función de las aplicaciones desarrolladas en los puntos anteriores, el presente
apartado se centrará en mostrar y describir el comportamiento de los mismos ante
diversas situaciones.
Se empezará con la aplicación guardar_imagen, para comprobar cómo detecta las
imágenes, y como termina creando las imágenes relacionadas con el empleado, así
como las actualizaciones en los ficheros de configuración.
Figura 5.1 Proceso Guardar Imagen (existe empleado)
Cuando se lanza el proceso de guardar_imagen, se comprueba si el empleado es
nuevo o bien ya existe en los ficheros de configuración, en la figura 5.1, existe el
empleado, tiene como identificador de empleado el número 0, y la siguiente imagen a
crear sería la “sergio_15.jpg” y se añadiría a la carpeta “ficheros”.
Si el empleado fuera nuevo, mostraría lo indicado en figura 5.2:
74
Figura 5.2 Guardar Imagen (no existe empleado)
En este caso, añadirá en el fichero de configuración cfg.csv, un nuevo registro,
como se puede ver en la figura 5.3:
Figura 5.3 Actualización del fichero cfg.csv
El nombre de la primera imagen donde aparecerá la cara de este empleado, se
identificará teniendo en cuenta que es nuevo (contador = 1), “nieves_1.jpg”.
Tras obtener estos datos, crearía el componente de la cámara para mostrar lo que
captura. Se puede ver en la figura 5.4, una captura de la pantalla sin ninguna cara en ella
por lo que no detectará ni guardará nada.
RESULTADOS Y DISCUSIÓN
75
Figura 5.4 Captura de PiCam
Una vez aparezca un rostro en la imagen (figura 5.5), lo detectará por el algoritmo
de Haar, y pasará a guardar primero la imagen y después los nuevos datos en el
fichero.csv.
Figura 5.5 Cara detectada por PiCam
Se puede ver lo que muestra la cámara, con esa imagen, mediante algoritmo de
Haar, recortado de la imagen y redimensionado a 100 x 100 píxeles, creará una nueva
imagen o varias imágenes, en función del tiempo de exposición, como se puede ver en la
figura 5.6:
76
Figura 5.6 Consola muestra guardado
Se puede comprobar que se ha realizado el guardado de 3 ficheros de imágenes
para el empleado, y se ha añadido dichos registros en el fichero plano ficheros.csv, como
se puede observar en la figura 5.7:
Figura 5.7 Actualización del fichero ficheros.csv
RESULTADOS Y DISCUSIÓN
77
Se puede comprobar cómo son las imágenes, y que solo recogen la cara quitando
el resto de la imagen que se veía en figura 5.5 (figura 5.8).
Figura 5.8 Cara recortada de la imagen
Una vez ya se hayan guardado las imágenes de todos los empleados, se podrá
pasar con la siguiente aplicación de reconocimiento de caras.
Al ejecutar la aplicación de reconocimiento de caras, se le pasaran 4 datos, dos
ficheros de configuración, siendo estos ficheros.csv y cfg.csv, el histograma, y el valor de
umbral de predicción. Se puede ver en la figura 5.9:
Figura 5.9 Ejecución de aplicación de reconocimiento
78
Al comienzo de la ejecución, lo primero que hará será en función de las imágenes
incluidas en el fichero de configuración de ficheros.csv y cfg.csv, preparar para entrenar
las imágenes en función de cada empleado. Se puede ver, que se han cargado 39
imágenes, y luego se distribuyen por empleado para saber identificarlos, y pasar a
entrenarlos para el proceso de reconocimiento. Al terminar de entrenar, la PiCam
empezará a obtener fotogramas (figura 5.10), por lo que se abrirá una ventana para
mostrar lo que captura.
Figura 5.10 Captura de PiCam
Ahora, empezará a buscar caras, con el algoritmo de Haar (igual que en el
programa anterior), pero en este caso, una vez detectada la cara, mediante algoritmo de
EigenFaces, tratara de encontrar a quién pertenece el rostro detectado (figura 5.11).
RESULTADOS Y DISCUSIÓN
79
Figura 5.11 Cara detectada e identificada
A parte de indicarlo en la misma ventana de video con un cuadrado rodeando la
cara y el nombre, también en el terminal de consola, indicaremos cual es el empleado
que se ha detectado (figura 5.12).
Figura 5.12 Cara reconocida indicado por terminal
El hecho de que aparezca varias veces, es por cada fotograma, aunque solo se
guardará una vez en el fichero. El motivo de no cortar la aplicación es que nos permita
capturar distintas caras y poder guardarlas todas de una vez. Ahora, se mostraran unos
ejemplos de distintas caras en las figuras 5.13 y 5.14.
Figura 5.13 Cara reconocida mediante EigenFaces
80
Figura 5.14 Cara reconocida indicado por terminal
Se ha cogido una fotografía y se ha probado con una persona que ya tenía
guardadas imágenes, y se puede ver en la figura 5.15, que ha cogido el empleado
correcto.
Figura 5.15 Cara guardada de empleado
Se han probado varios casos, y se comprueba que funciona correctamente (figura
5.16). Según se ha ido bajando el valor del umbral de predicción, empiezan a salir falsos
positivos. A parte, las variaciones en luminosidad pueden provocar que también
aparezcan los falsos positivos.
RESULTADOS Y DISCUSIÓN
81
Figura 5.16 Cara reconocida por EigenFaces
Una vez obtenido los empleados detectados por la PiCam, se guardará en una lista
de cadena de caracteres (string), para que al final de la ejecución guarde los datos
asociados a esa captura para el control de asistencia en unos ficheros incluidos en la
carpeta de “detectados” (figura 5.17).
Figura 5.17 Datos incluidos de fichero de Salida
Y con el script enviar.sh, se enviarán el fichero anterior a un servidor FTP, siempre
y cuando el cliente FTP esté instalado en Raspbian.
Ante la problemática existente debido a que ante variaciones de luz, a veces no es
tan eficiente el proceso, el uso del algoritmo de EigenFaces en vez del de FisherFaces,
no es del todo eficiente. En muchos casos por estos problemas, el umbral de predicción
es necesario bajarlo, lo cual conlleva problemas al no identificar correctamente al
empleado.
Pero debido al problema del coste computacional y que la Raspberry pese a ser un
gran equipo de bajo coste, se queda corto algo corto para usar el algoritmo de
FisherFaces, por lo que se ha tenido que usar el algoritmo de EigenFaces.
LÍNEAS DE FUTURO
82
6. CONCLUSIONES
En el presente Trabajo fin de Grado se ha desarrollado una aplicación de
reconocimiento de caras basada en visión por computador de bajo coste.. El desarrollo se
ha centrado en la detección y seguimiento de características, en este caso, las caras de
los empleados de una empresa para su control de asistencia. El objetivo inicial era
detectar la existencia o no existencia de un individuo en una secuencia de fotogramas, y
a partir de las detecciones positivas analizar el contenido, como las caras y las
características internas faciales, o seguir la evolución de las mismas con tal de extraer
información de forma automática. Para el desarrollo de este sistema se ha implementado
un código en C++ desde la cual se pueden ejecutar diferentes métodos de procesamiento
de imágenes e inteligencia artificial.
A partir de la captura de vídeo, el primer paso consistía en detectar caras mediante
aprendizaje estadístico y detectarlas usando una cascada de clasificadores. Estos
clasificadores se han trabajado sobre las características Haar-like, que nos han permitido
realizar aprendizajes y detecciones robustas, aún con las transformaciones típicas que
nos podemos encontrar, tales como cambios de iluminación o transformaciones en la
forma de las caras a detectar. Una vez la cara ha sido detectada, se ha procesado la
información recibida, para ello, teniendo en cuenta las imágenes de los empleados que
se tenían guardadas, o que se han guardado posteriormente mediante proceso de
guardar imagen, y con el método de reconocimiento de rostros llamado algoritmo de
EigenFaces, se ha procedido al identificado de del personal de la empresa.
Por último, se ha obtenido información del individuo que ha detectado y guardado
datos relativos sobre él. Los resultados muestran que las detecciones obtenidas son
robustas en un amplio rango de transformaciones producidas en entornos no controlados.
Aunque si se quisiera mayor exactitud, tendríamos que cambiar el algoritmo por el de
FisherFaces.
6.1. Líneas de futuro
Entre las líneas de futuro que creo que podemos tener, teniendo en cuenta que
están apareciendo actualmente una gran cantidad de equipos de bajo pero más potentes
que la Raspberry Pi, sería interesante encontrar uno compatible con OpenCV para
CONCLUSIONES
83
implementar el algoritmo de FisherFaces, que aunque consume mucho más recursos,
resulta más útil que el algoritmo de EigenFaces ante variaciones de iluminación y pose.
A parte, OpenCV incluye una gran cantidad de filtros, procedimientos y algoritmos
que nos permite mejorar la imagen para que el procesado de ellas, sea mucho más
efectivo. Por ello, sería interesante investigar e implementar dichos métodos para evitar
los temidos falsos positivos.
INSTALACIÓN DE RASPBIAN
84
7. ANEXOS
En los anexos vamos a incluir todo lo necesario para dejar la Raspberry lista para
poder usar la aplicación que se ha realizado para el trabajo fin de grado.
7.1. Instalación de Raspbian
Para la instalación del sistema operativo en la tarjeta SD y configuración del
entorno, hay dos opciones: Una es usando directamente la imagen de Raspbian y otra es
usando NOOBS. Esta última opción es la más sencilla y permitirá instalar también otras
distribuciones Linux para la Raspberry Pi, pero también ocupará un espacio adicional en
la tarjeta SD (que en el caso que sea de poco tamaño puede suponer un problema).
Se optará por la segunda opción, se pasará a instalar NOOBS (o New Out Of Box
Software), se tendrá que formatear la tarjeta SD con formato FAT32 (en Ubuntu podemos
hacerlo fácilmente con gparted) y copiar los archivos que nos descarguemos de la página
oficial de Raspberry Pi:
http://www.raspberrypi.org/downloads/
Después se introducirá la SD en la Raspberry: Una vez iniciada la Raspberry Pi, se
seleccionará las opciones que nos ofrezca el asistente de instalación. De esta sencilla
manera ya estará Raspbian preparado para instalarse en la Raspberry Pi en el siguiente
reinicio. Ahora, se incluirán los pasos que se indicarán en el asistente de instalación.
Una vez iniciada la Raspberry Pi tras el paso de NOOBS a la SD, aparecerá una
pantalla indicando los módulos a instalar, el idioma (no incluido el español en NOOBS).
Se deberá señalar el sistema operativo Raspbian, y se ejecutará pulsando el botón
“Install OS” como se observa en la figura 7.1.
ANEXOS
85
Figura 7.1 Inicio de Instalación
Finalizada la instalación, lo primero que aparecerá tras el inicio es el programa de
configuración raspi-config que usaremos posteriormente para la instalación de la cámara
PiCam (figura 7.2).
Figura 7.2 Programa de configuración
Las opciones que da son:
1. Expandir el sistema de archivos. Esta opción permite expandir el sistema
operativo para que utilice todo el espacio disponible en la tarjeta. Cuando se
instala Raspbian “Wheezy” la imagen copiada en la tarjeta sólo ocupa 2 GB, por
INSTALACIÓN DE RASPBIAN
86
lo tanto es necesario ejecutar esta opción para que todo el espacio de la tarjeta
SD sea utilizado. Como el sistema operativo fue instalado utilizando NOOBS, no
es necesario ejecutar esta opción. Ya el sistema operativo ha sido expandido
(figura 7.3).
Figura 7.3 Indicador de sistema expandido de archivos
2. Cambiar la contraseña de usuario. El más importante es el administrador del
sistema que se llama “root”, éste tiene acceso privilegiado a todos los archivos,
configuraciones y carpetas del sistema. El otro tipo de usuario son los comunes
como lo es “pi”, éste viene predeterminado con la contraseña “raspberry” por lo
tanto cualquier persona podría acceder su sistema (figura 7.4).
Figura 7.4 Cambio de contraseña de usuario
ANEXOS
87
3. Activación del escritorio al iniciar. Permite que ejecute el comando “startx”
automáticamente cuando se inicia el sistema, o bien, que aparezca la consola
(figura 7.5).
Figura 7.5 Activación de escritorio al iniciar
4. Opciones de Idioma. Este submenú permite cambiar el idioma del sistema
operativo (figura 7.6), cambiar la zona horaria o la distribución del teclado (“PC
genérico 105 teclas [intl]” si no apareciera el que se tenga).
Figura 7.6 Opciones de Idioma
5. Habilitar la cámara. Esta opción la veremos en el anexo 7.2.
6. Añadirse a Rastrack. Esta opción permite que su Raspberry Pi sea rastreado
por el sitio web Rastrack (http://rastrack.co.uk). Este sitio no pretende registrar o
recolectar información alguna, es una herramienta para tener la estadística de
donde se encuentran los Raspberry Pi en el mundo (figura 7.7).
INSTALACIÓN DE RASPBIAN
88
Figura 7.7 Rastrack
7. Overclock. Esta opción permite aumentar la velocidad del procesador (figura
7.8). Hay que tener en cuenta lo siguiente a la hora de modificar la velocidad.
Primero, la vida del dispositivo se puede disminuir considerablemente.
Segundo, el dispositivo generará más calor, por lo tanto es recomendable tener
disipadores en el procesador, en circuito de Ethernet y en regulador de energía.
Tercero, va a necesitar una fuente de alimentación de mayor capacidad para
que pueda compensar la nueva velocidad seleccionada.
Figura 7.8 Overclock
8. Opciones Avanzadas. Éste abrirá otro submenú que permitirá las siguientes
opciones (figura 7.9):
A1 overscan, sirve para borrar las líneas negras en algunos monitores o
televisores.
ANEXOS
89
A2 Hostname, sirve para identificar su Raspberry Pi en la red local.
A3 Distribución de la memoria (Memory Split), le permite seleccionar la
cantidad de memoria compartida entre la CPU y la unidad de gráficos
(GPU), el modelo B versión 2.0 cuenta con 512 MB en total. El
predeterminado es 64 MB para la memoria de vídeo. Si piensa ejecutar
aplicaciones que requieren alto procesamiento gráfico como ver
películas o ver imágenes aumente el valor. Tenga en cuenta que, al
aumentar la memoria del vídeo y disminuir la del procesador, éste podrá
ejecutar mejor los gráficos a cambio de ralentizarse al ejecutar otras
tareas.
A4 Activar SSH (Enable SSH), se utiliza para acceder el Raspberry Pi
remotamente desde un cliente SSH. Habilitaremos está opción.
A5 SPI se utiliza para habilitar al inicio el modulo SPI Kernel.
A6 Audio se utiliza para forzar el audio para que salga automáticamente
por la conexión HDMI.
A7 Actualizar (update) se utiliza para que descargue una actualización
del sistema. Se puede hacer desde la línea de comandos de la consola,
ejecutando “sudo apt-get update”.
Figura 7.9 Opciones avanzadas
9. Información sobre raspi-config (figura 7.10).
INSTALACIÓN DE CÁMARA PI
90
Figura 7.10 Información de raspi-config
7.2. Instalación de la Cámara Pi
Para la instalación de la Pi Cámara en la Raspberry Pi (figura 7.11) tenemos que
seguir unos pasos básicos. Hay que tener mucho cuidado con ella, debido a que la
cámara es sensible a la estática - o ESD por sus siglas en inglés - por lo que se debe
manipular con el debido cuidado.
El primer paso, y como es lógico, será conectar el modulo en la Raspberry Pi. La
conexión se hace mediante un bus de cinta (flexible) tipo Ribbon que irá conectado al
conector especial que hay junto al conector Ethernet. Comprobar que está bien colocado
y cerrar las pestañas que están a los lados. Quedando tal que así:
Figura 7.11 PiCam conectada a Raspberry Pi
Una vez conectado, deberemos encender la Raspberry para configurarla y
comprobar que está correctamente instalada.
ANEXOS
91
Para no tener que conectar todo, es ideal establecer una conexión SSH para
configurarlo. Una vez encendida la Raspberry Pi, ejecutaremos los siguientes comandos
en la consola de Raspbian.
sudo apt-get update
sudo apt-get-upgrade
Estos comandos se deben ejecutar paso a paso, dando tiempo a que el comando
anterior termine.
El último paso y el más importante será habilitar el modulo cámara en la
configuración de Raspberry Pi. Para abrir el menú de configuración de Raspberry
usaremos el siguiente comando.
sudo raspi-config
Mostrando la siguiente ventana de configuración de la Raspberry (figura 7.12):
Figura 7.12 Ventana de configuración de Raspbian
Si todo está correcto, tendremos la opción para habilitar y deshabilitar el soporte
para la cámara (figura 7.13). Seleccionamos esa opción y presionamos Enter.
INSTALACIÓN DE CÁMARA PI
92
Figura 7.13 Habilitado de CamPi
Una vez pulsado en Enabled, vamos a la opción Finish, y nos parecerá la siguiente
ventana (figura 7.14):
Figura 7.14 Confirmado de reinicio
Se seleccionará la opción que pone <Si> para que la Raspberry Pi se reinicie y los
cambios tengan efecto.
Ahora, para comprobar que la cámara funciona correctamente una vez que se haya
iniciado, entramos en el escritorio con el comando startx. Después, accedemos a consola
y ejecutaremos el siguiente comando:
raspistill -v -o test.jpg
ANEXOS
93
Este comando aparecerá una vista previa de 5 segundos de la cámara, luego se
guardará el archivo test.jpg y se mostraran una serie de datos de la imagen tomada
(figuras 7.15 y 7.16).
Figura 7.15 Información de PiCam
Siendo la imagen resultante test.jpg, la siguiente:
INSTALACIÓN DE OPENCV Y OTROS MÓDULOS
94
Figura 7.16 Imagen tomada por PiCam
Si se quisiera guardar el video se tendrá que ejecutar el siguiente comando:
raspivid -o pruebavideo.h264 -t 10000
Quedará guardado un video de 10000 milisegundos en formato h264, el cual
podremos pasar a otros formatos con las actualizaciones pertinentes.
7.3. Instalación de OpenCV y otros módulos
Para la instalación de OpenCV se necesita entrar en el modo consola de Raspbian,
y ejecutar ciertos comandos en este orden:
sudo apt-get update
sudo apt-get install libopencv-dev
sudo apt-get install python-opencv
Pese a que el código es en C, el módulo de python también es interesante instalarlo
por ciertos scripts que ejecute para ciertas pruebas. En función de la versión de OpenCV
que se instale, será necesario añadir la librería de reconocimiento facial llamada
ANEXOS
95
“libfacerec-0.04”, la cual puede descargarse fácilmente desde la página de GITHUB en
https://github.com/bytefish/libfacerec/zipball/v0.04 (figura 7.17):
Figura 7.17 Descarga de Librería
Figura 7.18 Ruta de guardado de librería
INSTALACIÓN DE QT4
96
Para compilar correctamente usando LIBOpenCV, se debe modificar el archivo
CMakeLists.txt, enlazando donde se encuentra instalada la nueva librería.
cmake_minimum_required(VERSION 2.8)
project( reco)
find_package( OpenCV REQUIRED )
add_executable( programa programa.cpp )
link_directories( ${RUTA_LIB}/libfacerec-0.04 )
target_link_libraries( displayimage ${RUTA_LIB}/libopencv_facerec.a
${OpenCV_LIBS} )
Siendo “programa.cpp”, el código que cargará la nueva librería, y RUTA_LIB, la ruta
donde esté instalada la librería.
7.4. Instalación de Qt4
Para la instalación de Qt4 se necesita entrar en el modo consola de Raspbian y
ejecutar ciertos comandos en el orden siguiente:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install g++
sudo apt-get install qt4-dev-tools
sudo apt-get install qtcreator
sudo apt-get install gcc
sudo apt-get install xterm
sudo apt-get install git-core
sudo apt-get install subversion
Una vez instalado todo, tendrá la siguiente forma (figura 7.19):
ANEXOS
97
Figura 7.19 Ventana de trabajo Qt
Sólo se tendría que configurar la ruta del compilador gcc (figura 7.20). Una vez
hecho, no habría ningún problema a la hora de crear código y trabajar con él.
Figura 7.20 Configuración del compilador gcc
7.5. Instalación de Cliente FTP
Para instalar el cliente FTP, deberemos instalar el complemento adecuado, para
ello, desde la consola de terminal, pulsamos “apt-get install ftp”, como se ve en la figura
7.21:
INSTALACIÓN DE CLIENTE FTP
98
Figura 7.21 Instalación de paquete FTP
BIBLIOGRAFÍA
99
8 Bibliografía
Paul Viola y Michael Jones (2004). Robust real-time face detection. International Journal
of ComputerVision
M. Turk y A. Pentland (1991). Eigenfaces for recognition. J. Cognitive Neuroscience
Documentación sobre la RaspiCam:
http://www.raspberrypi.org/wp-content/uploads/2013/07/RaspiCam-Documentation.pdf
Documentación general sobre OpenCV: http://docs.opencv.org
Documentación de modulo de reconocimiento facial:
http://docs.opencv.org/trunk/modules/contrib/doc/facerec/index.html
Documentación sobre funciones del algoritmo Haar:
http://opencv.jp/opencv-2svn_org/c/objdetect_cascade_classification.html
Documentación sobre CMake: http://www.cmake.org/Wiki/CMake_FAQ
Documentación sobre algoritmos holísticos para reconocimiento de caras:
http://www.cs.columbia.edu/~belhumeur/journal/fisherface-pami97.pdf
Representación de caras mediante EigenFaces:
https://upcommons.upc.edu/revistes/bitstream/2099/9853/1/Article005.pdf
Reconocimiento de caras: Eigenfaces y Fisherfaces:
https://eva.fing.edu.uy/file.php/514/ARCHIVO/2010/TrabajosFinales2010/informe_final_ott
ado.pdf