Upload
duongmien
View
225
Download
0
Embed Size (px)
Citation preview
UNIVERSIDAD DE SEVILLA
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA
Análisis visual y transmisión de
imágenes en redes inalámbricas de
sensores
Autor: Pablo Chacón Carrión
Tutor: María Teresa Ariza Gómez
Proyecto Fin de Carrera
Ingeniería de Telecomunicación
Sevilla, 2014
II
III
PROYECTO FIN DE CARRERA
ANÁLISIS VISUAL Y TRANSMISIÓN DE
IMÁGENES EN REDES INALÁMBRICAS
DE SENSORES
Autor:
Pablo Chacón Carrión
Tutor:
Dña. María Teresa Ariza Gómez
Dr. en Informática
Profesora Titular del Departamento de Ingeniería Telemática
Tutor Auxiliar:
D. Matteo Cesana
Dr. Ingeniero de Telecomunicación
Profesor Asistente en el Politécnico de Milán
IV
A mis padres Fernando y Lola, por no perder nunca la fe en mi
A mi tía Ana, por ser muchas veces más que una madre
A mis hermanos Álvaro, Lola y Ana, por ser mi fuente de inspiración para hacer las cosas lo mejor
posible.
A Simona Cavasio, por alegrarme cada día y darme ánimos para acabar este Proyecto
A toda mi familia
A mis compañeros de promoción y del Colegio Mayor Guadaira y Torrescalla, por haber
conseguido que mi etapa universitaria sea inolvidable.
V
VI
Resumen
En este Proyecto, realizado en el laboratorio Antlab (Advanced Network Technologies
Laboratory) del Politécnico de Milán, se realiza el estudio comparativo de detección y
extracción de propiedades en imágenes para su posterior envío a través de una red
inalámbrica de sensores.
Estos dispositivos consisten en unos micro-controladores funcionando como sensores, nodos
de reenvío y/o nodos centrales que permiten añadir una mayor cobertura a la red, teniendo a
la vez un funcionamiento de bajo consumo y de total independencia entre ellos. Este nuevo
hardware fue recientemente adquirido por el laboratorio y por ello la necesidad de realizar
este estudio intenso, novedoso en ellos.
En más detalle, se usan unos descriptores binarios de imágenes como herramienta para el
envío óptimo de estas imágenes, adquiridas mediante una cámara adaptada a uno de los
nodos que conforman esta red de dispositivos o precargadas directamente en ellos.
Además, se realiza un estudio y comparación del tiempo de cálculo de estos descriptores
para tener una estimación del tiempo de procesamiento de todo el procedimiento.
Este Proyecto es meramente un estudio cualitativo y cuantitativo de todo el proceso de
cálculo computacional y envío con múltiples saltos en redes distribuidas.
Se añade, para cerrar el estudio, la explicación de cómo implementar el estudio para un
reconocimiento de objetos en el nodo central de la red, una técnica ampliamente utilizada y
con múltiples usos prácticos en la actualidad.
Quiero aprovechar la ocasión para agradecer al profesor Matteo Cesana por permitir
ocuparme de este Proyecto y darme las guías necesarias para llevarlo a cabo, y a los
estudiantes de doctorado y profesores Alessandro Redondi y Antonio Canclini por ayudarme
y corregirme día tras día en el laboratorio.
VII
Abstract
In this Project, carried out in the Antlab laboratory (Advanced Network Technologies
Laboratory) of the Polytechnic of Milan, a comparative feature detection and extraction
study is performed on images for a later delivery via a wireless sensor network.
These devices are some microcontrollers operating as sensors, forwarding nodes and/or sink
nodes that let adding more coverage to the network, having low power operation and total
independence between them. This new hardware was recently acquired by the laboratory and
thus the need for this intense test, completely new in them.
In more detail, some binary descriptors are used as a tool for the optimal transmission of
these images, which are acquired by a camera adapted to one of the nodes that shapes this
network or are directly preloaded on them.
Furthermore, a study and comparison of the descriptors calculation time is also performed in
order to have a general estimation of the processing time.
This Project is merely a qualitative and quantitative study of the entire process of
computational calculation and delivery in distributed multi-hop networks.
In addition, and to close down this project, it is included an explanation of how to practically
implements an object recognition study in the network sink node, a technique that is widely
used and has got lots of practical applications nowadays.
I would like to take this opportunity to thank Professor Matteo Cesana for letting me holding
this Project and giving me the necessary guidelines for its implementation, and also doctoral
students and professors Alessandro Redondi and Antonio Canclini for helping me and
correcting me every day in the laboratory.
VIII
Índice General
Resumen .............................................................................................................................. VI
Abstract ............................................................................................................................... VII
Índice de figuras .................................................................................................................. XI
Índice de tablas ................................................................................................................. XIV
Capítulo 1. Introducción. Motivación y objetivos ................................................................. 1
1.1. Escenario de Referencia .......................................................................................................... 1
1.1.1. Redes inalámbricas de sensores (WSN) ........................................................................... 1
1.1.2. Redes de sensores visuales .............................................................................................. 6
1.2. Problema de Referencia .......................................................................................................... 7
1.3. Ambiente de referencia ........................................................................................................ 10
1.4. Contribuciones ...................................................................................................................... 11
1.5. Aplicaciones ........................................................................................................................... 12
1.6. Resto de la memoria ............................................................................................................. 15
Capítulo 2. Conceptos de teoría de imágenes ...................................................................... 17
2.1. Procesamiento digital de imágenes ...................................................................................... 17
2.1.1. Introducción ................................................................................................................... 17
2.1.2. Pasos fundamentales ..................................................................................................... 21
2.2. Análisis visual por computador ............................................................................................. 26
2.3. Descriptores visuales de imágenes ....................................................................................... 28
2.3.1. Descriptores de información general ............................................................................. 29
2.3.2. Descriptores de información específica ......................................................................... 34
2.4. Métodos basados en propiedades y puntos de interés ........................................................ 37
2.4.1. Visión general ................................................................................................................. 37
2.4.2. BRISK: El método ............................................................................................................ 40
Capítulo 3. Tecnología usada .............................................................................................. 46
3.1. Sistemas operativos .............................................................................................................. 46
3.1.1. Distribución Linux Ubuntu 12.04 LTS ............................................................................. 46
IX
3.1.2. Distribución Linux Ångström .......................................................................................... 47
3.1.3. TinyOS............................................................................................................................. 48
3.2. Entorno de desarrollo ........................................................................................................... 49
3.2.1. Compilación cruzada ...................................................................................................... 49
3.3. Hardware usado .................................................................................................................... 49
3.3.1. Cámara Logitech QuickCam® S 7500™ ........................................................................... 50
3.3.2. BeagleBone ..................................................................................................................... 51
3.3.3. Controlador central y receptor ...................................................................................... 55
3.4. Librerías OpenCV ................................................................................................................... 55
3.5. Protocolos de comunicación inalámbricos ........................................................................... 57
3.6. Otros protocolos ................................................................................................................... 58
3.7. Analizadores de tráfico y protocolos ..................................................................................... 60
Capítulo 4. Descripción del trabajo realizado ..................................................................... 61
4.1. Modelo práctico .................................................................................................................... 61
4.2. Instalación y configuración .................................................................................................... 63
4.2.1. Configuración de Eclipse para la compilación cruzada .................................................. 63
4.2.2. Instalación de las librerías OpenCV ................................................................................ 64
4.3. Errores encontrados en la instalación y configuración ......................................................... 65
4.4. Programación del hardware .................................................................................................. 66
4.4.1. Programa de obtención de las imágenes ....................................................................... 66
4.4.2. Programa de obtención de tiempos locales del algoritmo BRISK .................................. 67
4.4.3. Programación del nodo con la cámara ........................................................................... 70
4.4.4. Programación del controlador central ........................................................................... 71
4.5. Configuración de los BeagleBone .......................................................................................... 71
4.5.1. Establecer la comunicación con el BeagleBone ............................................................. 72
4.5.2. Configuración del nodo de reenvío ................................................................................ 74
4.5.3. Configuración NTP .......................................................................................................... 76
Capítulo 5. Descripción y evaluación de resultados ............................................................ 79
5.1. Muestras utilizadas ............................................................................................................... 79
5.2. Tiempos obtenidos en la detección ...................................................................................... 81
5.2.1. Resultados en el BeagleBone ......................................................................................... 82
X
5.2.2. Resultados en el ordenador Intel ................................................................................... 88
5.3. Tiempos obtenidos en la extracción ..................................................................................... 91
5.3.1. Resultados en el BeagleBone ......................................................................................... 92
5.3.2. Resultados en el ordenador Intel ................................................................................... 97
5.4. Tiempos obtenidos en la transmisión ................................................................................... 99
5.4.1. Conexión directa con cable Ethernet ........................................................................... 101
5.4.2. Conexión directa con protocolo WiFi ........................................................................... 102
5.4.3. Conexión indirecta con un salto con protocolo WiFi ................................................... 104
5.4.4. Conexión indirecta con dos saltos con protocolo WiFi ................................................ 106
5.5. Comentarios de tiempos de reconocimiento...................................................................... 107
Capítulo 6. Conclusión y líneas futuras de estudio ............................................................ 109
Bibliografía ........................................................................................................................ 112
Anexos ............................................................................................................................... 116
XI
Índice de figuras
Ilustración 1: Disposición de una WSN ................................................................................ 2
Ilustración 2: Ejemplo de red Ad Hoc ................................................................................... 5
Ilustración 3: Diagrama básico de una VSN ......................................................................... 7
Ilustración 4: Cobertura y gestión de eventos en VSN .......................................................... 8
Ilustración 5: Aplicaciones de las WSN .............................................................................. 13
Ilustración 6: Aplicación de las WNS en una carretera ....................................................... 14
Ilustración 7: Concepto de píxel en una imagen ................................................................. 18
Ilustración 8: Espectro EM conforme a la energía por fotón .............................................. 19
Ilustración 9: Ejemplo de reconocimiento de números en una imagen ............................... 21
Ilustración 10: Pasos en el procesamiento de imágenes ...................................................... 22
Ilustración 11: Ejemplo de realce de color en una foto ....................................................... 23
Ilustración 12: Relaciones entre visión por computador y otras áreas afines ...................... 27
Ilustración 13: Seguimiento de jugadores en un partido ..................................................... 28
Ilustración 14: Reconocimiento de expresión facial............................................................ 29
Ilustración 15: Descriptores visuales del estándar MPEG-7 ............................................... 31
Ilustración 16: Detección de Bordes y Crestas .................................................................... 36
Ilustración 17: Ejemplo de descriptor SIFT ........................................................................ 39
Ilustración 18: Primer plano de la detección BRISK .......................................................... 42
Ilustración 19: Patrón de muestreo BRISK con N = 60 puntos ........................................... 43
Ilustración 20: Pantalla de inicio de Ångström ................................................................... 47
Ilustración 21: Cámara sensor Logitech QuickCam ............................................................ 50
Ilustración 22: Micro-controlador BeagleBone ................................................................... 52
Ilustración 23: Componentes del BegleBone ...................................................................... 54
Ilustración 24: BeagleBone Black ....................................................................................... 54
Ilustración 25: Dongle WiFi 802.11n .................................................................................. 58
Ilustración 26: Modelo práctico de estudio ......................................................................... 62
Ilustración 27: Conexión del BeagleBone ........................................................................... 72
Ilustración 28: Imagen original ........................................................................................... 80
Ilustración 29: Imágenes escaladas al 10 y 25% ................................................................. 81
Ilustración 30: Resultados de detección en el BeagleBone (768x1024 píxeles) ................. 83
Ilustración 31: Resultados de detección en el BeagleBone (384x512 píxeles) ................... 85
Ilustración 32: Resultados de detección en el ordenador (768x1024 píxeles) .................... 89
Ilustración 33: Resultados de la detección en el ordenador (384x512 píxeles)................... 90
Ilustración 34: Resultados de la extracción en el BeagleBone (768x1024 píxeles) ............ 93
Ilustración 35: Resultados de la extracción en el BeagleBone (384x512 píxeles) .............. 96
Ilustración 36: Resultados de la extracción en el ordenador (768x1024 píxeles) ............... 98
Ilustración 37: Resultados de la extracción en el ordenador (384x512 píxeles) ................. 98
Ilustración 38: Topología con un BeagleBone (cable Ethernet)........................................ 102
XII
Ilustración 39: Topología con un BeagleBone (WiFi) ...................................................... 103
Ilustración 40: Topología con 2 BeagleBone (WiFi) ........................................................ 105
Ilustración 41: Topología con tres BeagleBone ................................................................ 106
Ilustración 42: Descarga del toolchain .............................................................................. 118
Ilustración 43: Centro de Software de Ubuntu .................................................................. 120
Ilustración 44: Crear nuevo proyecto ................................................................................ 121
Ilustración 45: Ventana de Nuevo Proyecto ...................................................................... 122
Ilustración 46: Build Configurations ................................................................................. 122
Ilustración 47: Configuración de compilación .................................................................. 123
Ilustración 48: Crear nueva configuración ........................................................................ 123
Ilustración 49: Seleccionar propiedades del proyecto ....................................................... 124
Ilustración 50: Propiedades del proyecto........................................................................... 124
Ilustración 51: Propiedades del compilador cruzado ......................................................... 125
Ilustración 52: Ruta de directorio hasta ficheros include .................................................. 126
Ilustración 53: Librerías de enlazado................................................................................. 126
Ilustración 54: Propiedades del ensamblador .................................................................... 127
Ilustración 55: Seleccionar la configuración de compilación ............................................ 128
Ilustración 56: Configuración del compilador para OpenCV ............................................ 130
Ilustración 57: Librerías de enlazado para OpenCV ......................................................... 131
XIII
XIV
Índice de tablas
Tabla 1: Métodos de detección de propiedades y usos ........................................................ 37
Tabla 2: Especificaciones de la cámara Logitech QuickCam ............................................. 51
Tabla 3: Especificaciones del BeagleBone Rev A6 ............................................................ 53
Tabla 4: Gráfico de tiempos de detección en el BeagleBone (768x1024) .......................... 84
Tabla 5: Gráfico de tiempos de detección en el BeagleBone (384x512) ............................ 87
Tabla 6: Gráfico de tiempos de detección en el BeagleBone 2 (768x1024) ....................... 88
Tabla 7: Gráfico de tiempos de extracción en el BeagleBone (768x1024) ......................... 95
Tabla 8: Gráfico de tiempos de extracción en el BeagleBone (384x512) ........................... 97
XV
1
Capítulo 1
Introducción. Motivación y objetivos
En este primer capítulo se realiza una definición de los aspectos que se han tenido por
referencia. Se aclara la base y los contenidos que se van a explicar en el resto de la memoria
haciendo hincapié en los problemas a tratar y las contribuciones conseguidas en este
Proyecto Fin de Carrera.
1.1. Escenario de Referencia
Como escenario de referencia a tener en cuenta en este Proyecto se podrían tener las Redes
Inalámbricas de Sensores (o WSN, como término abreviado en la literatura inglesa de
“Wireless Sensor Networks”) y las Redes de Sensores Visuales (o VSN, del mismo modo
abreviado de “Visual Sensor Networks”).
1.1.1. Redes inalámbricas de sensores (WSN)
En las últimas décadas hemos asistido a un explosivo crecimiento de las redes de
computadores y en concreto de las comunicaciones inalámbricas, propiciado por los
continuos avances tecnológicos. Así, han aparecido circuitos electrónicos cada vez más
pequeños, potentes y de menor coste, permitiendo también en esta línea, importantes avances
en el campo de los transductores. Todo ello permite el desarrollo de nuevos dispositivos para
2
la detección y medida de cualquier magnitud de forma sencilla y con gran precisión, siendo
estos dispositivos de pequeño tamaño y bajo coste.
Estos factores han dado cabida al despegue del campo de investigación de las Redes
Inalámbricas de Sensores, que han sido identificadas como una de las tecnologías más
prometedoras por diversos analistas tecnológicos y revistas especializadas.
Dando una definición informal, una red inalámbrica de sensores (WSN en adelante) es una
distribución de dispositivos electrónicos autónomos que incorporan las propiedades
mencionadas anteriormente y que se relacionan entre ellos mediante un protocolo de
comunicación inalámbrico. Un sistema WSN incorpora una puerta de enlace o gateway (ver
Figura 1) que proporciona conectividad inalámbrica mediante un protocolo seleccionado
dependiendo de los requisitos de la aplicación y que será mencionado más en detalle en esta
memoria.
Ilustración 1: Disposición de una WSN
La principal innovación hacia estos sistemas consiste en sustituir sensores de elevada
complejidad (y por tanto caros y limitados en número) y su infraestructura de
comunicaciones asociada, por un conjunto mucho mayor de dispositivos más sencillos, que
resultan considerablemente más baratos y que también actúan como sensores, obteniendo
magnitudes físicas del entorno y además dando soporte a las comunicaciones de otros nodos
como elementos de infraestructura.
3
La característica principal de las WSN es su capacidad de organización automática. Así, es
posible realizar despliegues de sensores en lugares de difícil acceso, o incluso en el interior
de zonas afectadas por catástrofes, mediante medios aéreos. Gracias a esta característica es
posible mantener la red en funcionamiento incluso cuando algunos nodos se encuentran
fuera de servicio, con problemas debidos a fallos, con agotamiento de baterías, en modo de
bajo consumo, etc. En estos casos la red es capaz de reorganizarse y continuar funcionando.
Las WSN se basan en dotar a cada nodo de enlaces de radio de baja potencia, de tal modo
que el área de cobertura es relativamente pequeña. De esta forma se consigue economizar de
forma significativa el consumo de potencia, mientras que, en cambio, es necesario
proporcionar mecanismos de encaminamiento con múltiples saltos, que permitan la
comunicación con los nodos más alejados.
Otra ventaja es la reutilización de frecuencias, ya que dos nodos con áreas de cobertura
disjuntas podrán emplear la misma banda de transmisión. Si la densidad de nodos es lo
suficientemente grande, este mecanismo permite establecer múltiples rutas para cada destino
posible, permitiendo la implementación de técnicas de tolerancia a fallos contemplando rutas
redundantes (y de gestión global de energía) empleando rutas alternativas para balancear el
consumo entre nodos.
Otra ventaja significativa consiste en la posibilidad de plantear mecanismos de cooperación
entre nodos; bien mediante distribución de funciones, por ejemplo realizando cada nodo una
labor complementaria a sus vecinos; o bien mediante procesos redundantes, donde cada nodo
supervisa el comportamiento del vecino.
Sin embargo, estas capacidades vienen limitadas por dos factores fundamentales: coste y
consumo. Así, en la mayoría de las aplicaciones se pretende que los nodos no requieran
mantenimiento, explotando el concepto de nodos de “usar y tirar”, puesto que una vez
desplegados no son recuperables. Para ello se requiere que su coste sea mínimo, y que
realicen un aprovechamiento óptimo de la energía, maximizando el tiempo de servicio.
El diseño de una red de sensores está motivado o influido por uno o más de los siguientes
requisitos:
4
Despliegue masivo y aleatorio: La mayoría de las WSN contienen un número muy
grande de sensores (del orden de cientos o millares), que pueden diseminarse de
forma aleatoria en las áreas de interés o ser lanzadas desde un avión sobre terrenos
inaccesibles o peligrosos. El sistema debe llevar una configuración automática antes
de llevar a cabo las tareas de medida requeridas.
Redundancia de la información: la alta densidad de nodos sensores hace que los datos
obtenidos en uno de ellos sean redundantes con respecto a otros nodos de su entorno.
Límite de recursos: El diseño e implementación de WSN debe tener en cuenta cuatro
límites de recursos: energía, potencia de cálculo, memoria y ancho de banda. Además
de estar generalmente limitados en tamaño, los sensores dependerán de sus baterías y
de la energía que puedan extraer del entorno para su funcionamiento. Por ello (y por
economizar costes), los nodos habitualmente están limitados en memoria, potencia de
cálculo y ancho de banda.
Topología y entornos dinámicos: La topología en la cual se despliega una red de
sensores no es fija, sino que puede existir movimiento de sensores e incluso
desaparición o adición de nodos. Las WSN deben ser capaces de reconfigurarse de
forma autónoma frente a estos avatares.
Medio de transmisión poco fiable: La utilización de comunicaciones inalámbricas
presenta una tasa de errores considerablemente mayor que las comunicaciones
cableadas.
Diversidad de aplicaciones: debido a las propiedades de las WSN, donde en cada una
de ellas pueden primar más unas características que otras (robustez, consumo, calidad
de servicio o QoS, alcance, etc.)
Seguridad y privacidad: estos factores son especialmente importantes en aplicaciones
militares o de vigilancia. Por tanto, los ataques de denegación de servicio, intrusión o
manipulación de datos en estas aplicaciones deben estar previstos.
Otro concepto importante dentro del contexto del Proyecto en referencia a la tipología de las
5
redes inalámbricas es el término de red “ad hoc” inalámbrica. Una red ad hoc inalámbrica o
descentralizada es un tipo de red inalámbrica que no depende de una infraestructura pre-
existente, como routers (en redes cableadas) o de puntos de acceso en redes inalámbricas
administradas. En lugar de ello, cada nodo participa en el encaminamiento mediante el
reenvío de datos hacia otros nodos, eligiéndose éstos dinámicamente en base a la
conectividad de la red.
En adición al encaminamiento clásico, las redes ad hoc pueden usar el mecanismo de
inundación o flooding para el re-envío de datos. Este mecanismo de inundación consiste en
un algoritmo simple de enrutamiento en el cuál se envían todos los paquetes entrantes por
cada interfaz de salida, excepto por la que se ha recibido. Debido a la manera en la que
funciona el algoritmo de enrutamiento se garantiza que un paquete es entregado (si éste
puede ser entregado).
En la siguiente figura podemos ver un claro ejemplo de una red “ad hoc”, ampliamente
utilizada en la práctica:
Ilustración 2: Ejemplo de red Ad Hoc
Por lo tanto, la naturaleza descentralizada de las redes ad hoc las hace aptas para una
variedad de aplicaciones en las que no se depende de equipos centrales, y que pueden
mejorar la escalabilidad de las redes en comparación con redes inalámbricas administradas.
En cuanto a los requisitos técnicos, una red ad hoc se compone de varios "nodos" conectados
por "links". Los enlaces o links están limitados por los recursos del nodo (por ejemplo,
potencia de transmisión, potencia de cálculo y memoria) y las propiedades de
comportamiento (p.ej. fiabilidad), así como de las propiedades de enlace (p.ej. la duración de
la conexión y la pérdida de señal, interferencia y ruido). Como los enlaces pueden ser
6
conectados o desconectados en cualquier momento, una red en funcionamiento debe ser
capaz de hacer frente a estas re-estructuraciones dinámicas, preferiblemente de una manera
oportuna, eficiente, fiable, robusta y escalable.
Teniendo en cuenta estas características y conociendo el hecho de que son muy fáciles de
implementar, las redes ad hoc juegan un papel muy importante en este Proyecto y serán
ampliamente mencionadas a lo largo de este.
1.1.2. Redes de sensores visuales
Podemos considerar a las redes de sensores visuales como un subconjunto de las redes
inalámbricas de sensores. De hecho, gran parte de la teoría y de las aplicaciones de este
último se aplican a la primera.
Las redes de sensores visuales (VSN en adelante) conforman una red de dispositivos
inteligente (generalmente cámaras) distribuidas espacialmente, capaces de procesar y
fusionar imágenes de una escena de una variedad de puntos de vista en una forma más útil
que las imágenes individuales.
La red, por lo tanto, generalmente consiste en las propias cámaras, que tienen ciertas
capacidades de procesamiento de imágenes, de comunicación y de almacenamiento locales y
uno o más ordenadores centrales, donde los datos de imagen de varias cámaras se procesan
adicionalmente y se fusionan (este procesamiento puede, sin embargo, simplemente tener
lugar de una manera distribuida a través de las cámaras y sus controladores locales). Las
VSN también ofrecen algunos servicios de alto nivel hacia el usuario, de manera que la gran
cantidad de datos se pueda tratar consiguiendo información de interés a través de consultas
específicas.
7
Ilustración 3: Diagrama básico de una VSN
La diferencia principal entre las VSN y otros tipos de redes de sensores es la naturaleza y el
volumen de la información que los sensores individuales adquieren. A diferencia de la
mayoría de los sensores, las cámaras son direccionales en su campo de visión, y captan una
gran cantidad de información visual que puede estar parcialmente procesada de forma
independiente de los datos de otras cámaras de la red.
Alternativamente, se puede decir que mientras que la mayoría de los sensores miden algún
valor tal como la temperatura o la presión, sensores visuales miden patrones visuales. En
vista de ello, la comunicación en redes de sensores visuales difiere sustancialmente de las
redes de sensores tradicionales.
1.2. Problema de Referencia
Desde hace décadas, las cámaras inteligentes han llevado a cabo la adquisición de la imagen
y la compresión localmente, consiguiendo una representación compacta de la imagen
capturada, que luego era analizada remotamente.
8
Tal paradigma no puede ser adecuado para la red inalámbrica de sensores, donde la entrega
de forma remota de una imagen comprimida o incluso una secuencia de imágenes puede
verse afectada (o ser simplemente imposible), debido a los limitados recursos (ancho de
banda, energía, etc.) que estos poseen.
Disponer de análisis visual en WSN con limitaciones de energía requiere apartarse de las
soluciones tradicionales y buscar un cambio de paradigma que afecte la forma en que los
datos visuales se detectan, procesan y transmiten.
El principio fundamental es que la mayoría de las tareas de análisis visual pueden llevarse a
cabo sobre la base de una representación concisa de la imagen, lo que implica tanto las
características globales y locales, al tiempo que tiene en cuenta la representación subyacente
a nivel de píxeles.
En pocas palabras, el sensor o cámara puede extraer y enviar sólo una representación concisa
de la imagen capturada en lugar de la entrega de la propia imagen completa.
Para esta medida, es imperativo optimizar el cálculo, la codificación y la comunicación de
las características visuales, es decir, las características de la imagen se recogen mediante la
detección en los nodos distribuidos, se procesan y luego se entregan a uno o más destinos
finales con el fin de permitir las tareas de análisis visual de alto nivel, ya sea mediante
detectores o clasificadores centralizados o distribuidos.
En la siguiente figura se muestra como se intenta cubrir una zona con redes visuales de
sensores. Cada uno de esos nodos se ocupará de estas tareas de optimización y reenvío.
Ilustración 4: Cobertura y gestión de eventos en VSN
9
Todas estas medidas están sujetas a ajustados requisitos dependientes de la aplicación
(garantías de ancho de banda o retraso); medidas que pueden verse afectadas por las
condiciones de la red, la comunicación y las limitaciones de hardware.
Tal cambio de paradigma en las funcionalidades de codificación y procesamiento requiere
algoritmos y protocolos de red mejorados e innovadores.
Los principales retos de investigación y consiguientes esfuerzos en el diseño de redes
inalámbricas de sensores multimedia se podrían resumir en los siguientes:
Todas las capas de la pila de comunicación necesitan ser re-adaptados ya que la
mayoría de los algoritmos existentes y protocolos originalmente desarrollados para
redes inalámbricas no son apropiados para soportar comunicación de datos
multimedia.
Enfoques de diseño de capas cruzadas se prefieren para minimizar la latencia, así que
garanticen la Calidad de Experiencia (o QoE, de Quality of Experience) específica
para la aplicación, y permitan reducir los gastos generales del protocolo (datos del
protocolo con respecto a la carga útil)
En el área de procesamiento de señal, técnicas de codificación de información
multimedia necesitan ser eficientemente aplicadas para lograr alta resolución de
codificación y solidez.
Se prefieren implementaciones en hardware comercial, para comprobar eficazmente
el rendimiento de las técnicas propuestas a través de estos experimentos.
Sin embargo, estos esfuerzos no han logrado aún los resultados esperados, principalmente
por el desajuste entre oferta (prestaciones del nodo sensor) y demanda (requisitos complejos
de codificación) de los recursos computacionales. De hecho, los sistemas convencionales de
comunicación visual sólo logran una eficiencia de codificación significativa a costa de una
alta complejidad computacional, especialmente en el lado del codificador (trasmisor).
10
En consecuencia, los requisitos de WSN en términos de complejidad de los nodos (muy baja)
y ancho de banda de transmisión (tan bajo como sea posible teniendo amplia cobertura y
larga autonomía/duración de batería) son muy difíciles de conseguir con hardware limitado
en recursos. Recientes estudios en [7] y [8], han demostrado que los requisitos propuestos
para WSN móviles no pueden ser eficientemente satisfechos por la comprensión de video
tradicional seguidos por el paradigma de análisis visual, incluso siendo tratados de manera
distribuida.
Por el contrario, un conjunto de aplicaciones de análisis visual puede, de manera eficiente,
ser llevada a cabo basada en una representación sucinta de la imagen, la cual se despreocupa
de la representación a nivel de pixel, capturando en cambio sólo propiedades locales y
globales de las imágenes, que serán descritas de manera más detallada en el siguiente
capítulo de esta memoria.
1.3. Ambiente de referencia
Como se ha comentado previamente, este Proyecto se ha realizado bajo la supervisión de un
profesor auxiliar del departamento de electrónica e información del Politécnico de Milán
(véase Anexo 1) durante el transcurso de una beca Erasmus en dicha universidad.
La parte práctica del mismo se ha llevado a cabo en los laboratorios de investigación AntLab
adjuntos a dicho Politécnico.
Este Laboratorio, fundado gracias a contribuciones de empresas de la industria y a becas del
gobierno italiano y de la comunidad europea, se encarga de proyectos de investigación en el
área de la redes de comunicaciones, siendo los temas principales actualmente los siguientes:
Internet inalámbrico (Wireless Internet)
Internet de las cosas (Internet of Things)
Internet de la energía (Internet of Energy)
11
Wireless Internet e Internet of Things son los términos que hacen referencia a la
identificación de objetos, dispositivos o “cosas” y a la comunicación entre ellos y a la vez
posibilitando su acceso remoto y control desde Internet.
Internet of Energy, por su parte, se refiere a la idea de conseguir estos propósitos de la
manera más optimizada en términos de recursos físicos, véase tiempo, coste, memoria, y por
supuesto energía.
Por lo tanto este Proyecto se ha llevado a cabo para ayudar en la línea de investigación que
este laboratorio está realizando intentando englobar lo fundamental de cada una de estas tres
áreas.
1.4. Contribuciones
Teniendo muy en cuenta este paradigma, el objetivo de este Proyecto es el estudio y diseño
de soluciones factibles haciendo uso de la extracción de propiedades en redes visuales
inalámbricas de sensores. En particular, el trabajo práctico describe, como ya se ha
comentado, la implementación de una red de dispositivos en la cual cualquiera de ellos
puede actuar como sensor tomando muestras de su entorno, nodo de reenvío para conseguir
más radio de cobertura o nodo central para procesar los resultados.
Luego podemos resumir las contribuciones prácticas de este Proyecto en las siguientes:
Diseño de la extracción de características eficaces, algoritmos para codificación en
cámaras de sensores.
Cálculo de tiempos de detección y extracción de propiedades, como procesos
diferentes, de imágenes precargadas en los micro-controladores.
Realización de red multi-hop con un número variable de nodos de reenvío y, por lo
tanto, de diferentes modelos de red. Diseño de los protocolos de coordinación u
orquestación. Aprovechando estos modelos, obtención de tiempo de envío de los
12
descriptores obtenidos de las imágenes previamente.
• Explicación para una posible implementación de reconocimiento de objetos en el
nodo central.
1.5. Aplicaciones
La posibilidad de implementar dispositivos de bajo coste y elevada duración sin
mantenimiento capaces de obtener información del entorno y reenviarla de forma
inalámbrica a un centro de coordinación ofrece posibilidades inimaginables en multitud de
aplicaciones.
Las WSN están siendo aplicadas con éxito a sistemas de automoción, aplicaciones
industriales, aviónica, entornos inteligentes, identificación de productos, domótica y
seguridad, control de consumo energético, estudio de invernaderos, monitorización del
medio ambiente, y un sinfín de nuevas aplicaciones, desarrolladas más amplia y
ordenadamente en el siguiente esquema:
Aplicaciones militares: Sistemas C4ISRT (Command, control, communications,
computing, intelligence, surveillance, reconnaissance and targeting), tareas de
reconocimiento y sistemas de alerta rápida.
Aplicaciones medioambientales: Monitorización de hábitat, detección de
inundaciones, incendios, etc.
Edificios: Sistemas de climatización más eficientes, localización de personas u
objetos, aplicaciones domóticas y de seguridad, etc.
Sistemas de emergencia.
Ciencias de la salud: Seguimiento y monitorización de las constantes biomédicas.
Hogar: Alarmas técnicas y de seguridad (inundación, gas, incendio, intrusión),
13
aplicaciones domóticas, etc.
Exploración científica: Entornos lugares inaccesibles o peligrosos (simas oceánicas,
volcanes, etc.).
En la siguiente figura se dibujan algunas de las aplicaciones cotidianas de las WSN:
Ilustración 5: Aplicaciones de las WSN
Mientras que en el siguiente esquema se muestra la planificación de señalización en una
carretera por desprendimiento de rocas o por aparición de animales:
14
Ilustración 6: Aplicación de las WNS en una carretera
Las redes de sensores visuales son más útiles en aplicaciones que implican la vigilancia del
área, el seguimiento y la vigilancia ambiental. De particular uso en aplicaciones de vigilancia
es la habilidad de realizar una reconstrucción en 3D de una escena amplia y almacenar datos
durante un período de tiempo, de modo que los operadores puedan ver los eventos a medida
que ocurren durante cualquier período de tiempo (incluyendo el momento actual) desde
cualquier punto de vista arbitrario de la superficie cubierta. Esto les permite incluso "viajar”
hacia la escena en tiempo real.
Igualmente, el análisis de alto nivel utilizando técnicas como el reconocimiento de objetos
posibilita el seguimiento inteligente de móviles (como personas o vehículos) a través de una
escena, e incluso determinar lo que están haciendo para que ciertas actividades puedan ser
llevadas a cabo automáticamente llamando la atención del operador.
Otra posibilidad es el uso de redes de sensores visuales en las telecomunicaciones, en los que
la red sería utilizada para seleccionar automáticamente la "mejor" vista (tal vez incluso una
generada arbitrariamente) de un evento en vivo.
Con la intención de proveer más ejemplos y referencias finales, en [9] los autores describen
la realización de una plataforma de cámaras inteligentes con múltiples procesadores, y
número variable de unidades de procesamiento digitales (DSPs) para procesamiento
multimedia. La arquitectura de referencia se usa para soportar aplicaciones de vigilancia tales
como rastreo de vehículos.
15
SenseEye, descrito en [10], es una red de sensores multimedia en varios niveles que adopta
hardware heterogéneo. Los diferentes niveles de la red sin embargo, comparten la misma
arquitectura, ofreciendo una plataforma de integración acoplada con video sensores
incluyendo CMUCam, Cyclops y cámaras web Logitech. Aplicaciones de detección de
objetos se desarrollan en la plataforma de referencia a través de substracción y aprovechando
la distribución de color de los objetos a ser reconocidos.
Una estructura similar es propuesta en [11], que describe una plataforma visual de sensores
para llevar a cabo reconocimiento de personas-objetos. El hardware de referencia es un
Beagleboard, la misma marca de hardware utilizado en este Proyecto, conectado a una
QuickCam Logitech S5500.
El trabajo en [12] presenta un sistema de búsqueda de imágenes distribuidas en una red de
nodos sensores iMote2 equipados con almacenamiento extendido de memoria flash. El
sistema está basado en propiedades locales SIFT [13] que serán explicadas en el segundo
capítulo de esta memoria, las cuales son extremadamente lentas de computar en dicho
software.
El Proyecto llevará a cabo la misma dinámica que estos proyectos con diferencias en
dispositivos hardware o tecnologías software usadas.
1.6. Resto de la memoria
Con este punto concluye el primer capítulo de esta memoria en el que se ha pretendido dar
una introducción del Proyecto y a la vez una base teórica necesaria para el resto.
En el siguiente, el capítulo segundo, se realiza una explicación extensa de los conceptos de
teoría de imágenes, enfocándose en los algoritmos de detección y descripción de propiedades.
El tercero es el capítulo de introducción a la práctica, en el que se describen las tecnologías y
componentes usados en este Proyecto.
En el capítulo cuarto se describen de manera práctica y detallada, las labores de instalación y
configuración, y el proceso necesario para haber obtenido los resultados definitivos.
16
Estos resultados, fundamentalmente tiempos, son mostrados y explicados en el quinto
capítulo para las diferentes configuraciones.
El sexto y último capítulo resume las conclusiones obtenidas en este Proyecto Fin de Carrera.
17
Capítulo 2
Conceptos de teoría de imágenes
En este capítulo se cubren los conceptos que han sido necesarios en cuanto a procesamiento
de imágenes para la realización de este Proyecto.
Dentro de este campo, se detallan las propiedades geométricas de las imágenes, y en
particular, cómo detectarlas y extraerlas para ser usadas en el posterior proceso que tenemos
como referencia.
Una amplia explicación del procedimiento usado en este Proyecto se muestra al final del
capítulo.
2.1. Procesamiento digital de imágenes
Dentro de este subcapítulo se definen primero los conceptos más importantes dentro del
procesamiento digital de imágenes y se terminan explicando en detalle los pasos o etapas de
este método.
2.1.1. Introducción
Una imagen puede ser definida como una función bidimensional, f(x, y), donde x e y son
coordenadas espaciales (planas), y donde la amplitud de la función en cada par de
coordenadas se conoce como intensidad o nivel de grises de la imagen en ese punto. Cuando
x, y, y los valores de intensidad de f son todos cantidades discretas finitas, denotamos a la
18
imagen como una imagen digital.
El campo del “procesamiento digital de imágenes” se refiere al procesamiento de imágenes
digitales por medio de un ordenador, teniendo en cuenta que una imagen digital se compone
de un número finito de elementos, cada uno de los cuales tiene una localización particular y
un valor f (x, y).
Estos elementos son llamados elementos pictóricos, elementos de la imagen, pels o píxeles.
Píxel es el término más ampliamente usado para denotar los elementos de una imagen
digital.
Ilustración 7: Concepto de píxel en una imagen
La visión es el más avanzado de nuestros sentidos, así que no es sorprendente que las
imágenes jueguen el rol más importante en la percepción humana. Sin embargo, a diferencia
de la visión humana, que está limitada a la banda visual del espectro electromagnético (EM),
los equipos de imágenes cubren casi todo el espectro EM, desde el rango de los rayos gamma
hasta las ondas radio.
Estos equipos, en general, operan con imágenes generadas por fuentes que los humanos no
están habituados a asociar con imágenes. Estas incluyen ultrasonido, microscopio de
electrones, e imágenes generadas por computador. Por lo tanto, procesamiento digital de
imágenes abarca un amplio y variado campo de aplicaciones, como ya se ha comentado.
19
Ilustración 8: Espectro EM conforme a la energía por fotón
No hay un acuerdo general entre los autores con respecto a dónde termina el procesamiento
de imágenes, y dónde inician otras áreas relacionadas tales como análisis de imágenes y
visión por computador. A veces se hace una distinción mediante la definición de
procesamiento de imágenes como una disciplina en la que tanto la entrada y la salida de un
proceso son imágenes. Pero esto puede ser tomado como una limitación y por una frontera
un tanto artificial. Por ejemplo, bajo esta definición, incluso la tarea trivial de computar la
intensidad media de una imagen (la cual produce un solo número) no sería considerada una
operación de procesamiento de imágenes.
Por otra parte, hay campos tales como la visión por computador, definido más en detalle
posteriormente, cuyo principal objetivo es usar ordenadores para emular la visión humana,
incluyendo un cierto aprendizaje y siendo capaces de crear inferencias y tomar acciones
basados en entradas visuales. Esta área es, por sí misma, una rama de la inteligencia artificial
(AI) cuyo objetivo es emular la inteligencia humana.
El campo de AI se encuentra todavía en sus primeras etapas de desarrollo, con progresos
yendo mucho más lentos de lo originalmente anticipado. El área del análisis (también
llamado comprensión) de imágenes está entre el procesamiento de imágenes y la visión por
computador. No hay límites bien definidos en la línea continua que une al procesamiento de
imágenes en un extremo hasta la visión artificial en el otro. Sin embargo, un paradigma útil
es tener en cuenta tres tipos de procesos informáticos en esta línea: bajos, medios, y procesos
de alto nivel.
Procesos de bajo nivel implican operaciones primitivas como pre-procesamiento de
imagen para reducir el ruido, mejora del contraste y la nitidez de imagen. Un proceso
de bajo nivel se caracteriza por el hecho de que tanto sus entradas como sus salidas
20
son imágenes.
Procesos de nivel medio en imágenes implican tareas como la segmentación
(partición de una imagen en regiones u objetos), la descripción de los objetos para
reducirlos a un formato adecuado para el tratamiento informático, y la clasificación
(reconocimiento) de los objetos individuales.
Un proceso de nivel medio se caracteriza por el hecho de que sus entradas son
generalmente imágenes, pero sus salidas son atributos extraídos de las imágenes (por
ejemplo, bordes, contornos, y la identidad de los objetos individuales).
Por último, el procesamiento de alto nivel implica "dar sentido" a un conjunto de
objetos reconocidos en el análisis de imágenes; y, en el otro extremo del espectro, la
realización de las funciones cognitivas que normalmente se asocian con la visión.
Con base en los comentarios anteriores, vemos que el lugar lógico de coincidencia entre el
procesamiento de imágenes y análisis de imágenes es el área de reconocimiento de las
distintas regiones u objetos en una imagen. Por lo tanto, lo que tomamos finalmente como
procesamiento de imágenes digitales serían los procesos cuyas entradas y salidas son
imágenes y, además, abarcan procesos que extraen los atributos de las imágenes, hasta
incluir el reconocimiento de objetos individuales.
A modo de ejemplo para aclarar estos conceptos, se considera el área de análisis
automatizado de texto. Los procesos de adquisición de la zona que contiene el texto, el
procesamiento previo de esa imagen, la extracción (o la segmentación) de los caracteres
individuales, la descripción de los caracteres en la forma adecuada para el tratamiento
informático, y el reconocimiento de los caracteres individuales están en el rango de lo que
estamos definiendo como procesamiento digital de imágenes.
21
Ilustración 9: Ejemplo de reconocimiento de números en una imagen
El dar sentido a los contenidos de la página se puede categorizar en el dominio de análisis de
imagen e incluso en el de la visión por ordenador, dependiendo del nivel de complejidad que
implique la declaración de "dar sentido".
Tal como ya se ha hecho evidente, el procesamiento de imágenes digitales, como lo hemos
definido, es utilizado con éxito en una amplia gama de áreas de valor social y económico
excepcional.
2.1.2. Pasos fundamentales
Es útil para continuar con la descripción del Proyecto, tener en cuenta el esquema en la
siguiente ilustración. El diagrama no implica que cada proceso esté aplicado a una imagen.
Más bien, la intención es transmitir una idea de todas las metodologías que se pueden aplicar
a las imágenes para diferentes propósitos y, posiblemente, con diferentes objetivos.
22
Ilustración 10: Pasos en el procesamiento de imágenes
La adquisición de la imagen.- Es el primer proceso, que puede ser tan simple como tener
una imagen que está ya en formato digital. Generalmente, la etapa de la adquisición de la
imagen envuelve el pre-procesamiento, como por ejemplo el escalado.
Mejora o realce de la imagen.- Es el proceso de manipulación de una imagen de manera que
el resultado es más conveniente que el original para una aplicación específica. La palabra
específica es importante aquí, ya que establece en primer lugar que las técnicas de mejora
están orientadas al problema. Así, por ejemplo, un método que es muy útil para mejorar las
imágenes de rayos X puede no ser el mejor enfoque para mejorar las imágenes tomadas por
un satélite en la banda de los infrarrojos del espectro electromagnético. No hay “teoría”
general de mejora de imágenes.
Cuando una imagen es procesada para interpretación visual, el espectador es el último juez
de cómo un método en particular funciona. Las técnicas de mejora son tan variadas, y usan
planteamientos tan diversos, que es difícil reunir un grupo significativo de técnicas
adecuadas para la mejora de imágenes en un capítulo sin un desarrollo extenso de fondo.
La restauración de imágenes.- Es un área que también se encarga de mejorar la apariencia
de una imagen. Sin embargo, a diferencia de la mejora o el realce mencionado anteriormente,
23
que es subjetivo, la restauración de imágenes es un proceso objetivo, en el sentido de que las
técnicas de restauración tienden a basarse en modelos matemáticos o probabilísticos de
degradación de la imagen. La mejora, por el contrario, se basa en las preferencias subjetivas
humanas sobre lo que constituye un "buen" resultado de realce.
Procesamiento de colores en imágenes.- Es un área que ha ido ganando en importancia
debido al aumento significativo del uso de imágenes digitales a través de Internet. El color se
utiliza también como base para la extracción de características de interés en una imagen y
será explicado con más detalle en este capítulo.
Ilustración 11: Ejemplo de realce de color en una foto
Las ondículas o wavelets.- Son la base para la representación de imágenes en distintos
grados de resolución, como pueda ser por ejemplo, para la compresión de datos de imagen o
para la representación piramidal, en la que las imágenes se subdividen sucesivamente en
regiones más pequeñas.
La compresión.- Como el nombre implica, se refiere a técnicas para reducir el
almacenamiento requerido para guardar una imagen, o el ancho de banda requerido para
transmitirla. Aunque la tecnología de almacenamiento ha mejorado significativamente en la
24
última década, lo mismo no puede decirse de la capacidad de transmisión. Esto es
particularmente cierto sobre todo en el uso de Internet, que se caracteriza por un significativo
contenido pictórico.
La compresión de imágenes es un concepto familiar (tal vez involuntariamente) a la mayoría
de usuarios de ordenadores en forma de extensiones de archivo de imagen, como la
extensión de archivo “jpg” utilizado en el formato JPEG (Joint Photographic Experts Group),
estándar de compresión de imágenes. Este estándar se basa en coger tramos o frames de una
imagen y realizar transformadas discretas de estas, para posteriormente realizar una
cuantización óptima usando una gran escala de valores. Se trata por tanto de un método que
produce pérdidas.
El procesamiento de la forma o morfológico.- Se basa en el uso de herramientas para la
extracción de componentes de la imagen que son útiles en la representación y la descripción
de la forma. En estos conceptos siguientes se comienza a ver ya una transición de los
procesos en los que la salida son imágenes, a aquellos en los que la salida son atributos de las
imágenes, tal como se indica en la sección previa.
Al igual que con descriptores extraídos del color, los descriptores de forma serán explicados
más en detalle en este capítulo.
Los procedimientos de segmentación.- Dividen una imagen en sus fracciones u objetos
constituyentes. Por lo general, la segmentación autónoma es una de las tareas más difíciles
en el procesamiento digital de imágenes.
Un procedimiento robusto de segmentación permite acercar al procesamiento de imágenes
hacia una solución satisfactoria de los problemas que requieren identificación individual de
objetos. En cambio, los algoritmos de segmentación débiles o erráticos casi siempre
garantizan el fracaso eventual. En general, cuanto más precisa es la segmentación, el
reconocimiento es más probable de tener éxito.
La representación y la descripción.- Vienen casi siempre después de la salida de una etapa
de segmentación, que por lo general son datos íntegramente representados por píxeles, y que
constituyen ya sea el límite de una región (es decir, el conjunto de píxeles que separan una
región de otra) o todos los puntos en la región misma. En cualquiera de los casos, es
25
necesaria la conversión de los datos a una forma adecuada para el tratamiento informático.
La primera decisión que debe hacerse es si los datos deben estar representados como un
límite o como una región completa. La representación de fronteras es apropiada cuando la
atención se centra en las características externas de la forma de un objeto, como las esquinas
y las inflexiones. La representación de regiones es apropiada cuando la atención se centra en
las propiedades internas, tales como la textura o la forma del esqueleto del objeto. En algunas
aplicaciones, estas representaciones se complementan entre sí.
La elección de la representación es sólo una parte de la solución para la transformación de
los datos en bruto (píxeles) hacia una forma adecuada para su posterior tratamiento
informático. El método también debe ser especificado en la descripción de los datos para que
se resalten las características de interés.
La descripción, o también llamada selección de propiedades.- Se ocupa de la extracción de
atributos que resultan de alguna información cuantitativa de interés o que son básicos para la
diferenciación de una clase de objetos con respecto a otro. La descripción es otro concepto
clave en este estudio.
El reconocimiento.- Es el proceso que asigna una etiqueta (por ejemplo, "vehículo") a un
objeto en función de sus descriptores.
Hasta ahora no se ha dicho nada acerca de la necesidad de un conocimiento previo o sobre la
interacción entre el conocimiento base o knowledge base y los módulos de procesamiento
que se muestran en la ilustración 10.
En un sistema de procesamiento de imágenes, el conocimiento acerca del dominio del
problema está codificado en forma de una base de datos. Este conocimiento puede ser tan
simple como tener regiones detallando dónde es más probable que esté la información
importante de una imagen, para luego limitar de este modo la búsqueda que tiene que ser
realizada para encontrar la información útil.
El conocimiento base también puede ser bastante complejo, como una lista interrelacionada
de todos los defectos posibles en un problema de inspección de materiales o una base de
datos de imágenes de alta calidad de una región tomadas por satélite, para aprovecharlas en
26
aplicaciones de detección de cambios del terreno. Además de guiar el funcionamiento de
cada módulo de procesamiento, el conocimiento base también controla la interacción entre
los módulos.
Esta distinción se hace en la ilustración 10 por el uso de las flechas de doble sentido entre los
módulos de procesamiento y conocimiento base, a diferencia de las flechas simples que
enlazan los módulos de procesamiento.
Aunque no se está hablando de visualización de la imagen de forma explícita en este punto,
es importante tener en cuenta que la visualización de los resultados del procesamiento de
imágenes se puede dar en la salida de cualquier fase en la ilustración número 10. También
observamos que no todas las aplicaciones de procesamiento de imágenes requieren la
complejidad de las interacciones que se muestran en esta ilustración. De hecho, no se
necesitan ni siquiera todos los módulos en muchos casos. Por ejemplo, la mejora de la
imagen para la interpretación visual humana rara vez requiere el uso de cualquiera de las
otras etapas en la figura.
Por lo general, sin embargo, a la vez que la complejidad de las tareas de procesamiento de
imágenes aumenta, también lo hace el número de procesos necesarios para resolver el
problema.
2.2. Análisis visual por computador
Como ya se ha comentado en la sección previa, dentro del procesamiento digital de señales
cobra especial interés la visión por computador, que se aprovecha de éste para realizar las
operaciones necesarias dentro del análisis visual.
Luego, sabiendo esto, se podría definir la visión por computador, o también conocida
como visión artificial, como un sub-campo de la inteligencia artificial cuyo objetivo es
programar un computador para que "entienda" una escena o las características de una imagen.
En la siguiente figura se encuentran las áreas, desarrolladas a continuación, en las que se
centra el análisis visual por ordenador:
27
Ilustración 12: Relaciones entre visión por computador y otras áreas afines
Los objetivos típicos de la visión artificial incluyen:
La detección, segmentación, localización y reconocimiento de ciertos objetos en
imágenes (por ejemplo, caras humanas).
La evaluación de los resultados.
El registro de diferentes imágenes de una misma escena u objeto, es decir, hacer
concordar un mismo objeto en diversas imágenes.
El seguimiento de un objeto en una secuencia de imágenes.
El mapeo de una escena para generar un modelo tridimensional de la escena; este
modelo podría ser usado por un robot para navegar por la escena.
La estimación de las posturas tridimensionales de humanos.
La búsqueda de imágenes digitales por su contenido.
28
Ilustración 13: Seguimiento de jugadores en un partido
El procesamiento de las imágenes que obtenemos será un paso vital en este Proyecto dado
que permitirá realizar la fase de optimización de envío una vez cosechada la imagen y
cargada internamente en el dispositivo.
2.3. Descriptores visuales de imágenes
Como resultado de las nuevas tecnologías de la comunicación, el uso masivo de Internet y
con ello, el aumento masivo de la cantidad de información audiovisual en formato digital, ha
sido necesario diseñar unos sistemas que permitan describir el contenido de los diversos
tipos de información multimedia con el fin de buscarlos y clasificarlos.
Dentro de la visión por computador, los descriptores visuales o descriptores de imágenes son
descripciones de las propiedades visuales de los contenidos de imágenes o vídeos. También
podemos definirlos como los algoritmos o aplicaciones que producen este tipo de
descripciones. Su función principal es por lo tanto describir características elementales tales
como la forma, el color, la textura o el movimiento, entre otros.
Los descriptores audiovisuales están a cargo de la descripción del contenido. Estos
descriptores tienen un buen conocimiento de los objetos y eventos que se encuentran en un
vídeo, imagen o grabación audio y permiten las búsquedas rápidas y eficientes de los
contenidos audiovisuales.
29
Este sistema puede ser comparado con los motores de búsqueda de contenidos textuales. Si
bien es cierto que es relativamente fácil encontrar texto con un ordenador, es mucho más
difícil encontrar partes concretas de audio y vídeo. Por ejemplo, buscar una escena de una
persona feliz. La felicidad es un sentimiento y su descripción en cuanto a forma, color y
textura en imágenes no es para nada evidente.
Ilustración 14: Reconocimiento de expresión facial
La descripción del contenido audiovisual no es una tarea superficial y es esencial para el uso
eficaz de este tipo de archivos. El sistema de normalización que se ocupa de los descriptores
de audiovisuales es el MPEG-7 (Motion Picture Expert Group - 7).
Los descriptores son el primer paso para descubrir la conexión entre los píxeles contenidos
en una imagen digital, y lo que los humanos recuerdan después de haber observado una
imagen o grupo de imágenes durante algunos minutos.
Podemos dividir los descriptores visuales en dos grupos principales según la información en
la que se centran: descriptores de información general o específica en un dominio.
2.3.1. Descriptores de información general
Contienen descriptores de bajo nivel que dan una descripción acerca del color, la forma, las
30
regiones, las texturas y el movimiento. Esta descripción se genera de forma automática
mediante el procesamiento de la señal.
En este conjunto podemos destacar los siguientes:
Color: la cualidad más básica del contenido visual. Se definen cinco herramientas
para describir el color. Las tres primeras herramientas representan la distribución del
color y los últimos describen la relación de color entre secuencias o grupo de
imágenes:
- Descriptor del Color Dominante (DCD): da una descripción de los colores
representativos de una imagen o región. Aunque puede ser aplicado sobre una
imagen completa, su utilidad se reserva más para la representación de
características locales (regiones u objetos), donde un menor número de colores
son suficientes para caracterizar la región.
- Descriptor del Color Escalable (SCD): deriva del histograma y puede
proporcionar características globales del color cuando se mide en una imagen
completa. Representa los colores presentes en la imagen mediante un
Histograma de Color HSV codificado mediante una transformación Haar.
El concepto de escalabilidad se encuentra representado en la elección variable
del número de intervalos o bins en los que se calcula el histograma.
31
Ilustración 15: Descriptores visuales del estándar MPEG-7
- Descriptor de la Estructura del Color (CSD): captura algunas características
espaciales de la distribución del color en una imagen.
- Descriptor del Diseño del Color (CLD): representación muy compacta e
invariante a la resolución del color para la recuperación de imágenes de alta
velocidad de recuperación. Representa la distribución espacial de los colores de
la imagen en el dominio frecuencial. Del mismo modo, este descriptor puede
ser aplicado sobre una imagen completa o sobre regiones de interés. Presenta
escalabilidad en cuanto al número de coeficientes seleccionados para la causa,
si bien la recomendación apunta a 18 coeficientes de un total de 64.
- Grupo de Tramas (GoF) o Grupo de Imágenes (GoP): extensión del color
escalable que define una estructura para representar propiedades del color de
una colección de tramas similares. El histograma final representativo del grupo
de imágenes puede ser calculado mediante la media, mediana o intersección de
los histogramas individuales.
Textura: es también una cualidad importante a la hora de describir una imagen.
32
Estos descriptores caracterizan la textura de una imagen o de regiones de ésta. Se
basan en la homogeneidad de las regiones y en los histogramas de las fronteras de las
regiones.
Este set de descriptores está formado por:
- Descriptor Homogéneo de la Textura (HTD): Este descriptor extrae la
textura presente en la imagen mediante la aplicación de diferentes filtros de
Gabor sobre diferentes escalas y orientaciones quedándose con el 1º y 2º
momento de la energía en el dominio frecuencial. Como resultado se obtiene
una matriz de 62 valores codificados con 8 bits cada uno.
- Descriptor de la Visualización de la Textura (TBD): Al igual que el anterior,
este descriptor hace uso de filtros de Gabor, salvo que ahora solo se
seleccionan las 2 orientaciones dominantes de la imagen que son codificadas
con 3 bits cada una. Al mismo tiempo se determina la regularidad (2 bits) y la
aspereza (4 bits) sobre las orientaciones dominantes. Con todo ello se construye
un vector de 12 bits, si bien este descriptor resulta más adecuado para su
aplicación sobre regiones que sobre la imagen completa.
- Descriptor del Histograma de Bordes (EHD): Representa la distribución
espacial de 5 tipos de bordes, 4 de ellos direccionales y el otro sin dirección,
presentes en la imagen.
Forma: contiene información importante sobre la semántica debido a la capacidad
humana de reconocer objetos a través de su forma. Sin embargo, esta información
sólo se puede extraer por medio de una segmentación similar a la que el sistema
visual humano implementa. Hoy en día, un sistema de tal segmentación no es posible,
sin embargo existen una serie de algoritmos considerados por ser una muy buena
aproximación. Estos descriptores describen las regiones, contornos y formas para
imágenes en 2D y volúmenes en 3D.
Los descriptores de forma son las siguientes:
33
- Descriptor de forma basado en regiones (RSD): Este descriptor representa la
forma de cualquier región de un objeto dentro de una imagen, ya sean regiones
simples, como conectadas o con agujeros.
- Descriptor de forma basado en contornos (CSD): Representa el contorno
cerrado de una región o un objeto 2D presente en una imagen o en una
secuencia de vídeo.
- Descriptor de forma en 3D (3D SD): Descripción de contornos 3D.
Movimiento: definido por cuatro descriptores diferentes que describen el
movimiento en una secuencia de vídeo. Relacionados con el movimiento de los
objetos y de la cámara en la secuencia. Esta última información es proporcionada por
el dispositivo de captura, mientras que el resto se implementa por medio de
procesamiento de imágenes.
El conjunto de descriptores es el siguiente:
- Descriptor del Movimiento de la Actividad (MAD): Este descriptor recoge
la intensidad de la acción o el ritmo de movimiento presente en una secuencia.
- Descriptor del Movimiento de la Cámara (CMD): Este descriptor recoge el
valor de los parámetros de los diferentes movimientos de una cámara (zoom,
tilt, pan, etc) presentes en un bloque de imágenes. Cada bloque está
representado por un grupo de frames que comparten un posible movimiento de
cámara.
- Descriptor de la Trayectoria del Movimiento (MTD): Caracteriza el
movimiento de un punto o región en la imagen en el dominio espacio-temporal.
- Descriptor del Movimiento Deformado y Paramétrico (WMD y PMD):
Permite caracterizar el movimiento de una región en la imagen, basándose en el
análisis de una transformación geométrica de la evolución espacio-temporal de
la región. Esta transformación se descompone en diferentes transformaciones
afines como translaciones, rotaciones, zoomings, etc.
34
Ubicación: se utiliza para describir elementos en el dominio espacial. Además, los
elementos también pueden estar ubicados en el dominio temporal.
Podemos encontrar estos dos descriptores:
- Descriptor de Localización de Región (RLD): Permite la localización de
regiones dentro de las imágenes especificadas mediante la representación de un
polígono.
- Descriptor de Localización Espaciotemporal (STLD): Parecido al anterior
salvo que en este caso, la localización de las imágenes se extiende al dominio
temporal también.
2.3.2. Descriptores de información específica
Estos descriptores, que dan información sobre los objetos y acontecimientos en la escena, no
son fácilmente extraíbles, y más aún cuando la extracción se realiza de forma automática. Sin
embargo, pueden ser procesados manualmente.
El reconocimiento de rostros es un ejemplo concreto de la aplicación que intenta obtener esta
información automáticamente.
Como elementos u objetos interesantes y específicos en imágenes, se pueden tomar los
siguientes:
Bordes: son puntos en los que hay un límite (o un borde) entre dos regiones de
imagen. En general, un borde puede ser de forma casi arbitraria, y puede incluir
uniones. En la práctica, los bordes se definen generalmente como conjuntos de
puntos en la imagen que tienen una fuerte magnitud del gradiente.
Aprovechándose de esto, algunos algoritmos comunes encadenan entre sí puntos de
elevado gradiente para automatizar y optimizar la búsqueda de bordes. Estos
algoritmos suelen colocar algunas restricciones a las propiedades de los bordes, tales
35
como la forma, la suavidad, y este valor del gradiente.
Localmente, los bordes tienen una estructura unidimensional.
Esquinas/ puntos de interés: Los términos de las esquinas o córner y los puntos de
interés son empleados como sinónimos y se refieren a las características puntuales en
una imagen.
El nombre de "Córner" surgió ya que los primeros algoritmos en este campo ya
realizaban detección de bordes, y luego analizaban estos bordes para encontrar los
cambios rápidos en la dirección (esquinas).
Estos algoritmos se desarrollaron a continuación, de manera que la detección de
bordes explícita ya no se requiere, por ejemplo mediante la búsqueda de altos niveles
de curvatura en el gradiente de la imagen. Fue entonces cuando se dieron cuenta de
que las llamadas esquinas también se habían detectado en partes de las imágenes que
no eran esquinas en el sentido tradicional (por ejemplo un pequeño punto brillante
sobre un fondo oscuro).
Estos puntos se conocen con frecuencia como puntos de interés, pero el término
"córner" es utilizado por la tradición.
Manchas/ regiones de interés (borrón): Las manchas, borrones, o blobs en la
literatura inglesa, proporcionan una descripción complementaria de las estructuras de
la imagen en función de las regiones, en lugar de las esquinas vistas previamente,
cuya información es un punto. Sin embargo, los descriptores de tipo mancha suelen
contener un punto preferido (un máximo local o de un centro de gravedad) lo que
significa que muchos detectores de este tipo también pueden ser considerados como
operadores de puntos de interés. Pueden detectar áreas de una imagen que son
demasiado suaves para ser detectados por un detector de esquinas.
Si consideramos una imagen reducida y luego aplicamos detección de esquinas, el
detector encontrará puntos muy marcados y distintivos en la imagen encogida, pero
que serían suaves en la imagen original. Es en este punto en el que la diferencia entre
un detector de esquinas y un detector de manchas se vuelve un tanto imprecisa. Pero
36
en igual medida, esta distinción se puede remediar mediante la inclusión de una
noción adecuada de escala.
Curvas o Ridges: para los objetos alargados, el concepto de crestas, curvas o ridges
es una herramienta fundamental. Un descriptor de crestas calculado a partir de una
imagen de nivel de grises puede ser visto como una generalización del eje medio.
Desde un punto de vista práctico, una cresta puede estar pensada como una curva
unidimensional que representa un eje de simetría, y que además tiene un atributo de
la anchura local asociada con cada punto de esa cresta.
Desafortunadamente, sin embargo, es algorítmicamente más difícil extraer
características de crestas en imágenes de nivel de grises que bordes, esquinas o
manchas. Sin embargo, los descriptores de crestas se utilizan con frecuencia para la
detección de carreteras en imágenes aéreas y para la detección de vasos sanguíneos
en imágenes médicas.
En la siguiente figura podemos ver un ejemplo de eje de simetría (a la izquierda) y de
detección de bordes, en verde, y de crestas, en rojo (a la derecha).
Ilustración 16: Detección de Bordes y Crestas
37
Explicar en detalle los métodos de detección de estas propiedades podría llevar otro capítulo
y no es objeto de este Proyecto.
Aun así, por dar algunos nombres y su uso, podemos fijarnos en la siguiente tabla:
Método de detección Borde Córner Mancha
Canny X
Sobel X
Harris & Stephens / Plessey X X
SUSAN X X
Shi & Tomasi X
Level curve curvature X
FAST X X
Laplacian of Gaussian X X
Difference of Gaussians X X
Determinant of Hessian X X
MSER X
PCBR X
Grey-level blobs X
Tabla 1: Métodos de detección de propiedades y usos
2.4. Métodos basados en propiedades y puntos de interés
En este subcapítulo se explican los métodos o algoritmos de detección y extracción de
propiedades centrados en puntos clave de la escena. Dentro de ellos, se detalla el método
usado para este Proyecto.
2.4.1. Visión general
Para cualquier objeto dentro de una imagen, los puntos interesantes, claves o “keypoints” de
38
éste pueden ser obtenidos para proporcionar una "descripción de las propiedades" del objeto.
Esta descripción, extraída a partir de una imagen origen, se puede utilizar a continuación
para identificar un objeto específico en una imagen de prueba que contiene muchos otros
objetos en ella.
Para llevar a cabo el reconocimiento fiable, es importante que las características extraídas de
la imagen de origen sean detectables incluso en los cambios en escala de la imagen, el ruido
y la iluminación. Generalmente dichos puntos se encuentran en regiones de alto contraste de
la imagen, tales como los bordes del objeto como ya hemos descrito anteriormente.
Normalmente las imágenes de prueba se tienen almacenadas en una base de datos como
imágenes de referencia, y tras la comparación de descriptores entre imagen origen e imagen
de referencia, se genera una lista ordenada de resultados.
Otra característica importante de los puntos clave es que las posiciones relativas entre ellos
en la escena original no deben cambiar de una imagen a otra. Por ejemplo, si sólo se utilizan
las cuatro esquinas de una puerta como características, éstas deberían valer
independientemente de la posición de la puerta; pero si también se utilizaron puntos del
marco, el reconocimiento fallaría si la puerta está abierta o cerrada.
Del mismo modo, los puntos ubicados en objetos articulados o flexibles típicamente no
funcionan si hay cualquier cambio en la geometría interna de las dos imágenes en el conjunto
que se está comparando. Sin embargo, en la práctica, el método SIFT detecta y utiliza un
número mucho mayor de puntos en las imágenes, lo que reduce el promedio de los errores de
emparejamiento causado por estas variaciones locales.
Se han propuesto en la literatura un gran número de algoritmos de detectores y descriptores.
A partir de los primeros trabajos en la década de los 80 [24], se ha realizado un gran esfuerzo
en producir detectores que sean sensibles a esquinas, bordes, manchas o uniones en “T”, a la
vez que deben también ser invariantes a diferentes condiciones de visión.
Mucha investigación se ha llevado a cabo también con el fin de estudiar y desarrollar estos
descriptores robustos, lo que resulta en sistemas que son invariantes a los cambios en la
escala, la rotación y la iluminación.
El descriptor que se toma por referencia, ampliamente aceptado por su uso, es el previamente
39
comentado “Scale Invariant Feature Transform” (o SIFT) que combina un detector DoG
(Difference of Gaussians) con un descriptor 128-dimensional obtenido analizando
histogramas para la orientación con 8 bins cada uno, teniendo en cuenta una matriz de 4x4
píxeles alrededor de cada punto clave.
SIFT puede identificar los objetos con bastante certeza, incluso entre objetos confusos y que
se encuentran bajo obstrucción parcial. Esto es debido a que la descripción del carácter SIFT
es invariante a escala uniforme, a orientación, y en parte invariante a distorsión afín y a
cambios en la iluminación.
Ilustración 17: Ejemplo de descriptor SIFT
Otro tipo de características muy atractivas y muy usadas desde hace algunos años son las de
tipo SURF (Speeded-Up Robust Features), que han demostrado ser significativamente más
rápidas que SIFT.
La detección SURF utiliza el determinante de la matriz de Hesse (detector de regiones o
manchas), mientras que la descripción se realiza mediante la suma de las respuestas de
wavelets de Haar en la región de interés. Aunque demuestran tiempos impresionantes con
respecto a la tecnología de referencia, SURF está todavía, en términos de velocidad, varios
órdenes de magnitud más alejado de la más rápida, limitada por propiedades de calidad
actualmente disponibles.
En cuanto a los detectores y los descriptores, en los últimos años se ha prestado mucha
40
atención a los algoritmos de respuesta rápida diseñados para arquitecturas de bajo consumo.
Haciendo referencia a estos últimos, los descriptores binarios como BRIEF (Binary Robust
Independent Elementary Features) se han propuesto recientemente con el fin de aumentar la
velocidad de cálculo y de reducir el tiempo a la hora de encontrar coincidencias, produciendo
al mismo tiempo una representación más compacta.
Trabajar con descriptores binarios es ventajoso desde diferentes perspectivas:
En primer lugar, y como más adelante se detallará, se construyen mediante la
concatenación de resultados de comprobaciones binarias en intensidades
suavizadas de píxeles, que son rápidos de calcular.
Como segunda ventaja, ya que cada elemento del descriptor es un bit (por
definición), el tamaño de un descriptor binario es considerablemente más pequeño
que descriptores tradicionales de valores reales.
Como tercer aspecto, la comprobación entre descriptores binarios puede ser
realizada por medio de un cálculo de la distancia de Hamming, la cual puede ser
ejecutada con una simple operación XOR en arquitecturas modernas.
Por todas estas razones, los descriptores binarios son una elección natural en sistemas de
recursos limitados, como ya hemos comentado lo son las redes visuales de sensores.
Luego, por tanto, en este trabajo nos centramos en el algoritmo llamado “Binary Robust
Invariant Scalable Keypoints” (o BRISK), el cual extiende el diseño de BRIEF añadiendo
invariancia a las transformaciones de escala y de rotación. A continuación, se profundiza
más en esta herramienta.
2.4.2. BRISK: El método
En esta sección, se describen las etapas clave para llevar a cabo el algoritmo BRISK, es decir,
la característica de detección, la composición del descriptor y la correspondencia (matching)
41
entre puntos clave para, por ejemplo, reconocimiento de objetos.
Es importante observar que la modularidad del método permite el uso del detector de BRISK
en combinación con cualquier otro descriptor de puntos claves, y viceversa, para optimizar el
rendimiento deseado y la tarea en cuestión.
En primer lugar, la imagen de entrada es procesada para detectar estos keypoints
significativos que corresponden con ubicaciones significativas de la imagen nombrada.
Luego, se codifica la información alrededor de cada punto clave en un descriptor de
propiedades. Y finalmente, los descriptores extraídos de la imagen origen se comparan con
los previamente almacenados en una base de datos de imágenes de referencia.
A. Detector BRISK
El detector BRISK es una versión multi-escala del popular algoritmo FAST (Fast
Accelerated Segment Test), método de detección mencionado en el apartado previo. FAST
representó un claro avance en la detección súper rápida de córners. Clasifica un punto
candidato p (con intensidad Ip) como un córner si n píxeles contiguos en el círculo de
Bresenham de radio 3 son todos más brillantes que Ip+t, o todos más oscuros que Ip-t, con t
como un umbral predefinido.
A cada córner o esquina p se le otorga tras el reconocimiento una puntuación s, definida
como el umbral máximo que sigue clasificando a p como una esquina. Además, los autores
del algoritmo presentan un enfoque de aprendizaje automático para crear árboles de decisión
que permite clasificar un punto candidato con sólo unas pocas pruebas entre píxeles, lo que
acelera la marcha de este proceso de detección. Se indica que el uso de este enfoque requiere,
en promedio, menos de 2,3 pruebas por píxel para determinar si es o no es una característica
importante.
Un ejemplo de la detección BRISK se muestra en las siguientes figuras de una secuencia de
barcos. Entre la primera foto y la segunda de la secuencia se realiza un pequeño zoom y una
rotación en el plano.
42
Ilustración 18: Primer plano de la detección BRISK
El tamaño de los círculos denota la magnitud de los puntos clave detectados mientras que los
radiales denotan su orientación. Para mayor claridad, el umbral de detección se ha ajustado
aquí a un valor más estricto que en la configuración típica, produciendo así una menor
repetición.
B. Descriptor BRISK
Dado un conjunto de puntos clave, el descriptor BRISK se compone de una cadena binaria
formada mediante la concatenación de resultados de comprobaciones simples del brillo o
iluminación. En BRISK, se identifica la dirección característica de cada punto clave para
permitir descriptores de orientación normalizada y por lo tanto lograr invariancia de rotación,
que es clave para tener una mayor robustez general en el método. Además, se seleccionan
cuidadosamente las comparaciones de brillo con el enfoque de maximizar el carácter
descriptivo.
Como inicio del proceso, el descriptor BRISK utiliza un patrón de puntos pi para el muestreo
de los puntos vecinos a cada punto clave.
El patrón, ilustrado en la siguiente figura, define N localizaciones igualmente espaciadas en
círculos concéntricos en el punto clave. Los pequeños círculos azules indican los sitios de
muestreo; los más grandes, los círculos de trazos rojos, están dibujados en un radio
43
correspondiente a la desviación estándar del centro de la gaussiana, utilizada para suavizar
los valores de intensidad en los puntos de muestreo a fin de evitar efectos de aliasing.
Ilustración 19: Patrón de muestreo BRISK con N = 60 puntos
En primer lugar, se obtiene para cada pi puntos del patrón, un valor de intensidad I(pi, )
mediante suavización gaussiana con como desviación estándar, proporcional a la distancia
entre el punto y el centro.
En lo siguiente consideramos (pi, pj) como un par de puntos del patrón de muestreo. De éstos,
siempre habrá un número fijo .
Consideramos el conjunto A de todos los pares de muestras como:
El patrón define dos conjuntos de pares de puntos de muestreo, nombrados como pares de
larga distancia y corta distancia. El conjunto de larga distancia S está compuesto por todos
44
los pares (i, j) de tal manera que y se utilizan para estimar la orientación
del punto clave por medio de un promedio de gradiente local.
Una vez que la orientación es estimada, el patrón de muestreo se adapta girándose en
consecuencia para conseguir un descriptor normalizado a rotación y escala. El conjunto de
pares de corta distancia L (cuya distancia al punto de muestreo es inferior a un umbral )
se utiliza en este caso para construir el descriptor.
Para recuperar eficientemente la ubicación y la información de suavizado de los puntos
patrón, se construye fuera del proceso una tabla de búsqueda de todas las orientaciones
posibles y se almacena en la memoria.
A modo de ejemplo, para 1024 ángulos pre-calculados, el tamaño de la tabla de búsqueda
sería de unos 40 MB.
Para construir el descriptor real, se construye una cadena binaria concatenando el resultado
de todas las comparaciones de pares de puntos de intensidad de corta distancia de tal
manera que cada bit corresponde a:
Donde denota el valor de intensidad suavizada en .
En la implementación estándar de BRISK, está sintonizado para que el descriptor
resultante tenga 512 bits.
45
C. Matching
La coincidencia o matching de dos descriptores BRISK requiere el cálculo de la distancia de
Hamming, que puede ser calculada de manera muy eficiente en arquitecturas de hoy en día
por medio de una operacion XOR bit a bit. Dos descriptores se dice que coinciden si su
distancia de Hamming es menor que un valor umbral predefinido .
Con esto concluye el segundo capítulo de esta memoria, en el que se han pretendido explicar
en profundidad los conceptos teóricos de procesamiento y visión por computador de
imágenes. Se termina haciendo alusión a los métodos de descripción y detección,
profundizando en el método usado en este proyecto.
46
Capítulo 3
Tecnología usada
En este tercer capítulo se define y detalla la tecnología usada en este Proyecto a modo de
“recetario”. Se analiza el porqué de su elección y la comparativa con otras tecnologías
similares. Se da una explicación al lector de todos los mecanismos y dispositivos necesarios
para llevar a cabo este Proyecto, facilitando la comprensión y animando a la recreación y
mejora del mismo.
Se trata por ello de una información importante para poder reproducir con fidelidad los
resultados conseguidos y que se mostrarán en el capítulo 5 de esta memoria.
3.1. Sistemas operativos
Se describen los sistemas operativos empleados en la realización del Proyecto y que son
útiles a la hora de tratar con redes inalámbricas de sensores.
3.1.1. Distribución Linux Ubuntu 12.04 LTS
Ubuntu 12.04 LTS (Precise Pangolin) es la distribución de Linux derivada de Debian y
mantenida por Canonical Ltd.
Esta distribución es usada para la realización de los programas en el entorno de desarrollo, la
configuración de los dispositivos hardware que se utilizan como nodos de la red, la creación
de la red WiFi adhoc para la comunicación y como nodo central controlador y receptor en el
47
proceso de envío de los descriptores.
Se utiliza también la versión mínima de esta distribución en los nodos sensor y de reenvío
para poder lograr compatibilidad con los dongle WiFi utilizados y que serán nombrados más
adelante en esta memoria.
3.1.2. Distribución Linux Ångström
La distribución Ångström es una distribución de Linux enfocada y usada en una gran
variedad de dispositivos integrados. Es el resultado de la unificación de los desarrolladores
de los proyectos OpenZaurus, OpenEmbedded y OpenSIMpad. Es una distribución gratuita y
de código libre con licencia GPL.
Es el sistema que viene por defecto en el dispositivo micro-controlador BeagleBone que se
utiliza para este Proyecto y que se explica más en detalle en este capítulo.
En la siguiente figura podemos ver la pantalla de inicio de Ångström una vez conectado el
BeagleBone a un ordenador con sistema operativo Linux Ubuntu.
Ilustración 20: Pantalla de inicio de Ångström
48
3.1.3. TinyOS
TinyOS es un sistema operativo de código abierto con licencia BSD diseñado para
dispositivos inalámbricos de baja potencia, tales como los utilizados en redes de sensores,
computación ubicua o inteligencia ambiental, redes de área personal y edificios y medidores
inteligentes, entre otros. Está diseñado para incorporar novedades rápidamente y para
funcionar bajo las importantes restricciones de memoria que se dan en las redes de sensores.
Está mantenido por TinyOS Alliance, un consorcio internacional que utiliza, desarrolla y
apoya a este sistema operativo, así como a sus herramientas asociadas, con un promedio de
35.000 descargas al año.
Está escrito en el lenguaje de programación nesC como un conjunto de tareas y procesos que
colaboran entre sí. Las aplicaciones para TinyOS también se escriben en nesC, este dialecto
del lenguaje de programación C optimizado para las limitaciones de memoria de las redes de
sensores.
Existen varias herramientas que completan y facilitan su uso, escritas en su mayoría en Java
y en Bash. Otras herramientas y librerías asociadas están escritas principalmente en C.
Se caracteriza por tener una arquitectura orientada a eventos, lo que permite optimizar el
rendimiento de los nodos de la red. Toda aplicación en NesC está basada en el uso de
componentes, que son bloques de programa que proporcionan unas funcionalidades
determinadas.
Un componente puede ser visto como un bloque funcional que dispone de varias puertas de
entrada/salida. A cada una de estas puertas se la conoce como interfaz.
El sistema operativo TinyOs se instala sobre la estación de trabajo en la que se vaya a
desarrollar el sistema. Se puede también probar sobre diferentes sistemas operativos de
propósito general (Windows, Linux). Sin embargo, su sistema nativo está basado en Linux.
Para instalarlo sobre Windows, sería necesario instalar previamente una interfaz Unix, como
Cygwin. Una vez instalado, se dispondrá de las herramientas necesarias para desarrollar e
implementar una red de sensores.
49
La versión actual, a la hora de redactar esta memoria, es TinyOS 2.1.2, que incluye entre
otras mejoras, soporte completo para el protocolo 6lowpan/RPL IPv6.
TinyOS no se utiliza en la práctica de este Proyecto pero se menciona dado que representa un
buen ejemplo de sistema operativo diseñado y enfocado en dispositivos para redes de
sensores.
3.2. Entorno de desarrollo
Como entorno de desarrollo para la programación en este Proyecto, se ha escogido Eclipse
CTD (C/C++ Development Tooling).
Este entorno de desarrollo de descarga libre permite trabajar fácilmente con C y C++, los
lenguajes de programación utilizados en este Proyecto, usando a la vez las librerías
necesarias para la compilación cruzada.
La correcta instalación y configuración se encuentran explicadas en el siguiente capítulo.
3.2.1. Compilación cruzada
La compilación cruzada, o cross compilation en inglés, es la técnica que permite crear código
ejecutable para una plataforma distinta a aquélla en la que el compilador se ejecuta. Para ello
se utiliza un compilador cruzado, que será posteriormente utilizado en esta memoria.
3.3. Hardware usado
En este subcapítulo se describe el hardware necesario, y como ya se ha indicado, las razones
de su uso en la realización del Proyecto.
50
3.3.1. Cámara Logitech QuickCam® S 7500™
La cámara web QuickCam® S 7500™ del proveedor Logitech ha sido la escogida para
tomar las fotos utilizadas en el proceso.
Ilustración 21: Cámara sensor Logitech QuickCam
Con conexión USB por cable y 1.3 Mega píxeles, la cámara cumple con los requisitos
requeridos por la aplicación, fácil conexión e instalación automática de drivers y suficiente
calidad de captación de imagen.
Todas las especificaciones técnicas se muestran en la siguiente tabla:
51
Specifications
Connection Type Corded USB
USB Type High Speed USB 2.0, UVC
USB VID_PID VID_046D&PID_09A2
Microphone Built-in, Noise Cancellation
Lens and Sensor Type Glass, CMOS
Focus Type Manual
Field of View (FOV) 72° Diagonal
Focal Length 3.08 mm
Optical Resolution (True) 1.3 MP (1280x960)
Still Image 640x480 (VGA), 1280x960
(1.3 MP) (JPG - True)
Max Video Capture 1280x720 (HD)
Frame Rate (max) 15 fps @ 1280x960 (1.3 MP)
30 fps @ 640x480 (VGA)
Right Light Right Light 2
Tabla 2: Especificaciones de la cámara Logitech QuickCam
Esta cámara, junto al dispositivo micro-controlador que se explica a continuación, constituye
el nodo sensor del esquema de este Proyecto, capaz de captar y procesar las imágenes para su
posterior envío.
Gracias a la conexión USB que provee el dispositivo, la conexión entre ambos es trivial.
3.3.2. BeagleBone
BeagleBone es un ordenador Linux del tamaño de una tarjeta de crédito con funciones de red
y que ejecuta software tales como Android 4.0 y Ubuntu.
Pertenece a la familia de microprocesadores del proyecto BeagleBoard.org [26], dirigida a la
Open Source Community (Comunidad de Código Abierto), a recién iniciados en micro-
controladores y a cualquiera interesado en procesadores de bajo costo ARM Cortex-A8.
52
Ilustración 22: Micro-controlador BeagleBone
Como se muestra en la figura, posee muchos dispositivos de entrada/salida y la característica
de poderse complementar con nuevas placas para aumentar su funcionalidad. Los
procesadores AM335x 720MHz ARM Cortex-A8 de Texas Instruments tienen la potencia de
procesamiento necesaria para el análisis de datos en tiempo real.
Todas las especificaciones técnicas se encuentran en esta tabla para el BeagleBone Rev A6:
53
Para ser más claros en la explicación, en la siguiente figura se muestran los componentes
señalados sobre el BeagleBone:
Component Feature
Processor
AM3359
500MHZ-USB Powered
720MHZ-DC Powered
Memory 256MB DDR2 400MHZ (128MB Optional)
PMIC TPS65217B
Power Regulators
LiION Single cell battery charger (via expansion*)
20mA LED Backlight driver, 39V, PWM (via expansion*)
*(Additional components required)
Debug Support
USB to Serial Adapter miniUSB connector
On Board JTAG via USB 4 USER LEDs
Optional 20-pin CTI JTAG
Power USB 5VDC External jack
PCB 3.4” x 2.1” 6 layers
Indicators Power
4-User Controllable LEDs
HS USB 2.0 Client Port Access to the USB1 Client mode
HS USB 2.0 Host Port USB Type A Socket, 500mA LS/FS/HS
Ethernet 10/100, RJ45
SD/MMC Connector microSD , 3.3V
User Interface 1-Reset Button
Overvoltage Protection Shutdown @ 5.6V MAX
5V Power USB or 5.0VDC to 5.2VDC
Weight 1.4 oz (39.68 grams)
Tabla 3: Especificaciones del BeagleBone Rev A6
54
Ilustración 23: Componentes del BegleBone
En este Proyecto, el dispositivo BeagleBone es usado, gracias a las características que posee,
como nodo sensor con la cámara adaptada y como nodo de reenvío de la red usando baterías
o alimentación de 5V de corriente continua.
Realizan el algoritmo de detección y descripción de propiedades de las imágenes captadas, y
envían estos descriptores hasta el nodo central.
En referencia a los dispositivos BeagleBoard, comentar que en el momento de redacción de
esta memoria, se encuentra disponible el siguiente dispositivo al BeagleBone por parte de la
misma empresa, el BeagleBone Black.
Ilustración 24: BeagleBone Black
55
Como características más destacadas, este dispositivo cuenta con un procesador del mismo
tipo que el visto previamente en el BeagleBone, pero con una frecuencia de reloj de 1GHz y
una memoria interna también superior, de capacidad y tipo 512MB DDR3 RAM.
3.3.3. Controlador central y receptor
El nodo central y receptor de la red de sensores está constituido por un ordenador Intel
Pentium Dual CPU i686 (32-bits), funcionando con Linux Ubuntu como ya se ha comentado
previamente.
Por comodidad, este ordenador es el que crea y mantiene la red WiFi ad-hoc y configura
todos los dispositivos previos a su funcionamiento.
El controlador central recibe los paquetes con las características de la cámara y ejecuta la
tarea de correspondencia. Opcionalmente y con más precisión, las propiedades visuales
recibidas desde el sensor visual de la red se pueden hacen coincidir con propiedades
extraídas de imágenes en una base de datos.
Como se ha comentado, dos características se consideran emparejadas según su distancia de
Hamming, por ejemplo si es inferior a un umbral igual a = 90 bits, lo que generaría una
lista ponderada de todas las imágenes computadas, ordenadas decrecientemente según el
número de propiedades emparejadas.
Opcionalmente también se puede comprobar la consistencia de la geometría con RANSAC,
para cancelar aquellas parejas que no respeten la estructura geométrica entre imágenes
captadas y aquellas de la base de datos.
3.4. Librerías OpenCV
OpenCV (Open Source Computer Vision) es una librería de funciones de programación
dirigida hacia la visión por computador en tiempo real. Desarrollada por Intel en Rusia y
56
lanzado por primera vez en 1999, esta librería es libre para usarse bajo la licencia de código
libre BSD.
Open CV es multiplataforma, existiendo versiones para GNU/Linux, Mac OS X, Windows y
Android OS. También existen proyectos para incorporar estas librerías a Maemo, FreeBSD,
OpenBSD y BlackBerry 10. OpenCV usa CMake para gestionar el proceso de compilación
multiplataforma.
Contiene más de 500 funciones y más de 2500 algoritmos optimizados que abarcan una gran
gama de áreas en el proceso de visión por computador. Estos algoritmos pueden ser usados
para detectar y reconocer caras, identificar objetos, clasificar acciones humanas en videos,
registrar movimientos de una cámara, movimientos de objetos, extraer modelos en 3D de
objetos, producir una nube de puntos en 3D, unir imágenes para producir una imagen en alta
resolución de una escena completa, encontrar imágenes similares dentro de una base de datos
de imágenes, quitar ojos rojos de imágenes tomadas con flash, seguir movimientos de ojos,
reconocer escenarios, etc.
El proyecto OpenCV pretende proporcionar un entorno de desarrollo fácil de utilizar y
altamente eficiente. Esto se ha logrado realizando su programación en código C y C++
optimizados y aprovechando además las capacidades que proveen los procesadores multi-
núcleo. OpenCV puede además utilizar el sistema de primitivas de rendimiento integradas de
Intel, un conjunto de rutinas de bajo nivel específicas para procesadores Intel.
Su principal interfaz está en C++ pero hay también ahora interfaces completas en Python,
Java y MATLAB/OCTAVE. Las API (Application Programming Interface) de estas
interfaces se pueden encontrar en la documentación online [31]. Se han desarrollado también
envoltorios o wrappers en otros lenguajes como C#, Ch o Ruby.
Debido a estas propiedades, estas librerías son las adecuadas para este Proyecto. Contienen
las funciones necesarias para llevar a cabo las tareas de visión por computador requeridas,
como por ejemplo, la detección y descripción BRISK.
La última versión de OpenCV es la número 2.4.9, pero para este Proyecto se ha utilizado la
versión 2.4.5.
En el siguiente capítulo se detalla como incluirlas y utilizarlas en nuestro entorno de
57
desarrollo.
3.5. Protocolos de comunicación inalámbricos
Uno de los aspectos que más impacto causa en las prestaciones de las redes inalámbricas de
sensores es el conjunto de protocolos empleados en cada uno de sus niveles. Por ello, este es
un frente de investigación aún abierto.
A pesar de la existencia de protocolos estándar (IEEE 802.15.4), no dejan de surgir otras
propuestas más eficientes para muchas aplicaciones en las que se requiere un amplio periodo
de funcionamiento con fuentes de energía muy limitadas (bajo coste de los nodos).
En cuanto a tecnologías para la implementación de WSN, en este momento se contemplan
las siguientes:
• WiFi: el estándar de comunicaciones IEEE 802.11 está ampliamente extendido en
comunicación entre computadores. Es una tecnología de elevado ancho de banda.
• BlueTooth: el estándar Bluetooth posibilita la transmisión de voz y datos entre
diferentes equipos mediante un enlace por radiofrecuencia. Requiere mucha menos
potencia para funcionar que WiFi u otros protocolos de comunicación. Es un
estándar ampliamente empleado en telefonía móvil.
• 802.15.4/Zigbee: ha sido diseñado específicamente para el desarrollo de redes
inalámbricas de sensores. Zigbee está orientado a dispositivos de un bajo coste, así
como reducido consumo de energía y gran simplicidad hardware y software.
• 6LowPAN (IPv6 over Low power Wireless Personal Area Networks): es un estándar
que posibilita el uso de IPv6 sobre redes basadas en el estándar IEEE 802.15.4. Hace
posible que dispositivos como los nodos de una red inalámbrica puedan comunicarse
directamente con otros dispositivos IP.
• Tecnologías inalámbricas sub-Ghz: se trata de tecnologías también diseñadas
específicamente para redes de sensores, que operan en bandas inferiores al GHz,
58
típicamente sobre los 400 y 800 Mhz, y cuyo primordial objetivo es el bajo consumo
tanto en transmisión como en recepción. La gran ventaja de estas tecnologías frente a
las ubicadas en los 2.4Ghz es que tienen un mayor radio de alcance, les afecta menos
las inclemencias meteorológicas, y tienen generalmente menos interferencias de
otros dispositivos inalámbricos en dichas bandas que en la de 2.4 Ghz.
En este Proyecto, por comodidad y por la facilidad de adquirir el hardware, ya disponible en
el laboratorio, se han utilizado llaves electrónicas o dongles incorporados con el protocolo
WiFi 802.11n.
Ilustración 25: Dongle WiFi 802.11n
Estos dispositivos son fácilmente adaptables por el puerto USB y configurables en el
BeagleBone.
3.6. Otros protocolos
Dentro de este Proyecto, también se han utilizado otro tipo de protocolos de aplicación:
Network Time Protocol (NTP): es un protocolo de red para la sincronización de
relojes entre sistemas de conmutación a través de paquetes en redes de datos
59
variables en latencia.
En funcionamiento desde antes de 1985, NTP es uno de los protocolos de Internet
más viejos en uso. Un equipo de voluntarios todavía lo desarrolla y mantiene.
Usa una versión modificada del algoritmo de Marzullo para seleccionar con exactitud
los tiempos del servidor y está designado para mitigar los efectos de la latencia
variable de la red. Puede conseguir una precisión de decenas de milisegundos a través
de Internet público y de milisegundos en redes LAN.
Es por todo esto por lo que se utilizará en este proyecto como herramienta
fundamental para calcular los tiempos de envío de los descriptores a través de la red.
La versión usada es la actual en tiempo de redacción de esta memoria, NTPv4, que
está documentada como estándar en RFC 5905.
Secure Shell (SSH): es un protocolo de red con funciones criptográficas para
comunicación segura de datos, inicio de sesión seguro desde línea de comandos,
ejecución remota de comandos, y otros servicios seguros entre dos ordenadores
interconectados por la red. Conecta, a través de un canal seguro sobre una red
insegura, a un servidor y un cliente usando programas SSH para servidor y cliente
respectivamente.
En este proyecto SSH se utiliza para acceder a los dispositivos BeagleBone a través
de la red Ethernet o WiFi para su posterior configuración.
Secure CoPy (SCP): es un protocolo o mecanismo para transferir ficheros de manera
segura entre un ordenador local y un ordenador remoto o entre dos ordenadores
remotos. Está basado en el protocolo SSH mencionado previamente.
En este Proyecto, este protocolo se usa para transferir las librerías necesarias para la
compilación cruzada desde el dispositivo BeagleBone hasta el ordenador local.
60
3.7. Analizadores de tráfico y protocolos
A la hora de usar adecuadamente los protocolos anteriormente mencionados y de configurar
las topologías de red, han sido de mucha ayuda en este Proyecto el analizador de protocolos
Wireshark y el detector de tráfico tcpdump.
Wireshark, antes conocido como Ethereal, es un analizador de protocolos utilizado para
realizar análisis y solucionar problemas en redes de comunicaciones, para desarrollo de
software y protocolos, y como una herramienta didáctica. Cuenta con todas las características
estándar de un analizador de protocolos de forma únicamente hueca.
tcpdump es un herramienta en línea de comandos cuya utilidad principal es analizar el tráfico
que circula por la red permitiendo al usuario capturar y mostrar a tiempo real los paquetes
transmitidos y recibidos en la red a la cual el ordenador está conectado.
Con esto finaliza el tercer capítulo, en el que se ha detallado la idea general de las
tecnologías software y dispositivos hardware necesarios. Es el paso previo a comenzar con el
trabajo práctico de esta memoria, que se describe en el siguiente capítulo.
61
Capítulo 4
Descripción del trabajo realizado
En este capítulo se describe de manera exhaustiva la realización práctica del Proyecto.
En la primera sección se da una visión global del modelo que se está describiendo en este
proyecto.
En la segunda sección se plantea paso a paso el proceso necesario a modo de tutorial para
llevar a cabo la instalación y configuración de las herramientas principales, detallando en la
segunda sección la serie de dificultades que se encontraron en el procedimiento.
En la tercera sección se explican en detalle los programas creados para conseguir los
resultados finales y en la cuarta, la configuración de los dispositivos BeagleBone para
obtenerlos.
4.1. Modelo práctico
Utilizamos ahora para la parte práctica, el modelo del que se ha estado hablando en esta
memoria, representado más claramente en la siguiente figura, y que hemos adoptado con los
dispositivos BeagleBone aplicando la configuración que más adelante se detallará.
62
Ilustración 26: Modelo práctico de estudio
En el primer bloque comenzando por la izquierda se muestra el nodo sensor con la cámara o
“camera sensor node”. Este bloque representa nuestro dispositivo BeagleBone con la cámara
adaptada para la captación o adquisición (“acquisition”) de imágenes. Tras esta adquisición
dentro del bloque, los pasos a seguir son la detección de puntos clave o “keypoints detection”
y la descripción o formación de descriptores (“description”). Este paso ha sido mostrado en
la teoría y será nuevamente detallado para la práctica en las secciones segunda y tercera del
siguiente capítulo. Por último, se establece la comunicación (“communication”) para
transmitir esos descriptores hasta el nodo controlador.
El segundo bloque, el central, se utiliza como nodo de reenvío o “node relay”. Este bloque
está constituido igualmente por un dispositivo BeagleBone con funciones de red y
configurado como nodo de reenvío para poder encaminar los paquetes que le llegan hacia el
nodo final. Esta configuración será explicada en este capítulo. Este bloque puede estar
formado por un dispositivo o varios, para dar más cobertura a la red.
Como último bloque, a la derecha, se representa el nodo controlador central o “central
controller”. Este nodo es el encargado de recibir los descriptores y realizar las tareas de
procesamiento de imágenes pertinentes con ellos, como reconocimiento de objetos o
comparación de imágenes de una base de datos. Este nodo controlador está constituido en
nuestro modelo por el ordenador de arquitectura Intel.
Comenzamos ahora con la instalación y configuración de los componentes mencionados
63
para poder lograr una configuración similar a la previamente mostrada.
4.2. Instalación y configuración
Esta sección muestra la puesta a punto de los componentes del Proyecto que permitirán
posteriormente crear el código ejecutable para el dispositivo BeagleBone.
4.2.1. Configuración de Eclipse para la compilación cruzada
Esta configuración se realizará en 3 pasos que serán detallados a continuación.
Parte 1: Instalar una cadena de herramientas
Para realizar la compilación cruzada de un programa, lo primero que se necesita es una
cadena de herramientas o toolchain con un compilador cruzado para la arquitectura que
tengamos como objetivo.
Esta cadena de herramientas de compilación cruzada debe estar basada en la arquitectura de
nuestro dispositivo BeagleBone ya que permitirá ejecutar programas directamente en el
dispositivo.
Con esto nos ahorramos tener que realizar la compilación directamente sobre el dispositivo,
lo que nos permite realizar tareas de edición y depuración de código de una manera mucho
más sencilla y rápida.
La instalación de la cadena de herramientas se explica en detalle en el segundo anexo de esta
memoria.
Parte 2: Instalación de Eclipse CTD
64
Para poder desarrollar los programas que realizan las tareas que nos hemos propuesto sobre
nuestros dispositivos, nos ayudamos de este entorno de desarrollo.
Eclipse CTD, como ya hemos presentado nos permite programar, editar, compilar y depurar
fácilmente programas en lenguajes C/C++.
La instalación de este entorno de desarrollo es bastante sencilla y se presenta para tener una
mejor referencia en la primera parte del tercer anexo de esta memoria.
Parte 3: Crear y configurar un proyecto
Una vez terminada la primera parte, con Eclipse CTD instalado y ejecutado, el siguiente paso
es crear y configurar un proyecto para que se compile con las librerías y referencias que
nosotros determinamos.
Esta configuración requiere una serie de pasos que se deben llevar a cabo con cuidado y por
ello se presenta en la segunda parte del tercer anexo de esta memoria, justo después de la
instalación del entorno de desarrollo.
Con esto se pretende mostrar una configuración que funciona correctamente y que podría ser
replicada para cualquier sistema, tan solo modificando la ruta de directorio a las librerías
determinadas.
4.2.2. Instalación de las librerías OpenCV
Después de haber instalado y correctamente configurado el entorno de desarrollo, el
siguiente paso sería comenzar a trabajar con las librerías de visión por computador que se
han seleccionado para esta memoria, las librerías OpenCV.
Estas librerías nos permiten usar clases, métodos y funciones ya implementados para llevar a
cabo la mayor parte de las tareas que nos hemos propuesto como objetivo.
Por ello, se presenta la instalación y configuración en detalle de estas librerías en el cuarto
anexo de esta memoria.
65
Con esto tenemos configuradas las herramientas necesarias para comenzar a programar el
código de nuestro proyecto, y compilarlo correctamente para cada tipo de dispositivo con las
librerías de visión por computador necesarias.
4.3. Errores encontrados en la instalación y configuración
Dentro de la instalación es importante tener en cuenta los pasos que se han comentado en
cuanto a los requisitos para instalar las librerías y el software necesario.
En cuanto a la compilación cruzada, durante la compilación de programas, se encontraron
problemas de compatibilidad de librerías debidos probablemente a que la cadena de
herramientas de compilación cruzada no era totalmente compatible con la arquitectura de
nuestro BeagleBone.
Para remediar esto y no obtener problemas en la compilación, lo que se realizó fue obtener
esas librerías problemáticas directamente desde los archivos internos del dispositivo
BeagleBone y usarlos para la compilación en lugar de esas librerías que venían por defecto
en la cadena de herramientas que descargamos en el apartado previo.
Este proceso es un poco tedioso por el aspecto de la búsqueda y el reemplazo de las librerías,
que se debe repetir múltiples veces, pero finalmente se ha conseguido realizar una
compilación cruzada apropiada al dispositivo.
Es necesario comentar, que la compilación cruzada se puede obviar realizando una
compilación directa sobre el mismo dispositivo BeagleBone. Esta opción no se contempla en
este Proyecto, dado que supone un proceso mucho más laborioso en cuanto a la depuración y
modificación de los programas, que no se pueden realizar con facilidad desde el mismo
dispositivo.
66
4.4. Programación del hardware
En esta sección se explican los programas realizados para la obtención de los datos. Todos
los programas están realizados en el lenguaje de programación C++ y utilizando la
configuración detallada en la primera sección de este capítulo sobre el entorno de desarrollo
Eclipse.
4.4.1. Programa de obtención de las imágenes
El código de este programa, detallado en el Anexo 5, permite conseguir, a partir de una
imagen origen de tamaño 768 píxeles de ancho por 1024 píxeles de alto, las imágenes
escaladas en tamaño que utilizaremos para calcular los tiempos de detección y descripción
del algoritmo BRISK.
Se obtienen 5 imágenes a partir de cada imagen origen, escaladas al 10, 25, 50, 75 y 90% del
valor original.
Este programa se detalla como un primer ejemplo de uso de las librerías OpenCV junto a la
programación C++ sobre Eclipse CDT.
El código es bastante sencillo y con el que gracias al hecho de incluir las librerías OpenCV
podemos hacer uso de las siguientes funciones:
- cvLoadImage: carga una imagen almacenada en la memoria. Devuelve un
puntero a la imagen cargada en la memoria de ejecución del programa.
- cvCreateImage: crea las cabeceras y reserva memoria para una nueva
imagen.
- cvResize: re-escala la imagen que se introduce por parámetro
- cvSaveImage: guarda una imagen en memoria
Siguiendo el flujo lógico del programa, lo primero que se realiza es declarar una variable de
67
tipo puntero a “IplImage” y asignarle el valor de retorno de la función cvLoadImage. Con
esto tenemos una referencia a la imagen original que acabamos de cargar de memoria.
“IplImage” se trata sólo de una estructura que contiene los datos de la imagen en sí, más algo
de información sobre ella (tamaño, profundidad de color, etc). Todos los campos de la
estructura se encuentran detallados al final del quinto anexo.
Seguido a esto se definen los porcentajes de reducción de escala de las imágenes y se utiliza
la función cvCreateImage con ellos para reservar la memoria necesaria para las nuevas
imágenes.
A la función cvCreateImage se le pasan como parámetros el ancho y el alto, la profundidad
de pixel en bits y el número de canales por píxel de la imagen de destino. El número de
canales puede ser 1, 2, 3 o 4. Esta función devuelve un puntero a estructura “IplImage”, igual
que ya lo hacía la función previa.
Una vez reservado el tamaño para las imágenes escaladas, se usa la función cvResize con la
imagen origen como primer parámetro y el puntero a “IplImage” de destino como segundo
parámetro. Con esto conseguimos tener escalada la imagen apropiadamente.
Por último se utiliza la función cvSaveImage con el nombre y el PATH de la imagen de
destino como primer parámetro y el puntero a “IplImage” final que obtuvimos en la función
anterior. Con esto conseguimos salvar las imágenes en memoria.
Este procedimiento se repite con las 5 fotos diferentes que se han tenido en cuenta.
Este set de imágenes se utilizará como hemos comentado en el programa de cálculo de
tiempos y será definido posteriormente en el capítulo 5.
4.4.2. Programa de obtención de tiempos locales del algoritmo BRISK
El código de este programa, detallado en el Anexo 6, es usado para el cálculo de los tiempos
de detección y extracción del algoritmo BRISK en el proceso para conseguir los descriptores.
68
Con este método, estamos llevando a cabo mediante las librerías de OpenCV la primera y
segunda parte del algoritmo BRISK, explicados como “Detector” y “Extractor BRISK”
respectivamente en el segundo capítulo de esta memoria.
Siguiendo el diagrama de flujo del programa, lo primero que se realiza es definir el extractor
de tipo BRISK con la siguiente función de OpenCV:
- BriskDescriptorExtractor()
Una vez hecho esto, cada una de las imágenes que se utilizan se cargan dentro del programa
con la siguiente función:
- imread(fichero_imagen, -1)
Donde fichero_imagen, el primer parámetro, es el fichero que contiene la imagen con
extensión .jpg y donde el valor -1, el segundo parámetro, indica a la función que cargue la
imagen tal y como es, sin ningún tipo de modificación de color. Una vez hecho esto, se
utiliza la macro CV_Assert para comprobar si se ha leído bien la imagen.
Se convierte la imagen a escala de grises con la siguiente función:
- ctvColor
Esto se ha llevado a cabo para llevar a cabo el algoritmo BRISK con más rapidez en la
respuesta aunque finalmente los resultados se muestran con la imagen original.
Se crean los ficheros de resultados y su formato para posterior presentación y organización.
Llevamos ahora a cabo la primera parte del método BRISK, la detección, como ya hemos
dicho detallada en el cuarto apartado del segundo capítulo de esta memoria como “Detector
BRISK”.
Estamos por lo tanto realizando la versión multi-escala del popular algoritmo FAST (Fast
Accelerated Segment Test) que fundamentalmente clasifica puntos candidatos según su
intensidad y la de los píxeles contiguos y otorga una puntuación determinada que se compara
con el umbral máximo que hemos previamente establecido.
Luego, siguiendo con el código, para diferentes valores de umbrales de detección
(representado en el programa como thresh), desde 120 a 20, y con escala de 10 como salto,
69
se crea el detector BRISK con la siguiente función:
- BriskFeatureDetector(umbral, octavas)
Donde como hemos dicho, el umbral es una variable y las octavas es un valor de precisión
del algoritmo que se toma fijo con un valor de 3 en este caso.
Se mide el tiempo mediante la función “getTickCount” y sucesivamente se detectan los
puntos importantes mediante el método “detect”. Justo después se vuelve a medir el tiempo y
por diferencia de estos se calcula el tiempo de detección.
Este método “detect” de nuestra variable BriskFeatureDetector, lleva a cabo la primera parte
del algoritmo sobre nuestra imagen pasada como primer parámetro. Como segundo
parámetro de este método, se debe introducir el vector de tipo keypoints o puntos clave
donde se almacenaran los datos obtenidos por esta función.
Se puede conocer la cantidad de puntos importantes obtenidos gracias a la función “size”.
Pasando ahora a la segunda parte del método BRISK, tenemos que llevar a cabo la
descripción, como ya hemos dicho detallada en el cuarto apartado del segundo capítulo de
esta memoria como “Descriptor BRISK”.
Dado un conjunto de puntos clave, el descriptor BRISK se compone de una cadena binaria
formada mediante la concatenación de resultados de comprobaciones simples del brillo o
iluminación. En BRISK, se identifica la dirección característica de cada punto clave para
permitir descriptores de orientación normalizada y por lo tanto lograr invariancia de rotación,
que es clave para tener una mayor robustez general en el método. Además, se seleccionan
cuidadosamente las comparaciones de brillo con el enfoque de maximizar el carácter
descriptivo.
Luego, siguiendo con el programa, se vuelve a repetir el proceso de los tiempos con el
método de cálculo de descriptores “compute”.
Este método “compute” de nuestra variable BriskDescriptorExtractor, creada al principio de
nuestro programa, lleva a cabo la segunda parte del algoritmo sobre nuestra imagen pasada
como primer parámetro. Como segundo parámetro de esta función, se introduce el vector de
puntos importantes obtenido con el método previo “detect” y que resulta fundamental para
poder llevar a cabo el algoritmo. Como tercer parámetro al método, se pasa una matriz de
70
tipo Mat de OpenCV donde se guardarán los resultados, los descriptores finales BRISK, muy
importantes en este Proyecto.
Por último se guardan los resultados en su fichero correspondiente y se cierran y liberan
recursos.
Así, tenemos los resultados de puntos importantes y descriptores BRISK, y los tiempos que
han sido necesarios para calcularlos.
4.4.3. Programación del nodo con la cámara
El código de este programa, detallado en el Anexo 7, está formado por AdquireImage.cpp,
Communication.cpp y Communication.hpp. Es el programa que se ejecuta en el nodo
BeagleBone que captura las imágenes y las envía.
En AdquireImage.cpp, se comienza conectando la cámara y capturando una imagen
mediante las funciones de OpenCV “cvCaptureFromCam” y “cvQueryFrame”. También se
podían haber utilizado las funciones “GrabFrame” y “RetrieveFrame” a la hora de captar la
imagen.
Posteriormente, se utiliza la función “cvSaveImage” para guardar la imagen.
Con el mismo procedimiento que en la sección anterior, se extraen los puntos claves y se
construyen los descriptores.
Una vez hecho esto se llama a la función “communication” pasando como parámetro la
matriz de descriptores.
La función “communication” establece la comunicación mediante sockets con el nodo
receptor y una vez hecho esto comienza a realizar el envío de los descriptores.
El envío se realiza dependiendo del número de descriptores que se hayan obtenido. Si este
número es menor o igual a 10, estos descriptores se envían todos en un mismo paquete. Si,
en cambio, hay más de 10 descriptores, lo que resulta el caso más normal, se divide la matriz
en sub-matrices de 10 descriptores y se van enviando estas una detrás de otras como
paquetes diferentes.
71
Se contempla el caso muy probable de que el último paquete no tenga justo 10 descriptores.
Como función para enviar se usa “sendto”.
Antes del primer envío, se hace uso de la función “ntp_gettime” de la librería de funciones
“sys/time.h” para calcular el tiempo exacto. Esta función también se utilizará a la hora de la
recepción para calcular la diferencia de tiempos en el envío.
La sincronización de los relojes mediante el servicio “ntp” se muestra detallada en la
siguiente sección.
4.4.4. Programación del controlador central
El código de este programa, detallado en el Anexo 8, se muestra la descripción del receptor.
Se utiliza la función “recvfrom” para recibir los descriptores.
Igualmente, se utiliza la función “ntp_gettime” para conseguir los tiempos necesarios en la
recepción.
Bastará con una resta de tiempos teniendo en cuenta el retraso de los relojes en la red para
conseguir el tiempo de transmisión.
4.5. Configuración de los BeagleBone
La configuración de los dispositivos BeagleBone la realizamos a través del puerto USB
disponible en la placa y conectándolo directamente a nuestro ordenador Linux Ubuntu.
Esta conexión USB provee al mismo tiempo energía para el funcionamiento del dispositivo
y se utiliza de igual manera como ya se ha comentado para adaptar los dongle WiFi que
proveen la comunicación wireless a los dispositivos.
Un led del dispositivo debe encenderse cuando realizamos la función de conexión USB.
72
Ilustración 27: Conexión del BeagleBone
Un aspecto interesante de los dispositivos BeagleBone en Linux es que no necesitan drivers
en la conexión para ser reconocidos y usados. Para versiones antiguas, hay un archivo con
reglas disponible en la página oficial de BeagleBone para configurar automáticamente el
acceso al dispositivo desde la consola de Linux.
En la tarjeta Micro-SD disponible con el dispositivo se encuentran dos particiones. Una es el
sistema operativo Ångström y la otra es una FAT donde se encuentran los archivos de
manual y drivers para sistemas operativos MAC y Windows.
Para ver los contenidos de la unidad, solo deberemos ir a la terminal del ordenador Ubuntu e
introducir:
ubuntu:~$ ls /media/BEAGLE_BONE
4.5.1. Establecer la comunicación con el BeagleBone
Una vez conectado el dispositivo con el cable USB, para interactuar con el dispositivo desde
nuestro ordenador tenemos que seguir una serie de pasos.
Abrir una terminal en Ubuntu desde nuestro ordenador e introducir el siguiente comando:
ubuntu:~$ screen /dev/ttyUSB1 115200
73
Es importante conocer previamente en qué nodo USB se encuentra nuestro dispositivo
BeagleBone. Para ello podemos basarnos de la información del siguiente comando, que nos
da información de los dispositivos conectados a los puertos USB:
ubuntu:~$ ls /dev/ttyUSB*
El valor 115200 en el comando “screen” se trata de la velocidad de transmisión en baudios
para la interfaz serie que conecta el chip del procesador del BeagleBone.
Este comando “screen” crea una terminal virtual para la comunicación con el dispositivo
conectado al puerto serie virtual USB en /dev/ttyUSB1.
Una vez hecho esto presionamos la tecla “Enter” y debemos obtener la pantalla de inicio de
sesión de Ångström, ya mostrada en la ilustración número 20 de esta memoria.
Iniciamos con root como valor de “login” y sin contraseña para el valor de “Password”, que
son los valores de inicio de sesión predeterminados. Deberemos ver el siguiente valor a partir
de ahora en la Terminal:
root@beaglebone:~#
Desde ahí podemos ejecutar comandos directamente en el dispositivo y por ejemplo
configurar la comunicación Ethernet, ya que el puerto USB del BeagleBone puede también
funcionar como puente de red o bridge Ethernet.
Podemos usar esta funcionalidad para comunicarnos con el PC usando SSH, el protocolo de
comunicación de datos seguro que ya se ha comentado.
Para hacerlo debemos salir de la terminal del BeagleBone presionando Ctrl+A, k, lo cual
nos lleva de vuelta a la terminal del PC.
Para abrir una sesión SSH, introducir:
ubuntu:~$ ssh –X [email protected]
74
Donde 192.168.7.2 es la dirección IP de nuestro BeagleBone. La opción –X habilita X11 con
soporte para interfaz gráfica de usuario, y no es necesaria. Para salir de la terminal basta
escribir “exit” y presionar “Enter”.
Estas opciones de comunicación son muy interesantes ya que nos permiten en el proyecto
comunicarnos fácilmente con el dispositivo para el intercambio de archivos, carga de
programas, y completa configuración del mismo.
Es también muy útil para cargar los programas en el dispositivo BeagleBone o tomar las
librerías necesarias para la compilación cruzada. Esto se puede realizar usando el protocolo
SCP, Secure CoPy, explicado en el tercer capítulo de esta memoria, en el apartado de “Otros
Protocolos”.
4.5.2. Configuración del nodo de reenvío
En esta sub-sección se explica cómo configurar los dispositivos BeagleBone que se utilizarán
como nodos de reenvío o encaminadores de los paquetes que se envían.
Lo primero sería habilitar el reenvío o forwarding de paquetes IP y lo segundo modificar las
rutas estáticas, todo esto en cada dispositivo que se vaya a usar de nuestra topología.
En la mayoría de las distribuciones de Linux en el reenvío de paquetes IP está desactivado.
De hecho, en la mayoría de los casos prácticos no necesita esta característica, pero si
queremos utilizar el PC como router, encaminador, servidor VPN (PPTP o IPSec) de Linux o
un servidor de acceso telefónico, entonces tendrá que activarse el reenvío, es decir, la
capacidad del sistema operativo de reenviar el tráfico de la red de una interfaz a otra. Esto
ocurre también con nuestro dispositivo y se puede realizar de diferentes maneras, como se
describirá a continuación.
Lo primero es consultar la variable del núcleo del sistema que nos indica si esta característica
está activada o no.
Podemos hacer esto directamente con el comando “sysctl”:
root@beaglebone:~# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
75
O simplemente para comprobar el valor en los procesos del sistema:
root@beaglebone:~# cat /proc/sys/net/ipv4/ip_forward
0
Como se puede ver en los ejemplos anteriores el valor de retorno es 0, lo que significa que el
reenvío de IP está deshabilitado.
Con el comando “sysctl” y con los permisos necesarios, podemos cambiar el valor de
“net.ipv4.ip_forward” sobre la marcha, es decir, sin necesidad de reiniciar el sistema:
root@beaglebone:~# cat /proc/sys/net/ipv4/ip_forward
O realizando:
root@beaglebone:~# echo 1 > /proc/sys/net/ipv4/ip_forward
Con esto el valor se establece de inmediato, pero no se guarda para un reinicio posterior, lo
que nos interesaría, ya que queremos que nuestro dispositivo mantenga el reenvío cuando lo
conectemos a una batería o a la corriente eléctrica directamente.
Si queremos establecer de forma permanente este parámetro, la mejor forma es editar el
archivo “/etc/sysctl.conf”, donde se puede añadir una línea que contiene:
- net.ipv4.ip_forward = 1
Si la línea que ya existía estaba inicializada a 0, se puede cambiar el valor a 1. Si se
encontraba comentada (con un signo "#"), simplemente basta borrarla y reemplazarla.
Para activar los cambios realizados en el archivo “sysctl.conf” ejecutar el comando:
root@beaglebone:~# sysctl -p /etc/sysctl.conf
O mediante la ejecución de la reanudación de la red de servicios:
76
root@beaglebone:~# service network restart
Con esto queda establecido el reenvío.
En cuanto a las rutas estáticas, éstas se modifican usando el comando “route” disponible en
Linux Ubuntu.
Para crear una ruta se usa la opción “add” mientras que para borrar una ya existente se debe
usar “del”. Para ver las rutas que tenemos establecidas basta introducir en la terminal el
comando “route” con permisos de superusuario.
Se configuran las rutas apropiadamente para que los paquetes puedan encaminarse
correctamente dependiendo de la topología que se esté utilizando en cada momento, teniendo
en cuentas las direcciones IP de cada dispositivo y las interfaces que se están usando.
Para realizar este proceso es bueno usar herramientas como Wireshark, ya descritas, para
comprobar que los paquetes se están encaminando correctamente.
4.5.3. Configuración NTP
Como se ha comentado en la memoria, el protocolo NTP es fundamental para conseguir una
sincronización de los relojes de partida, en el dispositivo que envía; y de llegada, en el
dispositivo que recibe.
Las funciones encargadas de obtener los tiempos se han explicado en el apartado previo y se
utilizan en el código de los programas detallados en los anexos.
Para la instalación del servicio se puede usar la página oficial de Ubuntu o directamente la
línea de comandos:
ubuntu:~$ sudo apt-get install ntp
Una vez hecho esto, se debe cambiar la configuración del servicio en el siguiente fichero
realizando el siguiente comando:
77
ubuntu:~$ sudo nano /etc/ntp.conf
Obteniendo una respuesta como la siguiente:
server 0.ubuntu.pool.ntp.org
server 1.ubuntu.pool.ntp.org
server 2.ubuntu.pool.ntp.org
server 3.ubuntu.pool.ntp.org
Es en este fichero donde configuramos los servidores NTP a los que se recurrirá para
sincronizar el reloj de tiempos. Luego, después de esto, procedemos a cambiar este fichero
para que todas las BeagleBone sincronicen su reloj con el del ordenador central, con IP
10.42.0.1, quedando lo siguiente:
#server 0.ubuntu.pool.ntp.org
#server 1.ubuntu.pool.ntp.org
#server 2.ubuntu.pool.ntp.org
#server 3.ubuntu.pool.ntp.org
server 10.42.0.1
Una vez modificado y guardado el archivo, se reinicia el servicio para aplicar los cambios:
ubuntu:~$ sudo service ntp restart
Para comprobar si el servidor esta sincronizado, podemos recurrir a la siguiente orden:
ubuntu:~$ sudo ntpq -c lpeer
Y por último, mediante el siguiente comando, podemos conocer el retraso o el offset que se
está produciendo en la sincronización:
78
ubuntu:~$ ntptrace
Este retraso de sincronización se tendrá en cuenta en el cálculo de los tiempos, incluso si se
puede considerar despreciable por ser del orden de décimas de milisegundos.
Con esto termina el cuarto capítulo, en el que se han explicado con detalle todos los pasos
necesarios para llevar a cabo la obtención de los resultados prácticos de esta memoria y que
serán detallados en el siguiente capítulo.
79
Capítulo 5
Descripción y evaluación de resultados
En este último capítulo práctico se finaliza mostrando los resultados y explicando mediante
gráficas y comentarios los tiempos de cálculo de todo el procedimiento.
Para ello se comienza dando una descripción de las fotos utilizadas para tener más precisión
en el proceso. Los resultados se muestran posteriormente en las secciones segunda, tercera y
cuarta.
En la quinta se indica cómo finalizar el proceso.
5.1. Muestras utilizadas
En esta sección se explican las imágenes usadas y precargadas en los dispositivos
BeagleBone para el cálculo de los tiempos de detección y extracción. También se utilizan en
el cálculo de tiempos del algoritmo en nuestro ordenador con arquitectura Intel, y así poder
obtener una comparativa de dos procesadores diferentes.
Se han utilizado estas muestras, y no imágenes obtenidas de la cámara por el hecho de tener
más precisión en el cálculo, ya que se usan varias repeticiones en el procedimiento por cada
imagen.
Las imágenes se han obtenido de la base de datos de imágenes “all_souls” de un colegio
universitario de Oxford, muestras comunes para pruebas en el procesamiento digital de
imágenes.
80
Se utilizan 15 imágenes de esta base de datos, que junto a sus versiones escaladas,
conforman 90 imágenes diferentes.
En las siguientes ilustraciones podemos ver un ejemplo de la primera imagen original y sus
versiones escaladas.
Las imágenes originales, como ya se ha comentado, poseen un tamaño de 768 píxeles de
ancho por 1024 píxeles de alto (768x1024).
Los factores de re-escala que se han tenido en cuenta han sido 10, 25, 50, 75 y 90%. Las
imágenes se han ampliado en esta memoria para poder apreciar la diferencia entre ellas.
Ilustración 28: Imagen original
81
Ilustración 29: Imágenes escaladas al 10 y 25%
Con estas imágenes, poseemos más variedad en el análisis y a la vez podemos comparar los
diferentes resultados de tiempos entre una imagen original y sus versiones escaladas.
En las siguientes dos secciones, para los tiempos de detección y extracción, se presentan
primero los datos con las imágenes originales y luego sendos ejemplos con sus versiones
escaladas.
5.2. Tiempos obtenidos en la detección
En esta sección se detallan los tiempos conseguidos en el proceso de detección del algoritmo
BRISK para nuestras imágenes previas.
Los resultados, como ya se ha comentado, se han obtenido sobre el BeagleBone, mediante la
compilación cruzada; y sobre el ordenador Intel, con una compilación directa, para contrastar
los resultados de ambos procesadores.
La medición de los tiempos se realiza gracias a las funciones “getTickCount” y
“getTickFrequency” en el código del programa mostrado en el sexto anexo. Se obtiene una
medida previa a la llamada a la función “detect” y otra posterior a esta, y con una simple
82
diferencia de marcas se obtiene nuestro resultado:
La función “getTickCount” devuelve el número de marcas después de un suceso
determinado (por ejemplo, cuando la máquina se enciende). Dado que para lo que queremos
esta función es para realizar una diferencia de marcas, no nos importa el evento que se esté
tomando como inicio, ya que éste será el mismo en sendas llamadas a la función.
En cuanto a la función “getTickFrequency”, esta nos devuelve el número de marcas por
segundo, lo que nos posibilita conseguir el tiempo entre las dos marcas establecidas, una
justo antes de la función y otra inmediatamente después, como se ha comentado.
5.2.1. Resultados en el BeagleBone
Se presenta ahora uno de los ficheros respuesta del programa detallado en el sexto anexo.
Representa los tiempos de detección, primera fase del algoritmo BRISK, sobre nuestro
dispositivo BeagleBone.
El fichero se llama “detector_01_det_time.txt” haciendo referencia a la primera foto de
768x1024 píxeles y al algoritmo de detección utilizado.
83
Ilustración 30: Resultados de detección en el BeagleBone (768x1024 píxeles)
En la primera columna, con título “threshold” se representa el umbral de detección utilizado
como variable en la función “detect” del método, que quedó explicado en el cuarto apartado
del segundo capítulo de esta memoria, “Detección BRISK”. Vemos que se toman valores
desde 120 hasta 20 con saltos de 10 entre uno y otro, como habíamos especificado en la
descripción del programa en el anterior capítulo.
En la segunda columna, con título “det_time (ms)” se representa el tiempo de detección en
milisegundos, resultado de la operación anteriormente mencionada de diferencia de tiempos.
En la tercera y última columna, con nombre “tam_keypoints”, se ha representado el número
de elementos del vector de puntos clave, es decir el número de puntos clave que se han
detectado en el procedimiento.
Con un rápido vistazo al fichero de resultados podemos sacar conclusiones que ya
imaginábamos según la teoría del método, explicada en el segundo capítulo.
Por ejemplo, podemos ver que a medida que el umbral de detección se sitúa más alto, el
número de detectores que se obtienen es mucho menor, llegando al máximo de que solo se
detecte un punto clave para un umbral de detección de valor 120, y a medida que el umbral
84
de detección se sitúa más bajo y relajado, el número es mucho mayor, llegando al máximo en
este caso de que se detecten 15433 puntos importantes para un umbral de detección de valor
20.
Otra conclusión inmediata de este archivo, es que si este umbral se acrecienta, el tiempo
necesario en calcular los puntos claves es menor y viceversa. Es un razonamiento obvio
teniendo en mente la primera conclusión.
Luego, como resumen, podríamos concluir que la variable umbral de detección posee una
característica inversamente proporcional al número de puntos clave detectados y, por lo tanto,
al tiempo de detección de estos.
En la siguiente gráfica, independientemente del valor del umbral escogido, se muestran los
tiempos de detección por número de puntos clave obtenidos. Para esta gráfica se han tenido
en cuenta los datos recogidos de las 15 imágenes originales (768x1024), siempre realizando
el algoritmo de detección sobre nuestro dispositivo BeagleBone.
Tabla 4: Gráfico de tiempos de detección en el BeagleBone (768x1024)
200
300
400
500
600
700
800
900
1000
1100
1200
1300
1400
1500
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
De
tect
ion
_Tim
e (
ms)
Tam_Keypoints (en miles)
Thousands
Results1_BB (Detector)
85
En esta gráfica se aprecia la conclusión mencionada previamente. A medida que el tiempo de
detección es mayor, fruto de un umbral de detección más bajo, el número de puntos clave
que se obtienen es mayor y viceversa. Se aprecia también que la característica es lineal con
pendiente positiva en este caso.
Se muestran ahora a continuación y para contrastar los primeros resultados, los tiempos de
detección para las imágenes escaladas al 50% de su tamaño, es decir, las mismas imágenes
representadas por 384x512 píxeles.
Para la primera foto origen escalada al 50% de su tamaño, y teniendo en cuenta que se
realizan los cálculos de nuevo sobre el BeagleBone, se tienen los siguientes resultados de
tiempos de detección:
Ilustración 31: Resultados de detección en el BeagleBone (384x512 píxeles)
El fichero se llama “detector_01_det_time50.txt” haciendo referencia a la primera foto de
768x1024 píxeles escalada al 50% y al algoritmo de detección utilizado. Este fichero tiene el
mismo formato de tres columnas del primer archivo.
86
En este caso, se aprecia en primer lugar cómo el número de puntos clave detectados se ha
reducido para la imagen escalada al 50%, llegando al extremo de no obtener ningún punto
para un umbral de detección de valor 120.
En cuanto a los valores de tiempos, éstos también se reducen debido a que el número de
puntos clave encontrados en esos umbrales es menor y es necesario menor tiempo en la
comparación para localizarlos.
Es interesante hacer notar que para encontrar el máximo número de puntos clave en la
imagen al 50%, se requiere aproximadamente la mitad de tiempo que lo que se tarda para
localizar este mismo número de puntos en la imagen original. Lo único que difiere es el
umbral que toma cada uno.
Esto nos indica que, sabiendo el número de puntos clave que vamos a necesitar obtener a
partir de una imagen para, por ejemplo, reconocimiento facial, puede ser más conveniente
reducir la imagen a la vez que se disminuye también el umbral de detección. Esto tendría
como ventaja una ganancia en el tiempo de detección en este algoritmo. La desventaja es, sin
embargo, tener menor precisión en la detección de los puntos clave del algoritmo BRISK, y
es con este balance con el que se debe jugar a la hora de seleccionar entre una opción u otra.
Esta conclusión de tiempos y número de puntos detectados se repite también en los
resultados de las imágenes escaladas con diferentes porcentajes, al igual que con las
diferentes 15 imágenes con las que se ha realizado el procedimiento.
Repitiendo el proceso anterior, en la siguiente gráfica, independientemente del valor del
umbral escogido, se muestran los tiempos de detección por número de puntos clave
obtenidos. Para esta gráfica se han tenido en cuenta los datos recogidos de las 15 imágenes
originales reducidas al 50% (384x512), siempre realizando el algoritmo de detección sobre
nuestro dispositivo BeagleBone.
87
Tabla 5: Gráfico de tiempos de detección en el BeagleBone (384x512)
Al igual que en el primer ejemplo, en este, tomando la imagen reducida, también se puede
notar la linealidad del algoritmo en la descripción, esta vez con una pendiente del 10%. Estas
gráficas nos dan rápidamente una idea del tiempo que vamos a emplear sabiendo el número
de puntos que necesitamos tomar.
En la siguiente gráfica se hace un zoom de la figura previa en la zona donde más muestras se
han tomado, la parte de menor número de puntos clave hallados.
A pesar de que la nube de puntos se aprecia más dispersa, se sigue notando la característica
lineal que este algoritmo posee en el cálculo de los puntos clave.
80
130
180
230
280
330
380
430
480
530
580
630
680
0 500 1000 1500 2000 2500 3000 3500 4000 4500 5000 5500 6000
De
tect
ion
_Tim
e (
ms)
Tam_Keypoints
Results1_50_BB (Detector)
88
Tabla 6: Gráfico de tiempos de detección en el BeagleBone 2 (768x1024)
Con esto acabamos el estudio de tiempos de detección en el dispositivo BeagleBone y
pasamos al del ordenador de arquitectura Intel.
5.2.2. Resultados en el ordenador Intel
Se presenta a continuación otro fichero respuesta del programa detallado en el sexto anexo.
Este fichero representa de nuevo los tiempos de detección, primera fase del algoritmo
BRISK, pero esta vez sobre nuestro ordenador de desarrollo Intel. Se toma igualmente para
este ejemplo, la primera imagen original con tamaño 768x1024.
80
90
100
110
120
130
140
150
160
170
0 100 200 300 400 500 600 700 800 900 1000
De
tect
ion
_Tim
e (
ms)
Tam_Keypoints
Results1_50_BB (Detector)
89
Ilustración 32: Resultados de detección en el ordenador (768x1024 píxeles)
Vemos que tanto el nombre como el formato y la información que se representa en las tres
columnas son iguales a los del primer archivo con extensión .txt mostrado anteriormente. La
imagen tomada y el programa usado son los mismos y solo cambia el método de
compilación y el dispositivo usado para obtenerlos.
En este caso, vemos que el único cambio dentro de los valores obtenidos lo representan los
tiempos de detección de puntos clave, siendo estos un orden de magnitud inferior a los del
fichero anterior.
Este es también un resultado esperado, debido a la diferencia de procesador de uno y otro
dispositivo, no estando el dispositivo BeagleBone igualmente dotado como lo pueda estar un
ordenador portátil común o un ordenador de sobremesa, dado que el principal objetivo de los
micro-controladores BeagleBone, como hemos explicado, es tener un dispositivo económico
que permita escalar fácilmente una red de sensores inalámbrica.
Vemos también que el número de puntos importantes obtenidos sigue siendo el mismo que
en el archivo anterior, esto es debido a que el método y la imagen usados son los mismos,
como ya se ha comentado.
Se muestran ahora a continuación y para contrastar los primeros resultados, los tiempos de
detección para las imágenes escaladas al 50% de su tamaño, es decir, las mismas imágenes
90
representadas por 384x512 píxeles.
Para la primera foto origen escalada al 50% de su tamaño, y teniendo en cuenta que se
realizan los cálculos de nuevo sobre el ordenador Intel, se tienen los siguientes resultados de
tiempos de detección:
Ilustración 33: Resultados de la detección en el ordenador (384x512 píxeles)
En este caso para el ordenador, podemos sacar las mismas conclusiones que en el apartado
anterior sobre el BeagleBone, comparando este fichero con el mismo para la imagen en
versión original. Menos puntos son detectados en este caso y el tiempo para calcularlos es
considerablemente menor en proporción.
Si comparamos ahora los ficheros de resultados de fotos escaladas al 50%, uno realizado
sobre el BeagleBone y otro sobre el ordenador, llegamos a la misma conclusión que en las
imágenes originales. El tiempo de detección es un orden de magnitud más pequeño en las
realizaciones sobre el dispositivo BeagleBone, por las razones que ya se han indicado en este
mismo apartado.
En este apartado no se muestran las gráficas de resultados de tiempos de las realizaciones
independientemente del valor del umbral de detección, con la finalidad de no recargar
91
demasiado esta parte de la memoria. Se indica igualmente, que la característica de las
gráficas seguiría siendo lineal al igual que las mostradas previamente, solo cambiando la
escala de tiempos, más pequeña para la realizada sobre el ordenador.
Con esto acabamos el estudio de tiempos de detección en el ordenador y pasamos al estudio
de tiempos de extracción.
5.3. Tiempos obtenidos en la extracción
En esta sección se detallan los tiempos conseguidos en el proceso de extracción, y por lo
tanto, en el cálculo de descriptores del algoritmo BRISK para nuestras imágenes previas. Es
el paso posterior a la detección.
Los resultados, como ya se ha comentado, se han obtenido sobre el BeagleBone, mediante la
compilación cruzada; y sobre el ordenador Intel, con una compilación directa, para contrastar
los resultados de ambos procesadores.
La medición de los tiempos se realiza de nuevo gracias a las funciones “getTickCount” y
“getTickFrequency”. Se obtiene una medida previa a la llamada a la función “compute” y
otra posterior a esta, y con una simple diferencia de marcas se obtiene nuestro resultado:
La explicación de las funciones utilizadas en el cálculo ya ha sido detallada al comienzo de
la sección previa.
La función “compute”, como ya se detalló, realiza la función de extracción y cálculo de
descriptores según el algoritmo BRISK, explicado en la teoría del cuarto apartado del
92
segundo capítulo de esta memoria.
Cada descriptor obtenido, como ya se ha explicado en esta teoría, se trata de un vector de
componentes binarios. Aunque el tamaño de este vector no está fijado, como valor más
común se toma 64, y ese es el número de elementos que tiene cada uno de nuestros
descriptores BRISK obtenidos.
Luego lo que obtenemos como resultado después de realizar el método “compute” es una
matriz rectangular en la que cada fila i representa un descriptor diferente. El número de filas
variará según el número de puntos clave detectados previamente. En esta matriz, por cada
fila i obtenemos 64 columnas que representan los valores de nuestro descriptor número i.
Luego, en resumen, el número de descriptores será igual al número de filas, y el tamaño de
estos será igual al número de columnas de esa matriz.
Tomando el número de descriptores como n y el valor de los elementos de los descriptores
como Axy, siendo x la fila e y la columna, podemos representar la matriz de descriptores de la
siguiente forma:
Procedemos ahora a mostrar los resultados y las conclusiones primero en la BeagleBone y
posteriormente en el ordenador Intel al igual que en la sección previa.
5.3.1. Resultados en el BeagleBone
Se presenta ahora nuevamente uno de los ficheros respuesta del programa detallado en el
sexto anexo. Representa los tiempos de cálculo de descriptores, segunda fase del algoritmo
BRISK, sobre nuestro dispositivo BeagleBone.
El fichero se llama “extractor_01_desc_time.txt” haciendo referencia a la primera foto de
93
768x1024 píxeles y al algoritmo de extracción utilizado.
Ilustración 34: Resultados de la extracción en el BeagleBone (768x1024 píxeles)
En la primera columna, con título “desc_time (ms)” se representa el tiempo de cálculo de
descriptores obtenido tras realizar la función “compute” del método BRISK, que quedó
explicado en el cuarto apartado del segundo capítulo de esta memoria, “Descritor BRISK”.
Estos tiempos se logran como resultado de la operación anteriormente mencionada de
diferencia de tiempos.
Estos tiempos corresponden respectivamente, a haber tomado los umbrales de detección
previos.
En la segunda columna, con título “num_desc (rows)” se representa el número de
descriptores o, lo que es lo mismo, el número de filas de la matriz resultado.
En la tercera y última columna, se ha representado el número de elementos del vector de
puntos clave, es decir el número de puntos clave que se han detectado en el procedimiento.
En esta columna se comprueba que el tamaño del descriptor para el algoritmo BRISK se
toma fijo con valor de 64, como ya se ha indicado previamente.
Lo primero que se observa es que el número de descriptores obtenidos depende obviamente
94
del número de puntos clave detectados previamente, obteniendo menos descriptores si el
número de puntos clave es menor y viceversa.
También en este caso comprobamos que la característica es lineal y con pendiente positiva,
resultado razonable dado el objetivo del algoritmo.
Comparando los tiempos de detección y extracción, se observa que para altos valores de
puntos clave obtenidos, el valor de los tiempos de extracción y formación de descriptores son
considerablemente más altos que los de detección. Esto es debido a que a medida que
obtenemos más puntos clave, más veces se tiene que repetir el proceso de aplicar el patrón de
muestreo en el algoritmo BRISK.
Este patrón se aplica para identificar la dirección característica de cada punto clave y así
permitir obtener descriptores de orientación normalizada y por lo tanto lograr invariancia de
rotación. Todo esto quedó explicado en la teoría sobre el método BRISK en el segundo
capítulo de esta memoria.
En la siguiente gráfica, independientemente del valor del umbral escogido, se muestran los
tiempos de extracción por número de descriptores obtenidos. Para esta gráfica se han tenido
en cuenta los datos obtenidos en las 15 imágenes originales (768x1024).
95
Tabla 7: Gráfico de tiempos de extracción en el BeagleBone (768x1024)
Vemos por lo tanto la característica lineal de la gráfica y tenemos con ella una rápida
estimación del tiempo que va a requerir el algoritmo para calcularlos.
Se muestran ahora a continuación y para contrastar los primeros resultados, los tiempos de
extracción de descriptores para las imágenes escaladas al 50% de su tamaño, es decir, las
mismas imágenes representadas por 384x512 píxeles.
Para la primera foto origen escalada al 50% de su tamaño, y teniendo en cuenta que se
realizan los cálculos de nuevo sobre el BeagleBone, se tienen los siguientes resultados de
tiempos de extracción de descriptores:
0 500
1000 1500 2000 2500 3000 3500 4000 4500 5000 5500 6000 6500 7000 7500 8000
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Des
crip
tio
n_T
ime
(ms)
Num_Descriptors (en miles)
Thousands
Results1_BB (Descriptors)
96
Ilustración 35: Resultados de la extracción en el BeagleBone (384x512 píxeles)
Al igual que en el caso de la detección, se aprecia cómo el número de descriptores se ha
reducido para la imagen escalada al 50%, llegando al extremo de no obtener ningún
descriptor en el primero de los casos. Esto es consecuencia directa de obtener menos puntos
clave detectados en el primer paso del procedimiento y de haber reducido al 50% el tamaño
de esta imagen.
En cuanto a los valores de tiempos, éstos también se reducen debido a que el número de
puntos clave encontrados en el paso anterior fue menor y es necesario menor tiempo en la
comparación de patrones de muestreo, como anteriormente ya se ha mencionado.
En la siguiente gráfica, independientemente del valor del umbral escogido, se muestran los
tiempos de extracción por número de descriptores obtenidos. Para esta gráfica se han tenido
en cuenta los datos obtenidos en las 15 imágenes originales escaladas al 50% (382x512).
97
Tabla 8: Gráfico de tiempos de extracción en el BeagleBone (384x512)
Esta gráfica muestra una característica nuevamente lineal con una pendiente del 40%.
Con esto acabamos el estudio de tiempos de extracción en el dispositivo BeagleBone y
pasamos al del ordenador.
5.3.2. Resultados en el ordenador Intel
Se presenta a continuación otro fichero respuesta del programa detallado en el sexto anexo.
Este fichero representa de nuevo los tiempos de extracción, segunda fase del algoritmo
BRISK, pero esta vez sobre nuestro ordenador de desarrollo Intel. Se toma igualmente para
este ejemplo, la primera imagen original con tamaño 768x1024.
0 100 200 300 400 500 600 700 800 900
1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500
0 500 1000 1500 2000 2500 3000 3500 4000 4500 5000 5500 6000 6500 7000
Des
crip
tio
n_T
ime
(ms)
Num_Descriptors
Results1_50_BB (Descriptors)
98
Ilustración 36: Resultados de la extracción en el ordenador (768x1024 píxeles)
Se muestran ahora a continuación y para contrastar los primeros resultados, los tiempos de
extracción de descriptores para las imágenes escaladas al 50% de su tamaño, es decir, las
mismas imágenes representadas por 384x512 píxeles.
Para la primera foto origen escalada al 50% de su tamaño, y teniendo en cuenta que se
realizan los cálculos de nuevo sobre el ordenador Intel, se tienen los siguientes resultados de
tiempos de extracción:
Ilustración 37: Resultados de la extracción en el ordenador (384x512 píxeles)
99
Comparando estos resultados con los obtenidos por el dispositivo BeagleBone, obtenemos
esta vez un margen incluso más grande de diferencia entre los tiempos calculados por ambos
procesadores cuando nos acercamos a altos niveles de descriptores computados. Los tiempos
son un poco más grandes que un orden de magnitud para los obtenidos por el dispositivo
BeagleBone.
Con esto acabamos el estudio de tiempos de detección en el ordenador y pasamos al estudio
de tiempos de transmisión.
5.4. Tiempos obtenidos en la transmisión
En esta sección se detallan los tiempos conseguidos en el proceso de transmisión de
descriptores, desde el momento en que se envía el primero hasta el momento en el que se
recibe el último.
Para este cálculo, se han requerido nuevamente las funciones del protocolo NTP en nuestro
código, redactado en los anexos 7 y 8 de esta memoria.
Lo primero que ha sido necesario realizar es sincronizar los relojes de los dispositivos de
envío y de recepción. Esto ha quedado ya explicado en el apartado de “Configuración NTP”,
en el cuarto capítulo. Como fruto de esta sincronización NTP, ambos relojes quedan
compenetrados a nivel de décimas de milisegundos y podemos obtener, como ya se ha
mencionado, el offset o retraso de tiempos que se produce en la transmisión.
En cuanto al mecanismo utilizado en el código de envío y recepción, se usa la estructura
“ntptimeval” de la librería “sys/timex.h” como método más preciso para lograr este propósito.
La estructura “ntptimeval” contiene elementos o miembros que almacenan la hora del
sistema en fomato “Unix timeval” (palabras de 32-bits) y el error máximo y el esperado en
microsegundos con respecto a la fuente primaria de sincronización
Teniendo definida esta estructura en nuestro código, y los relojes de las máquinas
100
sincronizados previamente, se llama a la función “ntp_gettime” pasando como parámetro la
dirección de la estructura “ntptimeval” definida.
Esta llamada permite almacenar en la estructura los tres valores previamente definidos, uno
es el tiempo y los otros dos los errores. Dado que estos errores se pueden considerar
despreciables, no han sido considerados en el cálculo.
Esta función es utilizada en el programa de envío justo antes de comenzar la transmisión
como hemos dicho y en el programa de recepción justo después de recibir el último
descriptor.
El cálculo posterior sería así de simple:
Donde el es el tiempo obtenido al recibir el último descriptor mientras que
es el tiempo obtenido al comenzar a enviar.
Con este cálculo obtenemos los datos que posteriormente se describirán.
Para tener más variedad en el procedimiento, y a la vez aprovecharnos de las características
de las redes inalámbricas de sensores como se detalló en el primer capítulo, se han tenido en
cuenta 4 topologías. Estas nos permitirían por ejemplo, la ampliación de cobertura con más
dispositivos.
Topología A: conexión directa con cable Ethernet
Topología B: conexión directa con protocolo WiFi
Topología C: conexión indirecta con un salto con protocolo WiFi
Topología D: conexión indirecta con dos saltos con protocolo WiFi
101
Los esquemas o dibujos de estás topologías de red serán presentados según se vayan
explicando los resultados en los siguientes apartados.
Para tener una comparación más precisa, se usará en este caso, al igual que en apartado
anterior, una imagen precargada en el dispositivo para todas las realizaciones.
De esta imagen, una vez detectado los puntos clave y formado los descriptores, se obtiene
una matriz de 2378 filas por 64 columnas, o lo que es lo mismo, 2378 descriptores de 64
componentes cada uno.
Estos descriptores, como ya se ha comentado, se envían en paquetes de 10 en 10 descriptores,
lo que resulta en este caso, 237 paquetes de 10 descriptores más uno adicional de 8.
En total, el tamaño en bits de todos los paquetes es de:
Este dato se tendrá en cuenta a la hora de los cálculos.
5.4.1. Conexión directa con cable Ethernet
En el siguiente esquema se representa la primera topología (A) tomada en el laboratorio. Se
representan la cámara web, que realiza la captación de la imagen, conectada al dispositivo
BeagleBone, que realiza las tareas de detección y extracción, la unión mediante el cable de
red y el ordenador central que recibe los datos y los procesa adecuadamente.
Se representan también las direcciones IP estáticas que se han configurado en los
dispositivos para el procedimiento.
102
Ilustración 38: Topología con un BeagleBone (cable Ethernet)
En este caso, se usa un cable Ethernet como se ha comentado anteriormente, con una
velocidad teórica de hasta 10 Mb/s.
Después de realizar la media ponderada de los tiempos obtenidos en la transmisión en 10
realizaciones diferentes, el resultado medio del tiempo de transmisión es de:
Este cálculo se ha llevado a cabo mediante el procedimiento explicado al principio de este
capítulo para obtener los tiempos de transmisión.
Si calculamos la velocidad de transmisión efectiva del procedimiento nos resulta lo
siguiente:
Vemos que esta velocidad efectiva es menor a la velocidad teórica que se puede alcanzar,
debido a límites prácticos en la transmisión.
5.4.2. Conexión directa con protocolo WiFi
103
En el siguiente esquema se representa la segunda topología (B) tomada en el laboratorio. Se
representa la cámara web, conectada al dispositivo BeagleBone, la unión, que esta vez se
realiza mediante la tecnología WiFi y el ordenador central que recibe los datos mediante una
antena equipada con esta funcionalidad.
Se representan también de nuevo las direcciones IP estáticas, configuradas iguales a las del
apartado previo y la distancia entre ambos dispositivos.
Ilustración 39: Topología con un BeagleBone (WiFi)
En este caso, se usa la tecnología inalámbrica WiFi como se ha comentado anteriormente,
usando especificaciones del estándar 802.11g en concreto, con una velocidad teórica de hasta
54 Mb/s.
Después de realizar la media ponderada de los tiempos obtenidos en la transmisión en 10
realizaciones diferentes, el resultado medio del tiempo de transmisión es de:
Este cálculo se ha llevado a cabo mediante el procedimiento explicado al principio de este
capítulo para obtener los tiempos de transmisión.
Si calculamos la velocidad de transmisión efectiva del procedimiento nos resulta lo
104
siguiente:
Vemos que esta velocidad efectiva es menor a la velocidad teórica que se puede alcanzar,
debido a límites prácticos en la transmisión y a que en redes ad-hoc la velocidad queda muy
limitada con respecto a redes de infraestructura, en concreto se contempla un límite de 11
Mb/s.
5.4.3. Conexión indirecta con un salto con protocolo WiFi
En el siguiente esquema se representa la tercera topología (C) tomada en el laboratorio. Se
representa la cámara web, conectada al dispositivo BeagleBone, la unión, que se realiza
mediante la tecnología WiFi, un dispositivo BeagleBone que actúa como nodo de reenvío, y
el ordenador central que recibe los datos mediante una antena equipada con esta
funcionalidad.
El dispositivo BeagleBone de reenvío, ha tenido que ser configurado previamente para
reenviar los paquetes que le lleguen hacia el siguiente nodo. Esto se consigue mediante los
pasos descritos en el apartado “Configuración del nodo de reenvío” de la quinta sección del
capítulo cuarto de esta memoria.
Se representan también de nuevo las direcciones IP estáticas y la distancia entre los tres
dispositivos.
105
Ilustración 40: Topología con 2 BeagleBone (WiFi)
Después de realizar la media ponderada de los tiempos obtenidos en la transmisión en 10
realizaciones diferentes, el resultado medio del tiempo de transmisión es de:
Si calculamos la velocidad de transmisión efectiva del procedimiento nos resulta lo
siguiente:
Observamos el mismo efecto que en el ejemplo previo y cómo, en este ejemplo, la velocidad
efectiva de todo el proceso es menor, debido a que la distancia a recorrer ha sido mayor y se
ha llevado a cabo un salto en el proceso.
Hay que añadir que esta no es la velocidad media teniendo en cuenta cada tramo, o la
velocidad que restringe la comunicación, es la velocidad efectiva media de transmisión de
todo el envío.
106
5.4.4. Conexión indirecta con dos saltos con protocolo WiFi
En el siguiente esquema se representa la cuarta topología (D) tomada en el laboratorio. Se
representa la cámara web, conectada al dispositivo BeagleBone, la unión, que se realiza
mediante la tecnología WiFi, los dos dispositivos BeagleBone de reenvío y el ordenador
central que recibe los datos mediante una antena equipada con esta funcionalidad.
Se representan también de nuevo las direcciones IP estáticas y la distancia entre los 4
dispositivos.
Ilustración 41: Topología con tres BeagleBone
Después de realizar la media ponderada de los tiempos obtenidos en la transmisión en 10
realizaciones diferentes, el resultado medio del tiempo de transmisión es de:
107
Si calculamos la velocidad de transmisión efectiva del procedimiento nos resulta lo
siguiente:
En este caso vemos que la velocidad de transmisión vuelve a sufrir el mismo efecto debido a
un nuevo salto en la configuración y al aumento en la distancia.
Con esto se finalizan la descripción de los tiempos de transmisión, importantes para tener un
mayor entendimiento del tiempo global del proceso.
En el siguiente apartado se dan algunos comentarios sobre el paso restante.
5.5. Comentarios de tiempos de reconocimiento
Una vez obtenidos los tiempos previos, el único paso restante para acabar el modelo sería
calcular el tiempo de reconocimiento o matching de los descriptores en una base de datos de
imágenes, para por ejemplo, realizar tareas de reconocimiento de objetos.
Como ya se comentó en la teoría del segundo capítulo en cuanto al método BRISK, la
coincidencia o matching de dos descriptores BRISK requiere el cálculo de la distancia de
Hamming, que puede ser calculada de manera muy eficiente en arquitecturas de hoy en día
por medio de una operacion XOR bit a bit. Dos descriptores se dice que coinciden si su
distancia de Hamming es menor que un valor umbral predefinido .
Luego para llevar a cabo este mecanismo, tendríamos que implementar la base de datos de
imágenes, realizar el proceso de detección y descripción sobre ellas (que solo debe ser
realizado una vez al comienzo del ejercicio) y realizar el reconocimiento previamente
comentado.
Debido a la falta de tiempo en la realización práctica y a la variabilidad de estos tiempos
dependiendo del número de imágenes que se tomen como base de datos, no se han obtenidos
108
estos tiempos en esta memoria, y se deja como posible línea de futuro en esta investigación
habiendo indicado previamente cómo conseguirlos.
Con esto finaliza el quinto y último capítulo práctico de esta memoria del Proyecto Fin de
Carrera. Se han detallado los resultados obtenidos en todo el procedimiento de detección,
descripción y envío de descriptores a la vez que se han mostrado comentarios sobre el
posible reconocimiento de estos descriptores en el nodo central de la red inalámbrica de
sensores.
109
Capítulo 6
Conclusión y líneas futuras de estudio
Con este capítulo finaliza el desarrollo de la memoria de este Proyecto Fin de Carrera.
En cuanto al trabajo realizado, en este Proyecto se ha tenido en cuenta el problema de
referencia que se mencionó en el primer capítulo de la memoria para las redes inalámbricas
de sensores; y, conociendo este paradigma, se han llevado a cabo los objetivos propuestos de
estudiar y diseñar una solución factible de extracción de propiedades en redes visuales.
En particular, se ha descrito el diseño de la extracción de características eficaces, la
realización e implementación de la red de sensores y el cálculo de los tiempos del
procedimiento.
En cuanto a las conclusiones, podemos ver que se han obtenido unos tiempos razonables de
realización para aplicaciones domésticas, ligadas por ejemplo a aplicaciones prácticas de
domótica. Para un hardware económico, como es el dispositivo BeagleBone, llegamos a la
conclusión de que llevar a cabo aplicaciones de procesamiento digital de imágenes en una
red distribuida de sensores es una opción muy viable y con multitud de opciones y software
existente para su rápida implementación.
En cuanto a las posibles líneas futuras de estudio, se ha propuesto ya anteriormente la
implementación práctica del mecanismo de reconocimiento de descriptores en una base de
datos, una vez recibidos estos en el nodo final de la red. Este paso permitiría cerrar el círculo
del procedimiento mostrado en la memoria y llevar a cabo en la práctica un sistema que se
aprovechase de esta funcionalidad para, por ejemplo, reconocer óptimamente formas u
objetos en imágenes.
Un estudio interesante dentro del campo de la transmisión de descriptores sería optimizar el
tiempo de transmisión dependiendo del número de descriptores enviados en cada paquete.
110
También se podría comprobar la robustez a errores del método BRISK y sus limitaciones en
memoria.
En cuanto a los algoritmos de extracción de propiedades y cálculo de descriptores, sería
interesante hacer una comparativa de tiempos entre ellos, basándose en la diferencia entre
descriptores binarios en particular. Este es uno de los frentes de estudio que actualmente se
siguen realizando en el laboratorio donde se ha realizado la parte práctica de este Proyecto.
Igualmente, y sabiendo que la mayoría de estos algoritmos están implementados en librerías
de código libre, otro frente de estudio sería estudiar esta implementación para llevar a cabo
mejoras en el propio código o en el algoritmo en sí.
La extracción de propiedades fundamentales de imágenes y su envío sobre redes de sensores
es un campo amplio en el que aun se puede avanzar mucho y que dadas las múltiples
aplicaciones prácticas que posee, se trata de un campo interesante de investigación.
111
112
Bibliografía
• Capítulo 1: Introducción. Motivación y objetivos
[1] W. Dargie y C. Poellabauer, "Fundamentals of wireless sensor networks: theory and
practice", ed. John Wiley and Sons
[2] K. Sohraby, D. Minoli, T. Znati, "Wireless sensor networks: technology, protocols,
and applications”, ed. John Wiley and Sons
[3] Chai K. Toh, “Ad Hoc Mobile Wireless Networks: Protocols and Systems” (1ra
edición)
[4] A. Redondi, L. Baroffio, A. Canclini, M. Cesana, M. Tagliasacchi. “A Visual Sensor
Network for Object Recognition: Testbed Realization”
[5] K. Obraczka, R. Manduchi, J.J. Garcia-Luna-Aveces (Octubre 2002). "Managing the
Information Flow in Visual Sensor Networks"
[6] Soro S., Heinzelman W, “A Survey of Visual Sensor Networks, Advances in
Multimedia, vol. 2009”.
[7] E. Culurciello, J. H. Park, y A. Savvides, “Address-event video streaming over
wireless sensor networks”
[8] S. Paniga, L. Borsani, A. Redondi, M. Tagliasacchi, y M. Cesana, “Experimental
evaluation of a video streaming system for wireless multimedia sensor networks”
[9] M. Bramberguer, A. Doblander, A. Maier, B. Rinner, y H. Schwabach, “Distributed
embedded smart cameras for surveillance applications”
[10] P. Kulkarni, D. Ganesan, P. Shenoy, y Q. Lu, “Senseye: A multi-tier camera sensor
network”
[11] W. Schriebl, T. Winkler, A. Starzacher, y B. Rinner, “A pervasive smart camera
network architecture applied for multicamera object classification”
113
[12] T. Yan, D. Ganesan, y R. Manmatha, “Distributed image search in camera sensor
networks”
[13] D. G. Lowe, “Distinctive image features from scale-invariant keypoints”
[14] Antlab – Matteo Cesana: Visual Analysis in Wireless Sensor Network
http://antlab.elet.polimi.it/
[15] P. Gupta, P.R. Kumar, “The capacity of wireless networks”
[16] [Online]. http://www.asl.ethz.ch/people/lestefan/personal/BRISK
• Capítulo 2: Conceptos de teoría de imágenes
[17] Rafael C. Gonzalez, Richard E. Woods, “Digital Image Processing”
[18] Theodoridis, Sergios Koutroumbas, Konstantinos, “Pattern Recognition”
[19] Marco Marcon, apuntes de la asignatura “Video Signals”. Politécnico de Milán
[20] Leszek Cieplinski, “MPEG-7 Color Descriptors and Their Applications”
[21] E. Roster, R. Porter, y T. Drummond, “Faster and better: A machine learning
approach to corner detection”
[22] H. Bay, A. Ess, T. Tuytelaars, y L. J. V. Gool, “Speed-up robust features (surf)”
[23] Stefan Leutenegger, Margarita Chli y Roland Y. Siegwart, “BRISK: Binary Robust
Invariant Scalable Keypoints”
[24] C. Harris y M. Stephens, “A combined corner and edge detector” (1988)
[25] David G. Lowe , “Distinctive Image Features from Scale-Invariant Keypoints”
Capítulo 3: Tecnología usada
[26] [Online] Cross Compilations Tools:
http://www.airs.com/ian/configure/configure_5.html
114
[27] BeagleBoard website: http://beagleboard.org/
[28] BeagleBone RevA6, System Reference Manual:
http://beagleboard.org/static/beaglebone/latest/Docs/Hardware/BONE_SRM.pdf
[29] [Online] http://elinux.org/Beagleboard:BeagleBone#Rev_A6
[30] Distribución Ångström: http://www.angstrom-distribution.org/
[31] OpenCV website: http://opencv.org/
[32] Documentación de las interfaces de OpenCV: http://docs.opencv.org
[33] Network Time Protocol Proyect: http://www.ntp.org/
[34] Wireshark: http://www.wireshark.org/
[35] tcpdump: http://www.tcpdump.org/
Capítulo 4: Descripción del trabajo realizado
[36] [Online] Eclipse – descargas: http://www.eclipse.org/downloads/
[37] [Online] Ångström – toolchains: http://www.angstrom-distribution.org/toolchains/
[38] [Online] Librerías OpenCV: http://sourceforge.net/projects/opencvlibrary/
[39] [Online] Librerías OpenCV: https://github.com/Itseez/opencv
[40] [Online] Documentacion OpenCV 2.4.5:
http://docs.opencv.org/2.4.5/doc/user_guide/user_guide.html
115
116
Anexos
Anexo 1. Prueba de la realización del Proyecto
Anexo 2. Instalación de la cadena de herramientas
Anexo 3. Instalación y configuración de Eclipse CTD
Anexo 4. Instalación y configuración de librerías OpenCV
Anexo 5. Programa de re-escala de imágenes
Anexo 6. Programa de cálculo de tiempos del algoritmo BRISK
Anexo 7. Programa de obtención y envío de descriptores BRISK
Anexo 8. Programa de recepción de descriptores BRISK
117
Anexo 1. Prueba de la realización del Proyecto:
118
Anexo 2. Instalación de la cadena de herramientas
Dentro de este anexo se explica la instalación de la cadena de herramientas o “toolchain”
necesaria para llevar a cabo la compilación cruzada o “crosscompilation” de programas que
funcionarán en la arquitectura de un dispositivo BeagleBone.
Nos centramos ahora por lo tanto en la instalación de una cadena de herramientas de
Ångström para la arquitectura Armv7a. Esto nos permitirá, como hemos dicho, crear
programas que puedan ejecutarse en el BeagleBone.
En un navegador en el ordenador de desarrollo, vamos a la página de distribución de
toolchains del sistema operativo Ångström [38]. Para una cadena de herramientas que
funcione en un sistema Intel Pentium Dual CPU i686 (32-bits), seleccionamos el siguiente
archivo comprimido:
angstrom-2011.03-i686-linux-armv7a-linux-gnueabi-toolchain.tar.bz2
El nombre del fichero podría variar con el tiempo e incluso la página web de referencia
cambiar de dominio. Para sistemas de 64-bits seleccionar la opción con x86_64. Para incluir
soporte para el “Qt framework” con interfaz gráfica de usuario, seleccionar la opción “qte”.
Tomamos el archivo de 32 bits y no incluimos soporte para ese marco de desarrollo Qt.
En el cuadro de diálogo que aparece, seleccionar Save File (Guardar Archivo) y luego OK.
Ilustración 42: Descarga del toolchain
119
La localización por defecto para guardar archivos es:
- /home/username/Downloads/
“username” dependerá del nombre del usuario que se esté usando.
Abrimos una terminal de Ubuntu (buscando terminal en el cuadro de búsqueda de Ubuntu y
haciendo click en el icono que muestra Terminal)
Dentro de la terminal se llevan a cabo los siguientes comandos para extraer correctamente los
archivos:
ubuntu:~$ cd /
ubuntu:~$ sudo tar -xjvf /home/username/Downloads/angstrom-2011.03-i686-
linux-armv7a-linux-gnueabi-toolchain.tar.bz2
Con esto quedan localizados los archivos que se deben utilizar en la compilación cruzada
dentro de nuestro sistema de desarrollo. Es importante recordar dónde se han extraído estos
archivos para referenciarlos en la posterior configuración.
120
Anexo 3. Instalación y configuración de Eclipse CTD
En este anexo se explicarán tanto la instalación de Eclipse CTD como la configuración
correcta del mismo para incorporar las referencias y librerías necesarias para la compilación
cruzada.
La instalación de Eclipse en Ubuntu 12.04 es bastante sencilla y se puede realizar por ejemplo
de cualquiera de estas 3 formas:
1. Instalación desde el Centro de Software de Ubuntu
2. Instalación desde línea de comandos en una terminal:
ubuntu:~$ sudo apt-get install eclipse-cdt
3. Instalación desde la página web de descargas de Eclipse [36]
Ilustración 43: Centro de Software de Ubuntu
Cuando la instalación se completa, para ejecutar eclipse, basta abrir una terminal y escribir
“eclipse” (si la localización de eclipse no está en el PATH, se debe introducir el PATH
121
correcto, por ejemplo, /usr/bin/eclipse).
Si se muestra, seleccionar una carpeta de trabajo (workspace). La que viene por defecto
normalmente es:
- /home/username/workspace
Con esto tenemos instalado y ejecutado nuestro entorno de desarrollo y procedemos ahora a
configurarlo apropiadamente.
Con Eclipse instalado y ejecutándose, procedemos a crear y configurar un proyecto. Para
ello seleccionamos: File New Project
Ilustración 44: Crear nuevo proyecto
En la ventana de New Project, seleccionamos C/C++, luego C++ Project, y luego Next >.
122
Ilustración 45: Ventana de Nuevo Proyecto
Introducimos el nombre del proyecto y hacemos click en Finish.
Una vez hecho esto, el siguiente paso es cambiar las opciones de “Build configurations”, que
dicen a Eclipse cómo realizar la compilación cruzada del proyecto para el BeagleBone.
En Project Explorer, hacer click derecho en el nombre del proyecto y seleccionar Build
Configurations Manage…
Ilustración 46: Build Configurations
123
Hacer click en New para crear una configuración para la compilación cruzada.
Ilustración 47: Configuración de compilación
En el cuadro Name, introducir el nombre de la configuración (bb_debug). Debajo de Copy
settings from, seleccionar Existing configuration y Debug.
Ilustración 48: Crear nueva configuración
Hacer click en OK dos veces para volver al proyecto.
En Project Explorer, hacer click derecho en el nombre del proyecto y seleccionar Properties.
124
Ilustración 49: Seleccionar propiedades del proyecto
En la pestaña de C/C++ Build, hacer click en la flecha para expandir las opciones y luego
pinchar en Settings.
Ilustración 50: Propiedades del proyecto
En el cuadro Configuration, seleccionar bb_debug. Hacer click en GCC C Compiler, y
escribimos lo siguiente en el cuadro de texto Command:
- /usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-gcc
125
Que es el PATH hacia el arm-angstrom-linux-gnueabi-gcc donde previamente hemos
descomprimido los archivos en la primera parte de esta sección.
Ilustración 51: Propiedades del compilador cruzado
Bajo GCC C Compiler, hacer click en Includes. En la ventana de Include paths (-I) (la de
arriba del todo), hacer click en el icono con una flecha para añadir una ruta del directorio.
Añadir:
- /usr/local/angstrom/arm/arm-angstrom-linux-gnueabi/usr/include
Y seleccionar OK.
126
Ilustración 52: Ruta de directorio hasta ficheros include
Debajo de GCC C Linker, hacer click en Libraries. En la ventana de Library search parth
(-L) (la de abajo), hacer click en el icono con una flecha para añadir una ruta de directorio.
Añadir:
- /usr/local/angstrom/arm/arm-angstrom-linux-gnueabi/lib
Ilustración 53: Librerías de enlazado
Hacer click en OK, y con esto tenemos incluida la ruta hacia las librerías necesarias para el
127
enlazado en la compilación cruzada.
Después de esto, hacer click en GCC Assembler y reemplazar el texto en el cuadro de
Command con:
- /usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-as
Ilustración 54: Propiedades del ensamblador
Y hacer click en OK.
En Project Explorer, hacemos click derecho en el nombre del proyecto y seleccionamos
Build Configurations Set Active y luego bb_debug para cambiar a la configuración que
acabamos de crear.
128
Ilustración 55: Seleccionar la configuración de compilación
Con esto, tenemos configurada la compilación cruzada en el entorno de desarrollo. Basta
cambiar el último punto y seleccionar Debug, para cambiar a la configuración inicial.
129
Anexo 4. Instalación y configuración de librerías OpenCV
Teniendo Eclipse instalado en la estación de trabajo con el plug-in para desarrolladores de
C/C++ procedemos a descargar e instalar las librerías de OpenCV. Éstas se pueden obtener de
dos maneras diferentes:
1. Desde la página web de Sourceforge [38]
2. Desde el repositorio Git que mantiene OpenCV [39]
Es necesario como prerrequisitos, instalar los siguientes paquetes:
• GCC 4.4.x o superior. Este puede ser instalado con:
ubuntu:~$ sudo apt-get install build-essential
CMake 2.6 o superior;
Git;
• GTK+2.x o superior, incluyendo las cabeceras (libgtk2.0-dev);
• pkg-config;
• Python 2.6 o superior y Numpy 1.5 o superior con paquetes de desarrollador (python-dev,
python-numpy);
• Paquetes de desarrollo ffmpeg o libav: libavcodec-dev, libavformat-dev, libswscale-dev;
• [opcional] libdc1394 2.x;
• [opcional] libjpeg-dev, libpng-dev, libtiff-dev, libjasper-dev.
Todas las librerías de arriba se pueden instalar por medio de la Terminal o usando Synaptic
Manager.
Se compilan ahora las librerías de la siguiente forma:
1. Creamos un directorio temporal, donde queremos poner los Makefiles, ficheros del
proyecto y también los ficheros objeto y los binarios de salida generados.
ubuntu:~$ cd ~/opencv
ubuntu:~$ mkdir release
130
ubuntu:~$ cd release
ubuntu:~$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
2. Dentro del directorio temporal realizar lo siguiente para la compilación e instalación:
ubuntu:~$ make
ubuntu:~$ sudo make install
Solo nos queda un último paso para poder usar estas librerías, decirle a Eclipse donde están las
librerías y cabeceras con el mismo procedimiento que en la sección anterior.
Para ello, realizamos lo siguiente:
Hacemos click en Project Properties. Luego, seleccionamos C/C++ Build, y hacemos
click en Settings. A la derecha, elegir la sección Tool Settings. Aquí es donde introducimos la
información de las librerías y las cabeceras como hicimos antes.
En GCC C++ Compiler Includes Include paths (-I) se debe introducir la ruta hacia la
carpeta donde se instaló OpenCV. En este Proyecto fue en el directorio:
- /usr/local/include/opencv.
Ilustración 56: Configuración del compilador para OpenCV
Para localizar esta ruta de directorio fácilmente, es útil el siguiente comando:
ubuntu:~$ pkg-config --cflags opencv
En la figura previa, en la opción de Configuration, nos aseguramos de que esté seleccionado
bb_debug, para que se apliquen los cambios a la configuración creada previamente para la
compilación cruzada.
131
Siguiendo con GCC C++ Linker, tenemos que rellenar dos espacios:
1. Library search path (-L): escribir la ruta donde residen las librerías de OpenCV. En el
caso de este Proyecto, se trata de:
- /usr/local/lib
2. Libraries (-I): añadir las librerías de OpenCV que se puedan necesitar en el código que
vayamos a escribir. Normalmente las 3 primeras de abajo son las más usadas (en
aplicaciones simples). En cualquier caso, para este Proyecto las añadimos todas para no
tener problemas de compatibilidad.
opencv_core opencv_imgproc opencv_highgui opencv_ml
opencv_video opencv_features2d opencv_calib3d opencv_objdetect
opencv_contrib opencv_legacy opencv_flann
Ilustración 57: Librerías de enlazado para OpenCV
Para comprobar la ruta hacia las librerías, se puede introducir el siguiente comando en la
terminal de Ubuntu:
ubuntu:~$ pkg-config --libs opencv
Con esto, queda configurado apropiadamente el entorno de desarrollo para una compilación
132
cruzada para el BeagleBone y usando librerías OpenCV.
133
Anexo 5. Programa de re-escala de imágenes
/*
* resizing.cpp
*
* Created on: 27/mag/2013
* Author: Pablo Chacón Carrión
* Description: Programa que re-escala y salva una imagen
*/
#include <iostream>
#include <opencv2/opencv.hpp>
#include "cv.h"
#include "highgui.h"
using namespace std;
int main( int argc, char** argv )
{
// Creamos un objeto IplImage origen
IplImage *source = cvLoadImage("all_souls_14.jpg");
// Aquí declaramos el valor de los porcentuales como enteros
int percent1 = 10;
int percent2 = 25;
int percent3 = 50;
int percent4 = 75;
int percent5 = 90;
// Objeto IplImage de destino con ancho, alto y número de canales
IplImage *destination1 = cvCreateImage( cvSize((int)((source-
>width*percent1)/100) , (int)((source->height*percent1)/100) ), source-
>depth, source->nChannels );
IplImage *destination2 = cvCreateImage( cvSize((int)((source-
>width*percent2)/100) , (int)((source->height*percent2)/100) ), source-
>depth, source->nChannels );
IplImage *destination3 = cvCreateImage( cvSize((int)((source-
>width*percent3)/100) , (int)((source->height*percent3)/100) ), source-
>depth, source->nChannels );
IplImage *destination4 = cvCreateImage( cvSize((int)((source-
>width*percent4)/100) , (int)((source->height*percent4)/100) ), source-
>depth, source->nChannels );
IplImage *destination5= cvCreateImage( cvSize((int)((source-
>width*percent5)/100) , (int)((source->height*percent5)/100) ), source-
>depth, source->nChannels );
// Se usa cvResize para cambiar la escala
cvResize(source, destination1);
cvResize(source, destination2);
cvResize(source, destination3);
cvResize(source, destination4);
cvResize(source, destination5);
// Se guarda la imagen
cvSaveImage( "all_souls_14_res10.jpg", destination1 );
134
cvSaveImage( "all_souls_14_res25.jpg", destination2 );
cvSaveImage( "all_souls_14_res50.jpg", destination3 );
cvSaveImage( "all_souls_14_res75.jpg", destination4 );
cvSaveImage( "all_souls_14_res90.jpg", destination5 );
return 0;
}
typedef struct _IplImage {
int nSize;
int ID;
int nChannels;
int alphaChannel;
int depth;
char colorModel[4];
char channelSeq[4];
int dataOrder;
int origin;
int align;
int width;
int height;
struct _IplROI* roi;
struct _IplImage* maskROI;
void* imageId;
struct _IplTileInfo* tileInfo;
int imageSize;
char* imageData;
int widthStep;
int BorderMode[4];
int BorderConst[4];
char* imageDataOrigin;
} IplImage;
135
Anexo 6. Programa de cálculo de tiempos del algoritmo BRISK
/*
* TimeBrisk.cpp
*
* Created on: 02/giu/2013
* Author: Pablo Chacón Carrión
*/
#include <fstream>
#include <list>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <stdio.h>
#include "../include/brisk/brisk.h"
#include <string.h>
#include <boost/lexical_cast.hpp>
//#include "cv.h"
//#include "highgui.h"
using namespace std;
using namespace cv;
#define OCT 3
#define NUM_IMAGENES 15
int main(int argc, char ** argv)
{
// vector de puntos claves
vector<KeyPoint> objectKeypoints;
// Matriz de descriptores
Mat objectDescriptors;
// La imagen que leemos guardada previamente
Mat imagen;
double desc_time = 0, det_time = 0;
// Umbral de detección
int thresh = 0;
int octaves = OCT;
// Número de keypoints que se detectan
int tam_keypoints = 0;
// Nombre del fichero de la foto
string fname;
int i = 0;
// Nombres de los ficheros donde se guardan los resultados
string resDet,resDesc;
Ptr<FeatureDetector> detector;
Ptr<DescriptorExtractor> extractor;
cout << "creating extractor..." << endl;
extractor = new BriskDescriptorExtractor();
cout<< "done"<< endl;
for(i = 1; i< NUM_IMAGENES+1; i++){
if(i<10){
136
fname = "all_souls_0"+
boost::lexical_cast<std::string>(i)+ "_res90.jpg";
// Se crean los ficheros de resultados
resDet = "results/detector_0" +
boost::lexical_cast<std::string>(i) + "_det_time_res90.txt";
resDesc = "results/extractor_0" +
boost::lexical_cast<std::string>(i) + "_desc_time_res90.txt";
}
else{
fname = "all_souls_"+
boost::lexical_cast<std::string>(i) + "_res90.jpg";
// Se crean los ficheros de resultados
resDet = "results/detector_" +
boost::lexical_cast<std::string>(i) + "_det_time_res90.txt";
resDesc = "results/extractor_" +
boost::lexical_cast<std::string>(i) + "_desc_time_res90.txt";
}
imagen = imread(fname, -1);
CV_Assert( !imagen.empty()); // Error si no hay imagen
// Convertir a escala de grises
Mat imgGray;
cvtColor(imagen, imgGray, CV_BGR2GRAY);
cout << resDet.c_str() << endl;
ofstream resFileDet;
ofstream resFileDesc;
resFileDet.open(resDet.c_str(), ofstream::out);
resFileDesc.open(resDesc.c_str(), ofstream::out);
// Formato de los ficheros de resultados
resFileDet << "threshold" << '\t' << "det_time (ms)" << '\t'
<< "tam_keypoints" << '\t'<< endl;
resFileDesc << "desc_time (ms)" << '\t' << "num_descr (rows)";
resFileDesc << '\t' << "tam_descr (cols)" << endl;
// Comprobar tiempos para diferentes valores de umbral
for(int thresh = 120; thresh>=20; thresh-=10){
cout << "Fichero: "<< i << "\t" << "Threshold: " <<
thresh << endl;
detector = new BriskFeatureDetector(thresh, octaves);
det_time = (double)getTickCount();
detector->detect(imagen, objectKeypoints);
det_time = ((double)getTickCount() -
det_time)/getTickFrequency();
tam_keypoints = objectKeypoints.size();
desc_time = (double)getTickCount();
extractor->compute(imagen, objectKeypoints,
objectDescriptors);
desc_time = ((double)getTickCount() -
desc_time)/getTickFrequency();
// Escribir en el fichero
resFileDet << thresh << '\t' << '\t' << det_time*1000 <<
'\t' << '\t'<< tam_keypoints << endl;
137
resFileDesc << desc_time*1000 << '\t' << '\t' <<
objectDescriptors.rows << '\t' << '\t' << objectDescriptors.cols <<
endl;
}
// Cerrar ficheros
resFileDet.close();
resFileDesc.close();
}
// Liberar los recursos
objectDescriptors.release();
return 0;
}
138
Anexo 7. Programa de obtención y envío de descriptores BRISK
/*
* AdquireImage.cpp
*
* Created on: 03/giu/2013
* Author: Pablo Chacón Carrión
*/
#include <iostream>
#include <opencv2/opencv.hpp>
//#include "cv.h"
#include <stdio.h>
#include "../include/brisk/brisk.h"
//#include "highgui.h"
#include <string.h>
#include "Communication.hpp"
using namespace std;
int main(int argc, char ** argv)
{
CvCapture * pCapture = 0;
IplImage * pVideoFrame = 0;
int i = 0;
char filename[50];
// Inicializar video de captura
// 0 para web cam interna, 1 para web cam usb...
pCapture = cvCaptureFromCAM( 1 );
if( !pCapture )
{
fprintf(stderr, "Ocurrió un fallo en el momento de iniciar la
captura de video.\n");
return -1;
}
// La función cvQueryFrame obtiene una trama desde la cámara,
// la descomprime y la devuelve
pVideoFrame = cvQueryFrame( pCapture );
if(!pVideoFrame)
{
fprintf(stderr, "Ocurrió un fallo al capturar la imagen");
cvReleaseCapture( &pCapture );
return -1;
}
// Guarda el cuadro de imagen del video capturado como un archivo
// imagen
sprintf(filename, "CuadroImagen%d.jpg", i+1);
if( !cvSaveImage(filename, pVideoFrame,0))
{
139
fprintf(stderr, "Ocurrió un error al momento de guardar el
archivo %s\n", filename);
}
/*
// Otro modo de hacerlo
if (!cvGrabFrame(pCapture)){
// Captura
fprintf(stderr,"Could not grab a frame\n");
exit(0);
}
pVideoFrame = cvRetrieveFrame(pCapture);
cvSaveImage("imagePrueba.jpg",pVideoFrame);
*/
vector<KeyPoint> objectKeypoints;
// Estos son los descriptores que posteriormente enviamos
Mat objectDescriptors;
Mat imagen = imread(filename, IMREAD_COLOR);
CV_Assert( !imagen.empty()); // error si no hay imagen
// Constructor del descriptor BRISK
// Binary Robust Invariant Scalable Keypoints
// Atributos: threshold, octaves, patternScale
int thresh = 30;
int octaves = 3;
// float patternScale = 1.0f;
/* Esta parte funciona bien con el compilador normal y las librerías
de OpenCV 2.4.3
Ptr<BRISK> BRISKD = new BRISK(thresh, octaves, patternScale);
// Se hace la operación de extracción de keypoints y de
descriptores
// La máscara (mask - segundo parámetro) se ha dejado en blanco
BRISKD->operator ()(imagen, noArray(),objectKeypoints,
objectDescriptors, false);
*/
cv::Ptr<cv::FeatureDetector> detector;
cv::Ptr<cv::DescriptorExtractor> extractor;
cout << "creating extractor..." << endl;
extractor = new cv::BriskDescriptorExtractor();
cout << "done" << endl;
detector = new cv::BriskFeatureDetector(thresh, octaves);
detector->detect(imagen, objectKeypoints);
extractor->compute(imagen, objectKeypoints, objectDescriptors);
printf("Object: %d keypoints detected\n",(int)
objectKeypoints.size());
printf("Object: %d descriptors extracted (rows)\n",
objectDescriptors.rows);
140
printf("Object: %d descriptors extracted (cols)\n",
objectDescriptors.cols);
/*
//imprimir valores de la matriz de descriptores
printf("El valor del (1,0) descriptor es:
%u\n",objectDescriptors.data[64]);
printf("El valor del (1,1) descriptor es:
%u\n",objectDescriptors.data[65]);
*/
// Llamada a la función que establece la comunicación
communication(objectDescriptors);
// Termina la captura de video y libera recursos
objectDescriptors.release();
cvReleaseCapture( &pCapture );
return 0;
}
/*
* Communication.hpp
*
* Created on: 03/06/2013
* Author: Pablo Chacón Carrión
*/
#ifndef COMMUNICATION_HPP_
#define COMMUNICATION_HPP_
using namespace std;
using namespace cv;
void error_fatal (string mens);
void communication(Mat objectDescriptors);
#endif /* COMMUNICATION_HPP_ */
141
/*
* Communication.cpp
*
* Created on: 03/giu/2013
* Author: Pablo Chacón Carrión
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
//#include "cv.h"
//#include "highgui.h"
#include "Communication.hpp"
#include <string.h>
#include <sys/time.h>
#include <sys/timex.h>
#include <sys/types.h>
#define MAX_DESCRIPTORES 10
#define TAM_DESCRIPTOR 64
#define NUM_PUERTO 20133
#define IP "10.42.0.1"
void error_fatal (string mens)
{
// perror(mens.c_str());
exit(1);
}
// Función que recibe descriptores y realiza la comunicación con ellos
void communication(Mat objectDescriptors){
int s = 0; // descriptor del socket
struct sockaddr_in iserv; // dirección de internet remota
int puerto = NUM_PUERTO; // puerto del servicio
int cc = 0;
Mat tmp(MAX_DESCRIPTORES, TAM_DESCRIPTOR, 0, 0);
int* ptr = NULL; // puntero auxiliar para enviar las matrices
int n_fils = objectDescriptors.rows;
int i = 0;
int usado = 0; // 0 si no se ha usado, 1 si sí se ha usado
// Estructura de los tiempos obtenidos por el protocolo ntp
struct ntptimeval send_time;
// Abrimos el socket UDP de datagramas de Internet
if((s= socket (AF_INET, SOCK_DGRAM, 0)) < 0)
error_fatal("socket");
142
// Prepara el nombre remoto
memset(&iserv,0,sizeof(iserv));
// Dirección tipo INTERNET
iserv.sin_family = AF_INET;
// El primer argumento
if(inet_pton(AF_INET, IP, &iserv.sin_addr)!=1)
error_fatal("address name");
iserv.sin_port = htons(puerto);
cout << "La matriz es: " << endl << objectDescriptors << endl;
// Si tenemos menos de MAX_DESCRIPTORES
if(n_fils < MAX_DESCRIPTORES){
ptr = (int*)&(objectDescriptors.at<uchar>(0));
if(usado == 0){
if(ntp_gettime(&send_time))
perror("ntp_gettime");
usado = 1;
}
// Se envían los descriptores de una sola vez
cc = sendto(s, ptr, (n_fils*MAX_DESCRIPTORES)*sizeof(int),
0,(struct sockaddr *)&iserv, sizeof(iserv));
if(cc < 0)
error_fatal("sendto1");
// Tenemos más de MAX_DESCRIPTORES
}else{
// Las filas son múltiplo del número de descriptores que enviamos
if(n_fils%MAX_DESCRIPTORES == 0){
// Mientras que haya filas, enviamos
while(i<n_fils){
// Guardamos la parte que nos interesa de los
// Descriptores en la matriz auxiliar
tmp =
objectDescriptors.colRange(0,TAM_DESCRIPTOR).rowRange(i,i+MAX_DESCRIPTOR
ES);
ptr = (int*)&(tmp.at<uchar>(0));
// cout << "La matriz tmp es: " << endl << tmp <<
endl;
if(usado == 0){
if(ntp_gettime(&send_time))
perror("ntp_gettime");
usado = 1;
}
// Se envían los descriptores
cc = sendto(s, ptr,
MAX_DESCRIPTORES*TAM_DESCRIPTOR*sizeof(int), 0,(struct sockaddr
*)&iserv, sizeof(iserv));
if (cc < 0)
143
error_fatal("sendto2");
i+=MAX_DESCRIPTORES;
}
}else{
// Si las filas no son múltiplo, lo más normal, tenemos que
// enviar la ultima vez un número menor
while(i<n_fils){
// Si nos quedan más de MAX_DESCRIPTORES filas,
// enviamos normalmente
if(n_fils-i >= MAX_DESCRIPTORES){
tmp =
objectDescriptors.colRange(0,TAM_DESCRIPTOR).rowRange(i,i+MAX_DESCRIPTOR
ES);
ptr = (int*)&(tmp.at<uchar>(0));
// cout << "La matriz tmp es: " << endl << tmp <<
endl;
if(usado == 0){
if(ntp_gettime(&send_time))
perror("ntp_gettime");
usado = 1;
}
// Se envían los descriptores
cc = sendto(s, ptr,
MAX_DESCRIPTORES*TAM_DESCRIPTOR*sizeof(int), 0,(struct sockaddr
*)&iserv, sizeof(iserv));
if (cc < 0)
error_fatal("sendto2");
}else{
// Enviamos las restantes
tmp =
objectDescriptors.colRange(0,TAM_DESCRIPTOR).rowRange(i,n_fils);
ptr = (int*)&(tmp.at<uchar>(0));
cout << "La matriz tmp final es: " << endl <<
tmp << endl;
cc = 0;
// Se envían los descriptores
cc = sendto(s, ptr, (n_fils-
i)*TAM_DESCRIPTOR*sizeof(int), 0,(struct sockaddr *)&iserv,
sizeof(iserv));
cout << "Se han enviado :"<< cc/sizeof(int) <<
" descriptores" << endl;
if (cc < 0)
error_fatal("sendto3");
}
i+= MAX_DESCRIPTORES;
} // Fin del while
}
} // Fin del else de la comprobación del número de descriptores
// Fin del envío
144
cout << "Tiempo inicial (se empieza a enviar) (sg):" <<
send_time.time.tv_sec << endl;
cout << "Tiempo inicial (se empieza a enviar) (usg):" <<
send_time.time.tv_usec << endl;
printf("El tiempo es : %ld.%06ld\n", send_time.time.tv_sec,
send_time.time.tv_usec);
printf("El tiempo es (usec) : %06ld\n", send_time.time.tv_usec);
if (close(s) <0) /*Cerramos el socket*/
error_fatal("close");
}
145
Anexo 8. Programa de recepción de descriptores BRISK
/*
* RecieveImage.cpp
*
* Created on: 06/06/2013
* Author: Pablo Chacón Carrión
* Info: Programa de recepción de los descriptores de la imagen
*/
#include <iostream>
//#include "cv.h"
//#include "highgui.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "../include/brisk/brisk.h"
#include <opencv2/opencv.hpp>
#include <sys/time.h>
#include <sys/timex.h>
#include <sys/types.h>
// Tamaño de los descriptores, columnas de la matriz
#define TAM_DESCRIPTOR 64
// Número máximo de descriptores que va a recibir
#define MAX_DESCRIPTORES 10
// Tamaño del descriptor tipo BRISK que se recibe
#define TAM_DESCRIPTOR 64
#define PLAZO 50 // plazo de recepción
#define NUM_PUERTO 20133 // número de puerto de la comunicación UDP
using namespace cv;
using namespace std;
void error_fatal (string mens)
{
perror(mens.c_str());
exit(1);
}
// Función de temporizador de la espera del servidor
int recibido_en_plazo (int descriptor, int segundos)
{
struct timeval plazo;
fd_set readfds;
plazo.tv_sec = segundos;
plazo.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(descriptor, &readfds);
return select(descriptor+1,
&readfds,
(fd_set *)NULL,
(fd_set *)NULL,
146
&plazo) != 0;
}
int main(int argc, char ** argv){
// Tampón de recepción
uchar buf[TAM_DESCRIPTOR*MAX_DESCRIPTORES];
int puerto = NUM_PUERTO;
int s = 0; // Descriptor del socket
struct sockaddr_in iyo; // Dirección de internet local
struct sockaddr_in iclnt; // Dirección de internet remota
socklen_t len; // longitud de la estructura sockaddr_in
int cc; // número de caracteres leídos o escritos
// IP del cliente como cadena de caracteres
char ipcli[INET_ADDRSTRLEN];
// Contador de los paquetes que llegan
int a = 0;
Mat tmp(MAX_DESCRIPTORES, TAM_DESCRIPTOR, 0, 0);
int i = 0;
// Estructura de los tiempos obtenidos por el protocolo ntp
struct ntptimeval recieve_time;
memset(buf,0,MAX_DESCRIPTORES*TAM_DESCRIPTOR);
memset(&recieve_time,0,sizeof(struct ntptimeval));
if((s= socket (AF_INET, SOCK_DGRAM, 0)) < 0)
error_fatal("socket");
memset(&iyo,0,sizeof(iyo));
iyo.sin_family = AF_INET; // Dirección de tipo INTERNET
iyo.sin_addr.s_addr = htonl(INADDR_ANY);
iyo.sin_port = htons(puerto); // Puerto especificado
if(bind(s, (struct sockaddr *)&iyo, sizeof(iyo)) < 0)
error_fatal("bind");
for (;;) {
/* El servidor solo finaliza cuando pasa el plazo sin recibir
nada, por eso a partir de ahora no se usa la función error_fatal */
if (recibido_en_plazo(s, PLAZO)) {
a++;
len= sizeof(iclnt);
/* recibe */
memset(buf,0,MAX_DESCRIPTORES*TAM_DESCRIPTOR);
cc= recvfrom(s, buf, sizeof(buf), MSG_TRUNC, (struct
sockaddr *)&iclnt, &len);
if(ntp_gettime(&recieve_time))
perror("ntp_gettime");
if (cc < 0)
perror("recvfrom");
// Ignoramos este mensaje y esperamos otro
else{
147
if (NULL!= inet_ntop(AF_INET, &iclnt.sin_addr,
ipcli, sizeof(ipcli))){
cout << "Paquete número: " << a << endl;
cout << "Desde " << ipcli << ": "<<
ntohs(iclnt.sin_port);
cout << " recibido: {" ;
cout << "El valor de cc es igual a:" <<
cc/sizeof(int) << endl;
for(i=0; i< (cc/(int)sizeof(int)); i++){
cout << (int)buf[i] << ", ";
}
cout << "}" << endl;
}
}
}else{
printf("*** no oigo nada ***\n");
break; // Salimos del bucle
}
cout << "Tiempo final (cuando todos los descriptores se han
recibido) (sg):" << (int)recieve_time.time.tv_sec << endl;
cout << "Tiempo final (cuando todos los descriptores se han
recibido) (usg):" << (suseconds_t)recieve_time.time.tv_usec << endl;
printf("El tiempo es : %ld.%06ld\n",
recieve_time.time.tv_sec, recieve_time.time.tv_usec);
printf("El tiempo es (usec) : %06ld\n",
recieve_time.time.tv_usec);
}
if (close(s) <0) /*Cerramos el socket*/
error_fatal("close");
return 0;
}
148