• No se han encontrado resultados

Sistema de co-pilotaje autónomo para la navegación en entornos de interior mediante mapas topológicos visuales

N/A
N/A
Protected

Academic year: 2021

Share "Sistema de co-pilotaje autónomo para la navegación en entornos de interior mediante mapas topológicos visuales"

Copied!
52
0
0

Texto completo

(1)ESCUELA TÉCNICA SUPERIOR DE INGENIEROS INFORMÁTICOS UNIVERSIDAD POLITÉCNICA DE MADRID. TESIS DE MASTER MASTER EN INTELIGENCIA ARTIFICIAL. SISTEMA DE CO-PILOTAJE AUTÓNOMO PARA LA NAVEGACIÓN EN ENTORNOS DE INTERIOR MEDIANTE MAPAS TOPOLÓGICOS VISUALES. AUTOR: CARLOS GARCÍA HUERTA TUTORES: DARÍO MARAVALL, JAVIER DE LOPE. JULIO, 2016.

(2) Resumen Existe una gran variedad de enfoques para resolver el problema de la localización y orientación en el entorno. Muchos enfoques dependen en mayor o menor medida de información externos al usuario. En este trabajo se va a desarrollar un sistema de localización basado únicamente en imágenes del entorno. Para ello nos hemos basado en un algoritmo de reconocimiento y clasificación de imágenes implementado sobre un mapa topológico. Para el reconocimiento se ha utilizado el algoritmo k-nearest neighbour, utilizando el histograma normalizado de las imágenes como caracterı́stica a diferenciar. El mapa topológico se ha construido sobre el terreno de pruebas, en este caso el Departamento de Inteligencia Artificial de la Escuela Técnica Superior de Ingenieros Informáticos de la Universidad Politécnica de Madrid. Se podrá ver al realizar las pruebas dinámicas que los resultados son bastante satisfactorios.. i.

(3) Abstract There is a wide variety of approaches to solve the issue of localization and orientation in an environment. Many of these approaches depend to a greater or lesser degree in information that is external to the user. In this work a localization system based only in imagenes from the environmente will be developed. To that end we have used a image classification algoritm implemented on a topological map. The classification algorithm used is a k-nearest neighbour, using the normalized histogram from the images as the characteristic to identify. The topological map has been built from the testing grounds, which is in this case the Departament of Artificial Intelligence of the Escuela Técnica Superior de Ingenieros Informáticos from the Universidad Politécnica de Madrid. It can be seen that the results shown when performing dynamic testing are promising.. ii.

(4) Índice general 1 Introducción. 1. 2 Fundamentos de los mapas topológicos visuales 2.1 Grafos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Mapas Topológicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 4 4 4. 3 Construcción supervisada de mapas topológicos visuales 3.1 Construccion del grafo . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Obtención de los nodos visuales . . . . . . . . . . . . . . . . . . . . . .. 7 7 14. 4 Diseño y evaluación del reconocedor de landmarks 4.1 Elección de caracterı́sticas y algoritmo . . . . . . . . . . . . . . . . . . 4.2 Construcción del set de entrenamiento . . . . . . . . . . . . . . . . . . 4.3 Pruebas estáticas del dataset . . . . . . . . . . . . . . . . . . . . . . . .. 16 16 19 20. 5 Integración y pruebas operativas dinámicas 5.1 Integración del dataset y el algoritmo en el mapa 5.2 Pruebas dinámicas . . . . . . . . . . . . . . . . . 5.2.1 Recorrido 1 . . . . . . . . . . . . . . . . . 5.2.2 Recorrido 2 . . . . . . . . . . . . . . . . . 5.2.3 Recorrido 3 . . . . . . . . . . . . . . . . .. 24 24 28 33 34 35. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. 6 Conclusiones. 36. A Portabilidad a Android A.1 main.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.2 mapa.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.3 classcamera.kv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 38 40 44 45. iii.

(5) Índice de figuras 2.1 2.2. Ejemplo de grafo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ejemplo de mapa topológico. Imagen obtenida de [7] . . . . . . . . . .. 5 6. 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10. Plano simplificado del DIA . . . . . . . . . . . . . . . . . . . . . . . . . Zona accesible en lı́nea recta desde el primer nodo (azul) . . . . . . . . Zona accesible tras eliminar retrocesos . . . . . . . . . . . . . . . . . . Opciones para colocar el nodo número 2 . . . . . . . . . . . . . . . . . Muestra de la necesidad de un nodo intermedio . . . . . . . . . . . . . Elección del nodo número 2 . . . . . . . . . . . . . . . . . . . . . . . . Elección del nodo número 4 . . . . . . . . . . . . . . . . . . . . . . . . Elección del nodo número 5 . . . . . . . . . . . . . . . . . . . . . . . . Mapa completo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fotografı́a de muestra e histograma de: a) Nodos 1 y 2; b) Nodos 3 y 4; c) Nodos 5 y 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 8 9 9 10 10 11 11 12 13. 4.1 4.2 4.3 5.1 5.2 5.3. Ejemplo de Histograma . . . . . . . . . . . . Ejemplo del algoritmo k-nn . . . . . . . . . a) Imagen original; b) Imagen en escala de Histograma normalizado . . . . . . . . . . .. . . . . . . . . grises; . . . .. . . . . c) . .. . . . . . . . . . . . . . . Histograma; . . . . . . .. . . . . d) . .. 15 17 18 21. Ejemplo de dataset parcial . . . . . . . . . . . . . . . . . . . . . . . . . Diagrama de Flujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fotograma de ejemplo. Arriba a la izquierda se ve el nodo actual mientras que abajo a la derecha se ve el anterior . . . . . . . . . . . . . . . . . . Muestra de fotogramas del vı́deo 1 mostrando diferentes nodos . . . . . Muestra de fotogramas del vı́deo 2 mostrando diferentes nodos . . . . . Falso positivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Muestra de fotogramas del vı́deo 3 mostrando diferentes nodos . . . . . Falso positivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 31 33 34 34 35 35. A.1 Muestra de imágenes de la aplicación en los distintos nodos . . . . . . .. 39. 5.4 5.5 5.6 5.7 5.8. iv. 27 30.

(6) Índice de cuadros 4.1 4.2 4.3 4.4. Matriz Matriz Matriz Matriz. de de de de. confusión confusión confusión confusión. para para para para. k k k k. = = = =. 1 3 5 7. . . . .. v. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. . . . .. 22 23 23 23.

(7) Capı́tulo 1 Introducción La navegación autónoma es una de las ramas de investigación la robótica donde se realizan un mayor número de aportaciones, con el objetivo de conseguir nuevas soluciones con buenos resultados y que sea posible trasladarlas al mundo real. En la actualidad, se ha desarrollado una gran cantidad de métodos para lograr una localización y orientación en un entorno, aprovechando gran cantidad de mecanismos e información disponible. Los sistemas más precisos para localización dependen de que una parte de la información necesaria para un correcto funcionamiento provenga de estructuras y mecanismos externos, tales como el GPS, que nos permite calcular nuestra posición utilizando triangulación por satélite. No todos esos métodos requieren de la creación de una infraestructura tan compleja como el GPS. Algunos tan sólo precisan colocar balizas señalizadoras ubicadas en el entorno, cuyo tipo puede variar, utilizando desde códigos de barras para su identificación con una cámara, hasta emisores de señal Wi-Fi, fácilmente captados por un teléfono móvil cualquiera. Sin embargo, su principal ventaja es, a su vez, uno de sus mayores inconvenientes. Esto es, su dependencia de estructuras externas implica que, si por algún motivo ese sistema no se encuentra disponible para su uso, la localización fallará. También se puede desarrollar un sistema de localización sin utilizar información extra recibida externamente, con su correspondiente ventaja de no depender de las 1.

(8) estructuras. Sin embargo, la localización es más complicada, ya que, como norma general, el entorno es mutable, con lo que resultará más complicado identificar lugares particulares. La localización en un entorno es sólo una parte de la navegación. La segunda parte es cómo desplazarse en el espacio, generando la ruta más eficaz entre dos puntos. Para desplazarte en el espacio, el primer paso es conocer con mayor o menor exactitud cómo es la zona por la que uno se intenta desplazar. Esto es, disponer de un mapa del entorno que podamos usar para generar nuestras rutas. Dependiendo de las necesidades del sistema de desplazamiento, necesitaremos un tipo de mapa distinto, con mayor o menor precisión. Por ejemplo, un mapa para movernos entre ciudades no tendrá la misma precisión que el plano de una casa. Ası́, la manera de construir rutas sobre dicho mapa también variará en función de la precisión con la que estén representados los obstáculos. Por ejemplo, mientras que en un mapa topológico, el cálculo de las mejores rutas es virtualmente trivial, debido a la gran cantidad de algoritmos existentes, diseñar una ruta automáticamente en un mapa con perfecta representación puede resultar complicado debido a la gran cantidad de opciones disponibles. La construcción automática de dicho mapa tampoco es un asunto trivial. Mientras que un mapa con representación precisa del entorno se incluyen todos los obstáculos, en un mapa topológico hay que decidir dónde colocar cada uno de los nodos del grafo subyacente para conseguir el mejor mapa posible, como se verá en apartados siguientes. Por último, comentar de los mapas que, aunque prácticamente necesarios para la navegación, hay que tener en cuenta que, como ya se ha dicho, el entorno es mutable. Pueden encontrarse en cualquier momento escenarios u obstáculos no contemplados en el mapa, con lo que lo ideal es tener el mapa actualizado lo más posible. Una vez visto por encima que existen gran cantidad de métodos y opciones para desplazarse en un entorno, pasamos a detallar el sistema que se desarrollará en este proyecto. El trabajo va a consistir en un sistema para ayudar a la navegación, utilizando como base un mapa topológico construido sobre un plano del entorno designado. El mapa topológico no se construirá automáticamente, sino que se hará de forma supervisada. Para la parte de identificación de los landmarks de nuestro mapa, se va a utilizar 2.

(9) reconocimiento directo de las imágenes obtenidas de una cámara, sin el uso de ningún otro sistema identificador de las imágenes. El sistema no irá montado sobre ningún robot, sino que se recorrerá el mapa de forma manual, por lo que no es tendrá datos de odometrı́a precisos que podamos aprovechar para aumentar la precisión del reconocimiento. El objetivo final será conseguir recorrer una ruta determinada sobre el terreno de manera que el sistema vaya identificando los distintos lugares de nuestro mapa según vamos avanzando por el entorno. En los siguientes capı́tulos del documento se procederá a realizar una descripción más detallada de los mapas topológicos, ası́ como explicar la construcción supervisada del mapa. Posteriormente se explicarán las caracterı́sticas escogidas para la clasificación de las imágenes y el algoritmo utilizado, ası́ como las pruebas estáticas realizadas. Por último, se integrará el algoritmo con el mapa y se probará recorriendo la ruta determinada.. 3.

(10) Capı́tulo 2 Fundamentos de los mapas topológicos visuales 2.1. Grafos. En matemáticas, un grafo es una representación de un conjunto de objetos en la que pares de los mismos están conectados por enlaces. Dichos objetos interconectados se representan con abstracciones matemáticas llamadas vértices o nodos, siendo los enlaces que los conectan llamados aristas o arcos. Habitualmente, un grafo se representa con un diagrama tal y como se muestra en la 2.1, donde los cı́rculos azules son los nodos, mientras que las lı́neas que los conectan son las aristas. Los grafos se pueden utilizar para modelizar muchos tipos de relaciones y procesos en sistemas tanto fı́sicos y biológicos como sociales o de información.. 2.2. Mapas Topológicos. Se llama mapa topológico a una representación de un entorno basada en grafos. Cada nodo de dicho grafo se corresponde con una caracterı́stica particular del entorno o landmark, mientras que los arcos del grafo se corresponderán con las rutas o instrucciones 4.

(11) Figura 2.1: Ejemplo de grafo de movimiento entre dichos nodos. Este tipo de mapa reduce el problema de navegación a encontrar una ruta de un nodo a otro hasta llegar al emplazamiento objetivo. Mediante algoritmos clásicos de búsqueda en grafos, como A*[2] o Dijkstra [1], el problema se resuelve rápidamente. Sin embargo, dado que en un mapa topológico no existe información explı́cita sobre la geometrı́a del entorno o posibles obstáculos, no es posible calcular un camino óptimo entre nodo y nodo. Una gran ventaja de los mapas topológicos para navegación es que no dependemos de la odometrı́a para localizar nuestra posición en el entorno, si no de la identificación de los landmarks del entorno. El único lugar donde se puede utilizar es en la información de los arcos del mapa, que en nuestro caso consiste en orientación y distancia entre nodos. Como los nodos vecinos están próximos unos a otros, el posible error en la odometrı́a está acotado y no se acumula al navegar por el entorno. 5.

(12) En la 2.2 tenemos un ejemplo de mapa topológico.. Figura 2.2: Ejemplo de mapa topológico. Imagen obtenida de [7]. 6.

(13) Capı́tulo 3 Construcción supervisada de mapas topológicos visuales La base del nuestro sistema de localización va a ser un mapa topológico. Por tanto, el primer paso en el desarrollo va a ser la construcción de dicho mapa. La construcción del mapa no se va a realizar automáticamente, sino que lo vamos a realizar de forma supervisada basándonos en un plano de la zona en la que se va a navegar. Podemos considerar que el desarrollo del mapa consta de dos partes diferenciadas. En un primer lugar se construirá el grafo base que contendrá los posibles lugares y rutas de nuestro mapa. Una vez tengamos un grafo que se adecúe a nuestras necesidades y a nuestro plano, se procederá a adquirir los datos visuales de los nodos del grafo que se ha acordado.. 3.1. Construccion del grafo. En este trabajo la zona en la que se va a navegar es la planta superior del Departamento de Inteligencia Artificial. Dentro de dicho departamento, el objetivo es conseguir navegar una ruta partiendo del ascensor localizado inmediatamente a la salida del departamento hasta conseguir llegar al despacho número 2207. En la Figura 3.1 se puede ver un plano simplificado de nuestra zona a navegar. En el plano se pueden ver dos cı́rculos representando el punto de salida, el ascensor, y nuestro objetivo a alcanzar, el despacho 2207, en verde y rojo, respectivamente. Todas las zonas 7.

(14) marcadas en negro son obstáculos inamovibles, paredes, básicamente. Las zonas grises se han marcado como tales debido a que no tienen interés de cara a nuestra ruta.. Figura 3.1: Plano simplificado del DIA Para comenzar con la creación de nuestro plano, empezaremos designando nodos sobre el mismo, de tal manera que consigamos que nodos adyacentes tengan entre los mismos visibilidad en lı́nea recta. Esto es debido a que los enlaces entre nuestros nodos estarán definidos tan sólo por una orientación y una distancia. Como primer nodo podemos tomar fácilmente el punto de inicio de nuestra ruta. Como el principio y el final de la misma van a ser parte de ella, podemos considerar que ya tenemos dos nodos fijos, el ascensor y el despacho. Para continuar escogiendo lugares en los que emplazar nuestros nodos, vamos a ver, partiendo del primero que tenemos, hasta dónde se puede llegar en lı́nea recta sin encontrarnos con ningún obstáculo.. 8.

(15) Podemos comprobar en la figura 3.2 que se ha coloreado una aproximación de las posibles áreas disponibles para colocar nuestro segundo nodo. Partiendo de aquı́ tenemos varias posibilidades para su colocación. Hay que tener en cuenta que el objetivo final va a ser alcanzar el nodo final, es decir, el despacho. Debido a esto, se pueden eliminar las zonas en las que, si colocásemos un nodo, nos llevarı́a en sentido contrario a nuestro objetivo. Figura 3.2: Zona accesible en lı́nea recta Esto se puede hacer de forma sencilla desde el primer nodo (azul) debido a que no se automatiza la construcción de nuestro grafo, y se puede apreciar visualmente y con facilidad si extender el grafo en determinadas direcciones nos ayuda o no a alcanzar nuestra meta. En el caso de que se quisiera automatizar la construcción, esto no serı́a tan trivial. Visto esto, la zona que nos queda se puede comprobar en la figura 3.3. Ası́, tenemos varias posibilidades para su colocación. Se pueden ver varios ejemplos en la figura 3.4. Realmente, no hay ninguna posibilidad que sea incorrecta de por sı́. Cualquiera de las opciones puede dar lugar a un mapa correcto y funcional. En este caso, nos hemos decantado por la opción 3, por varias razones. En primer lugar, es el nodo que Figura 3.3: Zona accesible tras eliminar reestá más próximo al final de nuestra ru- trocesos ta. Un dato relevante, sin duda, aunque muy dependiente del posicionamiento de los obstáculos y de la ruta a seguir. En nuestro caso es un nodo muy beneficioso, aunque se puede dar caso que el nodo más 9.

(16) cercano al objetivo no sea siempre el mejor. En segundo lugar, debido a la configuración del mapa, al colocar un nodo directamente en dicha posición, nos ahorramos un nodo que es necesario en las otras configuraciones. Como se puede ver en la figura 3.5, si queremos continuar nuestra ruta es necesario colocar un nodo en esta posición, o muy similar a la misma, para cualquier configuración del mapa.. Figura 3.4: Opciones para colocar el nodo número 2 Figura 3.5: Muestra de la necesidad de un nodo intermedio Por último, saliendo un poco de la parte estrictamente del grafo, los otros dos nodos se encuentran en posiciones donde van a resultar afectados por la variación de luz natural, mientras que aquı́ no se da ese caso, o, al menos, no de forma tan acentuada, lo que facilita el proceso posterior de clasificación. Una vez decidida la posición de nuestro nodo, procederemos a colocar el siguiente. Partiendo desde esta última posición, se puede ver que el nodo se puede colocar en cualquier punto a lo largo del pasillo. Esta decisión es más sencilla que el caso anterior, ya que no existen lugares de interés de nuestra ruta en posiciones intermedias. Por tanto, el lugar más beneficioso 10.

(17) para nuestro nodo es la esquina, como se puede ver en la figura 3.6. Para colocar nuestro siguiente nodo, tenemos un pasillo más largo que en el caso anterior. Sin embargo, de la misma forma que en el caso anterior, no es necesario tener nodos intermedios a lo largo del pasillo, porque nuestra ruta no tiene puntos de interés. En el caso de que en algún momento quisiéramos que con nuestro mapa se acceda a los despachos laterales, se colocarı́an nodos en las posiciones necesarias. Sin embargo, en este caso no podemos realizar la misma operación que en el caso anterior, colocar el nodo al final del pasillo, dado que es un callejón sin salida. Por tanto, colocaremos el nodo en la intersección de los dos pasillos, como se muestra en la figura 3.7. El siguiente nodo es similar al del pasillo corto. La mejor posición que tenemos es el final del pasillo 3.8. Una vez aquı́, lo único que queda es unir nuestro último nodo con el final de nuestra Figura 3.6: Elección del nodo número 2 ruta para completar nuestro mapa, como se puede ver en la figura 3.9. En nuestro mapa completo se puede apreciar que la mayorı́a de los nodos se encuentran en esquinas o intersecciones. Como ya se ha mencionado, los nodos están todos enlazados de la misma forma, por lı́neas rectas, variando sólo la longitud de las mismas, es decir, la distancia entre los nodos. Dado. Figura 3.7: Elección del nodo número 4. 11.

(18) que los pasillos del departamento son rectos, colocar los nodos en las esquinas nos permite conseguir las condiciones de visibilidad entre nodos de las que hemos hablado anteriormente. A su vez, como ya hemos mencionado, los despachos laterales de los pasillos no son relevantes para nuestra ruta, luego no se han colocado nodos a lo largo del pasillo. Hay que tener en cuenta que este grafo se ha construido basándose en un plano en el que sólo se encuentran marcados los obstáculos fijos del terreno. No se están contemplando elementos tales como armarios, mesas, sillas o aparatos electrónicos que puedan interferir con la distribución inicial de nuestro mapa. Ası́ mismo, tampoco tenemos otras operaciones que puedan afectar, tales como obras que cierren parte del recorrido. En el caso de que no se tenga información sobre estos obstáculos dinámicos, habrı́a que comprobar sobre el terreno si afectan al grafo construido y, en su caso, reconstruir las partes del grafo que estén afectadas. Esto es uno de los principales problemas que se pueden encontrar al construir y utilizar el grafo, dado que la edición del mapa a tiempo real es virtualmente imposible. Por suerte para nuestro caso y como se Figura 3.8: Elección del nodo número 5 podrá comprobar en el apartado siguiente de toma de imágenes, no ha resultado necesario reconstruir el mapa, ya que no se han encontrado nuevos obstáculos.. 12.

(19) Figura 3.9: Mapa completo. 13.

(20) 3.2. Obtención de los nodos visuales. Una vez tengamos un grafo que podamos considerar válido, el siguiente paso consistirá en acceder al terreno para tomar imágenes de cada uno de los nodos a evaluar y comprobar si, independientemente del posicionamiento sobre el terreno, ya definido en el apartado anterior, los nodos designados son válidos de cara al reconocimiento de nuestra posición. Para ello, tenemos que ver si las imágenes de los nodos son fácilmente reconocibles de nodo a nodo. Esto puede ser trivial para un observador humano, cuya capacidad de reconocimiento y diferenciación de objetos es muy elevada. Sin embargo, es una tarea mucho más difı́cil y compleja realizar reconocimientos mediante computadora. Como ya se explicará con mayor detalle en capı́tulos siguientes, el elemento discriminante que se va a utilizar en principio para nuestro reconocimiento va a ser el histograma de las imágenes. Ası́ pues, el primer paso consiste en tomar una imagen representativa de cada nodo de nuestro mapa, de la que posteriormente se extraerá el histograma para comprobar visualmente la diferencia entre las imágenes. Las imágenes representativas junto con sus histogramas se pueden ver en la figura 3.10. Se puede comprobar que en general los histogramas son bastante diferentes entre sı́. Los picos y los valles de color están situados en posiciones distintas en cada uno de ellos. Esto quiere decir que, a priori, nuestros nodos pueden resultar completamente válidos para realizar la localización. Sin embargo, aún será necesario un mayor número de pruebas junto con el algoritmo a utilizar para tener la seguridad de que las imágenes sean completamente útiles. Estas pruebas se detallarán en el capı́tulo siguiente. En el caso de que, por el motivo que sea, nos encontrásemos que dos o más de nuestras muestras fueran muy similares, tendrı́amos varias opciones a seguir. Una primera idea serı́a rehacer parte del mapa de tal forma que los nodos similares desaparezcan. Esta puede ser la opción más sencilla si no queremos variar el discriminante o el algoritmo utilizado para la localización de los nodos. Sin embargo, que se pueda realizar esta opción depende en gran medida del terreno sobre el que se construye nuestro mapa. Si hay espacio suficiente para situar o reorientar nuevos nodos, no habrá mucho problema. En nuestro caso, por ejemplo, gran parte del 14.

(21) Figura 3.10: Fotografı́a de muestra e histograma de: a) Nodos 1 y 2; b) Nodos 3 y 4; c) Nodos 5 y 6 mapa es una sucesión de pasillos estrechos, donde no hay demasiado lugar para recolocar nodos. Una segunda opción podrı́a ser variar el elemento a usar para reconocer las imágenes. Básicamente, no utilizar el histograma. Utilizar por ejemplo, reconocimiento de objetos en la imagen. Aquı́ el problema se lo lleva la parte computacional de la localización, ya que probablemente se deberı́a cambiar el algoritmo a utilizar, siendo este nuevo algoritmo, muy probablemente, más complejo que otros que utilicen histograma. De todos modos, como ya se ha dicho, en nuestro caso en principio no tenemos esos problemas, ya que los histogramas están lo suficientemente diferenciados. Por tanto, el siguiente paso será la parte de uso del algoritmo y comprobación de si, efectivamente, nuestras imágenes son válidas.. 15.

(22) Capı́tulo 4 Diseño y evaluación del reconocedor de landmarks 4.1. Elección de caracterı́sticas y algoritmo. Ya tenemos nuestro mapa topológico construido y tenemos una muestra visual de los nodos que consideramos que, en principio, puede funcionar adecuadamente de cara al reconocimiento. Ası́, el siguiente paso consistirá en definir las caracterı́sticas de las imágenes que utilizaremos, ası́ como el algoritmo a usar, realizando, por supuesto, las pruebas de eficiencia correspondientes. Estamos utilizando como base para reconocer nuestra posición una imagen directa de cada nodo, sin apoyos externos. Ası́ pues, deberemos elegir qué caracterı́sticas de nuestra imagen nos pueden servir de mejor manera para realizar la identificación. La primera y más sencilla opción es utilizar el histograma de la imagen. El histograma de una imagen es básicamente una representación de la distribución de tonos de color en una imagen digital, mostrando el número de pı́xeles de la imagen correspondientes a cada tono de color. De esta manera podemos comprobar la distribución de tonos de un sólo vistazo. Dado que una imagen suele tener varios tonos de color, en general podemos generar varios histogramas distintos para una sola imagen, dependiendo del color que usemos. Por ejemplo, en una imagen en formato RGB podemos encontrar tres histogramas, rojo, verde y azul. 16.

(23) Para nuestro caso, vamos a simplificar más el problema. En lugar de utilizar las imágenes tal y como se obtengan de la cámara, en primer lugar se transformarán a escala de grises. De esta manera obtendremos un solo histograma con 256 valores distintos dependiendo de la intensidad del gris. Podemos ver en la figura 4.1 un ejemplo de histograma. El eje horizontal de la imagen representa la variación de tono, mientras que el eje vertical representa el número de pı́xeles en cada tono. El tono aumenta en luminosidad de izquierda a derecha, partiendo del color negro al blanco. Ası́, una imagen oscura contendrá la mayorı́a de los datos en la parte izquierda del histograma, mientras que una imagen clara los tendrá a la derecha. Sin embargo, aún se pueden encontrar algunos problemas al comparar histogramas. Puede darse el caso de que encontremos dos imágenes que necesitemos comparar y que tengan distinta resolución. Dado que el histograma trabaja con números en bruto, no se pueden comparar dos imágenes con distinto número de pı́xeles. Para paliar este problema, en lugar del histograma clásico vamos a utilizar Figura 4.1: Ejemplo de Histograma el llamado histograma normalizado. Para ello, una vez tengamos nuestro histograma estándar, dividiremos el número de pı́xeles de cada valor por el número total de pı́xeles de la imagen. De esta manera, estaremos trabajando con proporciones en lugar de valores absolutos, eliminando en gran medida el problema de las diferencias de resolución. Como se puede ver en la figura 3.10, a simple vista los histogramas de las imágenes de muestra de nuestros nodos se diferencian bastante entre sı́. Ası́, tenemos que en un primer momento utilizaremos como caracterı́stica discriminante el histograma normalizado de nuestras imágenes. El siguiente paso es seleccionar un algoritmo que pueda trabajar con los valores de nuestros histogramas para identificar las imágenes. Al igual que para el caso de la elección de caracterı́sticas, la idea de partida va a ser un algoritmo simple. Para comenzar, utilizaremos el algoritmo k-nn, que es un 17.

(24) algoritmo fácil de diseñar y bastante eficiente, con lo que resulta un buen punto de partida antes de meterse con algoritmos más complejos. El algoritmo de clasificación k-nearest neighbour, o k-nn, es un algoritmo cuya entrada consiste en los k ejemplos de entrenamiento más próximos en el espacio de caracterı́sticas y cuya salida es una asignación de pertenencia a una clase. Un objeto se asigna a la clase más común entre sus k vecinos más próximos. Si k=1, directamente se asigna a la clase del vecino más próximo. Podemos ver un ejemplo en la Figura 4.2. Tenemos que clasificar el cı́rculo verde en una de las dos clases posibles, azules o rojos. Utilizando k = 3 vemos que se clasifica en la clase roja, porque hay dos en el cı́rculo interno, por uno sólo de la otra clase. Sin embargo, al utilizar k = 5, se asigna a la clase contraria, debido a que ahora hay más objetos de la misma. Como ya se ha comentado, el k-nn es uno de los algoritmos de clasificación más simples, soliendo ser un buen punto de partida para un trabajo de clasificación en el que no se conoce la distribución de los datos [6]. La eficiencia del k-nn depende básicamente de la calidad y el tamaño del set de ejemplos que se encuentran en su memoria. Por ello, el conjunto de elementos inicial debe tener un gran tamaño para que el algoritmo resulte efectivo. Además del tamaño del dataset, éste tiene que estar equilibrado. Esto es, cada una de las clases tiene que estar representada por aproximadamente el mismo número de elementos para que los resultados sean lo más precisos posibles.. Figura 4.2: Ejemplo del algoritmo k-nn. Si una vez realizadas las pruebas con el k-nn comprobamos que los resultados no son todo lo precisos que se puede esperar, veremos a ver si resulta necesario cambiar de algoritmo. Para este sistema hemos utilizado el algoritmo k-nn implementado en la librerı́a de 18.

(25) visión computacional y aprendizaje automático de OpenCV (TODO:Ref). Una vez tenemos escogidas tanto las caracterı́sticas a utilizar de nuestras imágenes como el algoritmo que se va a emplear, el siguiente paso es comprobar si la elección es correcta, es decir, realizar pruebas para comprobar la eficacia del método.. 4.2. Construcción del set de entrenamiento. El primer paso para probar la eficiencia de nuestro algoritmo es construir un set de entrenamiento con imágenes de los nodos a identificar. Como ya hemos comentado, el k-nn precisa de un set de entrenamiento de gran tamaño para obtener buenos resultados. Para construir dicho set de entrenamiento, es necesario tomar manualmente gran cantidad de imágenes de los diferentes nodos de nuestro mapa. No sólo eso, sino que, para mejorar la posible identificación, es importante que el ángulo de la cámara no se mantenga fijo, para aumentar la variación de imágenes dentro de un mismo modo y que sea más sencillo identificar el lugar sin necesidad de colocarse en una posición precisa. Teniendo en cuenta que para esta situación la importancia no es tanto la posición de los objetos de la imagen si no la distribución de las imágenes, se ha procedido a utilizar el siguiente método para facilitar la toma de imágenes. Estando en la posición en la que tenemos un nodo en nuestro mapa, procederemos a grabar un vı́deo de varios segundos, realizando ligeros movimientos de cámara para abarcar un mayor plano de la escena. Una vez grabados los vı́deos necesarios, procederemos a extraer los fotogramas de los mismos, los cuales utilizaremos como imágenes para nuestro dataset. Dado que es probable que cada vı́deo tenga diferente número de imágenes, con el fin de tener equilibrio en la representación de las clases, deberemos eliminar imágenes hasta tener el mismo número de cada nodo. Hay que tener en cuenta que, al grabar el vı́deo, el movimiento de la cámara provoca que la mayorı́a de las fotos obtenidas resulten borrosas. En nuestro caso, las caracterı́sticas que extraemos de nuestra imagen no dependen de los pı́xeles individuales, si no de las proporciones de color de las imágenes, que se van a mantener sin mucha variación estando la foto borrosa o no.. 19.

(26) Para nuestro caso, tras extraer todos los fotogramas, tendremos 600 imágenes por nodo en nuestro dataset, en principio suficiente para nuestras necesidades. El siguiente paso consistirá en extraer nuestro discriminante, el histograma, de nuestro set de imágenes. Para ello, el primer paso será convertir nuestra imagen a escala de grises, transformando cada pı́xel de la imagen en un valor entre 0 y 255, en función del balance de colores RGB que contenga cada uno de los mismos. A continuación contaremos el número de pı́xeles de cada valor que encontramos en nuestra imagen modificada. Agrupando cada valor obtendremos un listado de 256 valores, que constituyen el número de pı́xeles de cada color en la imagen. Este listado es nuestro histograma inicial de la imagen. Como ya hemos comentado, de cara a eliminar en la medida de lo posible las diferencias en la resolución de las imágenes tomadas, no utilizaremos el histograma directamente tal y como lo hemos obtenido, sino que procederemos a realizar una normalización del mismo. Una vez hecho esto, tendremos nuestro set de entrenamiento preparado para realizar las pruebas con el algoritmo. Un esquema de las etapas del proceso por las que pasa la imagen se puede ver en la figura 4.3. Todo este proceso, extracción de fotogramas, conversión a escala de grises y obtención del histograma se a realizado utilizando la librerı́a OpenCV, excepto la normalización, que se ha hecho de forma manual. Una vez tenemos nuestro dataset de caracterı́sticas preparado, el siguiente paso es comprobar si obtenemos buenos resultados con nuestro algoritmo de clasificación.. 4.3. Pruebas estáticas del dataset. Ahora tenemos que ver si, efectivamente, nuestro algoritmo consigue buenos resultados de nuestro dataset de entrenamiento. Para comprobar la eficiencia de nuestro algoritmo, procederemos a realizar un procedimiento de validación cruzada denominado leave-one-out. Este proceso consiste en utilizar como set de entrenamiento todas las imágenes de las que dispone nuestro dataset excepto una. Posteriormente esa imagen se clasificará utilizando el k-nn y el resto. 20.

(27) Figura 4.3: a) Imagen original; b) Imagen en escala de grises; c) Histograma; d) Histograma normalizado de nuestro dataset. Este procedimiento se repite con todas las imágenes de nuestro conjunto de entrenamiento. Después se procederá a contar el número de aciertos obtenidos durante la clasificación. Dividiendo ese resultado por el número total de imágenes obtendremos un ı́ndice que nos dirá la eficiencia global del dataset. Un segundo conjunto de resultados consistirá en la llamada matriz de confusión. Esto es una tabla de resultados que indica las imágenes de cada nodo que se han clasificado erróneamente como nodos distintos. Esta tabla puede resultar útil para comprobar en qué nodos se confunde el clasificador en mayor medida.. 21.

(28) Dado que en el k-nn se puede variar el valor de k para obtener distintos grados de separación entre clases, se ha repetido el procedimiento con valores de k impares desde 1 hasta 7. Para calcular el valor de eficiencia, se ha dividido el número de aciertos durante la prueba por el número total de imágenes del conjunto. Los resultados varı́an en función del valor de k, ya que la diferenciación entre clases disminuirá al aumentar este valor. Ası́ obtenemos los siguentes resultados: • k = 1. Resultado 100 % de aciertos • k = 3. Resultado 99.97 % de aciertos (1 fallo) • k = 5. Resultado 99.69 % de aciertos (11 fallos) • k = 7. Resultado 99.67 % de aciertos (12 fallos) A continuación se muestran las diferentes matrices de confusión obtenidas para los distintos valores de k. Esperado\Obtenido (No Imágenes) Nodo 1 Nodo 2 Nodo 3 Nodo 4 Nodo 5 Nodo 6. Nodo 1 600 0 0 0 0 0. Nodo 2 0 600 0 0 0 0. Nodo 3 0 0 600 0 0 0. Nodo 4 0 0 0 600 0 0. Nodo 5 0 0 0 0 600 0. Cuadro 4.1: Matriz de confusión para k = 1. Se puede ver que con valores superiores de k encontramos mayor confusión en el nodo número 2. Como ya hemos comentado anteriormente, el algoritmo k-nn utilizado es el que se encuentra implementado en la librerı́a OpenCV. Dados los buenos resultados obtenidos en las pruebas estáticas, en principio no consideraremos necesario modificar las caracterı́sticas escogidas de nuestras imágenes ni el algoritmo elegido, con lo que procederemos a integrar el sistema de identificación con el mapa topológico y a realizar pruebas dinámicas del sistema. 22. Nodo 6 0 0 0 0 0 600.

(29) Esperado\Obtenido (No Imágenes) Nodo 1 Nodo 2 Nodo 3 Nodo 4 Nodo 5 Nodo 6. Nodo 1 600 0 0 0 0 0. Nodo 2 1 599 0 0 0 0. Nodo 3 0 0 600 0 0 0. Nodo 4 0 0 0 600 0 0. Nodo 5 0 0 0 0 600 0. Nodo 6 0 0 0 0 0 600. Nodo 4 0 0 0 600 0 0. Nodo 5 0 0 0 0 600 0. Nodo 6 0 0 0 0 0 600. Nodo 4 0 0 0 600 0 0. Nodo 5 0 0 0 0 600 0. Nodo 6 0 0 0 0 0 600. Cuadro 4.2: Matriz de confusión para k = 3. Esperado\Obtenido (No Imágenes) Nodo 1 Nodo 2 Nodo 3 Nodo 4 Nodo 5 Nodo 6. Nodo 1 600 0 0 0 0 0. Nodo 2 7 589 0 4 0 0. Nodo 3 0 0 600 0 0 0. Cuadro 4.3: Matriz de confusión para k = 5. Esperado\Obtenido (No Imágenes) Nodo 1 Nodo 2 Nodo 3 Nodo 4 Nodo 5 Nodo 6. Nodo 1 600 0 0 0 0 0. Nodo 2 8 588 0 4 0 0. Nodo 3 0 0 600 0 0 0. Cuadro 4.4: Matriz de confusión para k = 7. 23.

(30) Capı́tulo 5 Integración y pruebas operativas dinámicas 5.1. Integración del dataset y el algoritmo en el mapa. Como se ha visto en los apartados anteriores, ya tenemos un conjunto de entrenamiento construido y hemos decidido qué algoritmo vamos a utilizar. Ası́, nuestro siguiente paso es combinar nuestro dataset con el mapa que construimos anteriormente y decidir cómo se va a utilizar el algoritmo para el reconocimiento. El primer paso es trasladar el dataset al mapa. Esto se hace de forma sencilla, puesto a que cada uno de los nodos de nuestro mapa le corresponderá un sólo grupo de imágenes de nuestro conjunto de datos. Ası́, interiormente, cada nodo de nuestro grafo tendrá asignado una serie de datos a los que accederá el algoritmo posteriormente. Una vez tenemos los datos distribuidos en nuestro mapa, lo siguiente que hay que decidir es cómo utilizar el algoritmo para la identificación de nuestra posición. Para ello, primero vamos a describir de forma breve cómo deberı́a ser el comportamiento final del sistema. El programa estará recibiendo imágenes del exterior en todo momento. Todas esas imágenes irán pasando por el algoritmo, el cual las identificará y clasificará en función de en qué nodo estemos, o las ignorará si consideramos que no estamos en ninguno de. 24.

(31) los puntos caracterı́sticos de nuestro mapa. Eso es, a grandes rasgos, el comportamiento básico del sistema. Ahora tenemos que ver cómo utilizamos el algoritmo de clasificación para alcanzar un comportamiento lo más similar posible. Para ello, vamos a diferenciar dos situaciones primarias. En primer lugar, al realizar el arranque del sistema, tenemos que identificar en qué nodo nos encontramos dada una imagen inicial. Dado que no tenemos un nodo inicial asignado por el que sepamos que vayamos a empezar en todas las situaciones, tenemos que decidir cual es, a priori, la mejor manera de identificar nuestro primer nodo. En nuestro caso, lo más sencillo será aplicar el algoritmo sobre todo el conjunto de datos. Es decir, mirar todos los nodos del mapa y escoger el que más se parece a nuestra situación inicial. En el caso de que el mapa fuera de gran tamaño, serı́a mucho más difı́cil encontrar nuestro nodo inicial, debido a la cantidad de datos y a la mayor probabilidad de encontrar nodos similares. Suponiendo que se diera un caso en el que tuviéramos un mapa de grandes dimensiones en el que por algún motivo no resultase viable pasar el algoritmo a todos los nodos, una opción para resolverlo serı́a dividir el mapa en grupos de nodos lo más diferentes posibles. Una vez hecho esto, pasar el algoritmo a cada uno de los grupos individualmente. Aún realizando estas operaciones puede suceder que se encuentren nodos similares de un grupo a otro. En ese caso, se pueden crear varias rutas paralelas partiendo de los diferentes nodos, e ir eliminando opciones según alcancemos nuevos nodos. De esta forma tenemos localizado nuestro nodo inicial. El siguiente paso será comenzar la clasificación nodo a nodo siguiendo la ruta. Como ya se ha comentado antes, el sistema va a estar recibiendo imágenes en todo momento. Esto quiere decir que nuestro algoritmo va a tratar de clasificar todos los fotogramas que reciba, incluyendo los correspondientes al tránsito entre los diferentes nodos de nuestro mapa. Como los fotogramas obtenidos del movimiento entre nodos no se encuentran en nuestro conjunto de datos, deberemos evitar en la medida de lo posible que sean clasificados como pertenecientes a algún nodo. Para ello se han aplicado varias medidas. En primer lugar, vamos a acotar la distancia máxima para que se considere que una imagen pertenece a un nodo. La implementación del k-nn devuelve una serie de datos 25.

(32) al realizar una clasificación: una lista de la pertenencia a las clases de los vecinos más próximos, tan larga como el valor de la k, la distancia correspondiente a cada vecino y, obviamente, la pertenencia de la imagen de entrada. Es la medida de distancia la que nos servirá para mejorar la precisión de la clasificación. Esas distancias miden, esencialmente, la diferencia entre el histograma de la imagen a clasificar y el de los vecinos. Aprovechando dicha medida, podemos poner una cota a las distancias al nodo. De esta manera utilizamos la distancia para comprobar la pertenencia real a la clase. Esto es, consideramos que estamos realmente en el nodo correspondiente si la distancia al vecino más próximo es menor que una cota determinada. Esta técnica tiene buenos resultados en general. Sin embargo, aún se pueden encontrar zonas de tránsito cuya distancia al nodo clasificado es menor que en el caso de algunos puntos de referencia del mapa, con lo que aún se puede mejorar. Ası́, podemos determinar una cota de proximidad variable dependiendo del nodo que estemos identificando. Como ya hemos comentado anteriormente, la opción más viable para identificar el primer nodo sin datos anteriores es pasar el algoritmo al mapa completo. Sin embargo, una vez que estamos en ruta, podemos utilizar nuestra posición actual para mejorar la localización local. En lugar de utilizar el dataset completo cada vez que queramos identificar nuestra posición, podemos crear un conjunto de datos parcial que englobe tan sólo el último nodo en el que nos hemos localizado y los nodos adyacentes al mismo y utilizar el algoritmo sólo con esos nodos. De esta forma eliminaremos ruido provocado por los nodos que estén más alejados de nuestra posición actual y a los que no se puede llegar en, digamos, un paso. Cada vez que alcancemos un nuevo nodo, construiremos un nuevo conjunto parcial utilizando la misma técnica. Se puede apreciar visualmente en la figura 5.1. En a) Nos encontramos en el Nodo 2, con lo que nuestro dataset consiste en las imágenes del Nodo 2 (Rojo) y las de los adyacentes, 1 y 3 (Amarillo). En b) Pasamos al Nodo 3 y realizamos el mismo proceso con los nodos 2 y 4. Sin embargo, esta forma de proceder no está exenta de fallos. Puede darse el caso que, al recorrer nuestra ruta, nos saltamos un nodo. Si eso sucediese, nuestro sistema 26.

(33) Figura 5.1: Ejemplo de dataset parcial no actualizarı́a el conjunto de datos parcial, y continuarı́a utilizando el que ya tiene, que ya no se corresponde con nuestra posición actual en el mapa. Para intentar resolver este problema, se puede aumentar el radio de nuestro conjunto parcial. Ası́, en lugar de almacenar sólo los nodos adyacentes, almacenarı́amos también los nodos adyacentes a estos. Hay que tener cuidado de no aumentar demasiado el radio porque, dependiendo de la estructura del mapa, puede eliminar el beneficio de tener un dataset parcial. También podemos pasar el algoritmo a datasets de distintos radios al mismo tiempo, para obtener el mejor resultado con el más pequeño, pero tener la posibilidad de identificar nodos externos con el de mayor tamaño si nos salimos del pequeño. Por último, una posible técnica es utilizar el tiempo en el que estamos en cada nodo como forma de identificación. Es decir, si las últimas n imágenes que ha recibido el 27.

(34) sistema se corresponden con un nodo determinada, podemos considerar que estamos en dicho nodo. Esto es factible debido que en momentos de tránsito entre nodos el comportamiento más común es la variación del contenido de las imágenes de forma relativamente rápida. A su vez, como dependemos del cambio rápido de la imagen cuando estamos en movimiento, se pueden recibir falsos positivos si la cámara se detiene en algún punto durante un tiempo determinado. Y en caso contrario, se puede dar el caso que la cámara apenas se detenga y el nodo no resulte identificado correctamente. En resumen, este método no resulta tan fiable debido a que depende más del movimiento de la cámara que de las imágenes recibidas por la misma. Una vez dicho todo esto, comentar que en el mapa están integradas la distancia y la orientación necesarias para llegar de un nodo a otro. Estos datos realmente no sirven de cara a la identificación de imágenes, pero es información que puede usar el sistema de movimiento, bien una persona o un robot, para colocar la cámara en una posición que contribuya a la identificación correcta de las imágenes. Ya teniendo el conjunto de datos y el algoritmo integrados con el mapa, el siguiente paso es realizar las pruebas en el terreno para comprobar el correcto funcionamiento del sistema.. 5.2. Pruebas dinámicas. Como ya se ha dicho, el siguiente paso del sistema es realizar pruebas a tiempo real para comprobar su funcionamiento. Debido a que la zona en la que vamos a navegar no es accesible en todo momento, se ha optado por realizar la identificación de los nodos sobre un vı́deo grabado con la cámara con la que se tomaron las imágenes del conjunto de entrenamiento. Este enfoque tiene sus ventajas y sus inconvenientes. En primer lugar, al ser el vı́deo reproducible las veces que sea necesario, tenemos una base sobre la que trabajar que se va a comportar de la misma forma todas las veces, con lo que resultará más sencillo identificar los principales problemas que podemos encontrar en la clasificación. A su vez, la falta de variación en los ejemplos puede dificultar la localización de. 28.

(35) algunos problemas que podrı́an haberse encontrado con mayor facilidad trabajando directamente a tiempo real. También, dado que no se puede mover la cámara como en el caso de pruebas a tiempo real, perdemos la posibilidad de enfocar si no tenemos la posición exacta del nodo. Sin embargo, a pesar de las desventajas, el vı́deo permite la ejecución de pruebas y cambio de parámetros de una forma mucho más veloz que lo que permitirı́an las pruebas a tiempo real. A continuación, vamos a describir el comportamiento del sistema para cada paso de ejecución. En cada iteración, el sistema extraerá un fotograma del vı́deo y obtendrá como se ha descrito anteriormente el histograma normalizado de nuestra imagen. Una vez hecho esto, tendremos dos situaciones dependiendo de si es el primer nodo a identificar o no. Si nos encontramos al principio de la ejecución, y no tenemos disponible el último nodo por el que hemos pasado, aplicaremos el algoritmo sobre todos los nodos del mapa, clasificando ası́ nuestra primera imagen en una clase. Si tenemos disponible el último nodo por el que hemos pasado, en lugar de aplicar el algoritmo a todo el mapa, lo aplicaremos al conjunto parcial correspondiente a ese nodo. Una vez realizada la clasificación, se comprobará la distancia a la clase obtenida por el algoritmo con la cota de distancia aplicada al algoritmo. En caso de que la distancia sea menor, el nodo identificado se almacenará como último nodo visitado y se creará un conjunto parcial centrado en dicho nodo para su uso en la siguiente iteración. En caso de que no alcance la cota de distancia máxima, ignoraremos el resultado de la clasificación y pasaremos a la siguiente iteración del sistema. A continuación, se incluye un fragmento sencillo de pseudocódigo para ilustrar el funcionamiento del algoritmo, junto con el diagrama de flujo correspondiente en la figura 5.2.. 29.

(36) Algorithm 1 Procedimiento Parametro externo mapa Parametro externo threshold Parametro externo K Conjunto Clasificacion ← mapa.nodos nodo actual ← None knn.train(K,Conjunto Clasificacion) while Quedanf otogramas do image ← fotograma siguiente hist ← histograma norm(image) nodo, distancia ← knn.classify(hist) if distancia < threshold then nodo actual ← nodo Conjunto Clasificacion ← nodo actual.vecinos Independientemente del resultado, el fotograma se reproducirá por pantalla. En cada fotograma se podrá observar en todo momento el nombre del último nodo por el que hemos pasado abajo a la derecha. En la esquina superior izquierda se puede ver el nodo en el que nos encontramos en ese fotograma. Como se puede comprender, esta etiqueta no aparece en la mayor parte del vı́deo, dado que en la mayor parte de los fotogramas nos encontramos en tránsito entre nodos. En la Figura 5.3 tenemos un fotograma de ejemplo. A continuación, mostraremos varios fotogramas correspondientes a varios recorridos de ejemplo. Aunque resulta complicado la presentación de resultados de pruebas de vı́deo en un documento de texto, podemos ver cómo va identificando los distintos nodos según se van alcanzando los mismos.. Figura 5.2: Diagrama de Flujo. 30.

(37) Figura 5.3: Fotograma de ejemplo. Arriba a la izquierda se ve el nodo actual mientras que abajo a la derecha se ve el anterior Para las pruebas se han prueba se han utilizado algunas de las medidas mencionadas en el apartado anterior, tal y como se ha visto en la descripción del funcionamiento del sistema. A continuación describiremos los parámetros mencionados. En primer lugar, para el algoritmo k-nn en si se ha utilizado un valor de k=1. Esto es, sólo hemos tenido en cuenta el vecino más próximo. Esto se ha decidido principalmente debido a los buenos resultados que se han obtenido en la prueba leave-one-out. Aunque se ha realizado varias pruebas con distintos valores de k, no se han apreciado mejores resultados con otros valores. Con respecto a la cota de distancia, ha ido variando a lo largo de las pruebas. En un primer momento se ha tomado una cota única para todos los nodos, la cual se ha colocado inicialmente en 0.001. Sin embargo, se ha comprobado que era una cota demasiado grande, dado que encontrábamos identificaciones falsas durante desplazamientos entre nodos. Por tanto, se ha ido disminuyendo hasta llegar a una cota que disminuyera los falsos positivos. Sin embargo, se ha empezado a dar casos en los que, a pesar de las mejoras de falsos positivos en tránsito, nos encontrábamos con que algunos nodos correctos no se identificaban adecuadamente. Este hecho nos ha llevado a tratar de colocar cotas individuales para los diferentes nodos. Para decidir el valor de las diferentes cotas, se ha realizado el siguiente procedimiento. En primer lugar se han escogido al azar diez vı́deos de entre los que disponemos para. 31.

(38) realizar pruebas. A esos vı́deos se les ha pasado el clasificador por todos los fotogramas, sin el uso de cotas de distancias ni otras técnicas, y se ha almacenado para cada nodo el valor de distancia mı́nimo con el que se ha clasificado cada nodo, ası́ como el fotograma en el que se ha alcanzado. Partiendo de los datos obtenidos, se han decidido las cotas mı́nimas de cada nodo, quedando de la siguiente manera: • Ascensor (Nodo 1): 0.0006 • Entrada (Nodo 2): 0.00075 • Fotocopiadora (Nodo 3): 0.0005 • Escalera (Nodo 4): 0.0006 • Cruce (Nodo 5): 0.0008 • Despacho (Nodo 6): 0.005 Sobre los conjuntos de datos parciales, se han realizado pruebas tanto sin conjuntos parciales, como con conjuntos de radio uno, sólo nodos adyacentes, excepto para el primer nodo, que se localiza utilizando todo el dataset. Se podrá ver que cada opción tiene sus ventajas y sus inconvenientes. Con respecto a la opción de medir el tiempo en cada nodo, no se ha utilizado en la prueba final del vı́deo. Sı́ se ha utilizado durante el proceso de prueba, pero el principal inconveniente es que, al ser un vı́deo, no se puede controlar el tiempo de espera en cada posición. Como ya se ha mencionado, el vı́deo no ofrece posibilidad de mover la cámara para conseguir un mejor enfoque de los nodos. A pesar de este problema, los resultados obtenidos son bastante aceptables. Por último, las imágenes que se muestran en las secciones siguientes se obtienen al guardar el fotograma en el que se realiza un cambio de nodo.. 32.

(39) 5.2.1. Recorrido 1. Figura 5.4: Muestra de fotogramas del vı́deo 1 mostrando diferentes nodos Estos fotogramas (Figura 5.4) son resultado de utilizar el algoritmo sin dividir los nodos posibles en subgrupos para la clasificación. Esto es, se ha clasificado todo el rato con todo el mapa al mismo tiempo. Se puede ver que se han localizado cada uno de los nodos de forma correcta, y no se han encontrado errores ni falsos positivos. También se ha realizado la prueba dividiendo el mapa en subconjuntos de radio 1, vecino más próximo, pero no existen diferencias funcionales entre ambas pruebas, ya que no hay errores ni falsos positivos que afinar, con lo que no se incluye dicha versión de las fotos.. 33.

(40) 5.2.2. Recorrido 2. Figura 5.5: Muestra de fotogramas del vı́deo 2 mostrando diferentes nodos Los fotogramas que encontramos en la Figura 5.5 resultan de aplicar el algoritmo con la división por grupos de radio 1. Este vı́deo es un buen ejemplo para apreciar visualmente una ventaja que tiene dicha división frente al uso de todo el conjunto de los nodos. Como se puede ver, los nodos están localizados adecuadamente en sus posiciones correctas. No existen errores ni falsos positivos. Sin embargo, si realizasemos la prueba utilizando todo el conjunto al mismo tiempo, aparte de estos fotogramas, nos encontrarı́amos con la imagen mostrada en la figura 5.6 Lo que sucede con esta imagen es que, utilizando la división por grupos de nodos, al llegar a este punto el nodo ’Esc’ no está disponible como clase para clasificar, con lo que no da el falso positivo en esa zona, al contrario de la prueba que utiliza todos los nodos a la vez.. 34. Figura 5.6: Falso positivo.

(41) 5.2.3. Recorrido 3. Figura 5.7: Muestra de fotogramas del vı́deo 3 mostrando diferentes nodos Tal como se ha visto en el recorrido anterior una ventaja que tiene la división en subgrupos sobre el uso de todo el mapa, ahora vamos a ver un inconveniente de dicho método. Se puede ver en las imágenes de la Figura 5.7 que cada uno de los nodos del mapa está clasificado en su lugar correspondiente, sin errores. Sin embargo, si nos fijamos se puede apreciar que el nodo que se muestra anteriormente al nodo ’Esc’, abajo a la derecha de su imagen, tenemos el nodo ’Ent’, lo cual no deberı́a ser correcto, ya que no son nodos contiguos. Esto se debe al falso positivo que encontramos en la figura 5.8. En el caso de utilizar todo el mapa para clasificar, como es el caso en estas imágenes, Figura 5.8: Falso positivo el problema no va más allá de un falso positivo. Sin embargo, si tenemos un subconjunto de radio 1, nos encontramos que no encuentra los nodos posteriores, ya que no están en el conjunto de clasificación.. 35.

(42) Capı́tulo 6 Conclusiones Como se ha podido ver en el apartado anterior, se ha conseguido identificar un recorrido completo de la ruta utilizando el sistema desarrollado. De todas formas, hay que tener en cuenta que el método no es perfecto, y que existen aún formas de mejorarlo. El principal inconveniente que se le puede encontrar, siendo más o menos general en la mayor parte de los sistemas que usen reconocimiento directo de imágenes basado en color, es que puede dar problemas en espacios al aire libre, debido a la variación de luminosidad a lo largo del dı́a. En nuestro caso, la mayorı́a de los nodos están en espacios cerrados, luego no afecta demasiado. Con el fin de mejorar el sistema sin realizar un cambio completo del método, se describieron algunas posibilidades en el apartado de aplicación del algoritmo. Sin embargo, se pueden idear más métodos que pueden dar buenos resultados, aunque no han sido probados. Por ejemplo, crear un nuevo umbral de distancia, no al vecino más próximo, si no en función de los k vecinos más próximos, dependiendo del nodo de pertenencia. Otra opción ya mencionada son los distintos umbrales por nodo. Se podrı́a crear un algoritmo para calcular la mejor opción en función de la zona del mapa. También, si se montara el sistema en un robot con sistema de odometrı́a, se podrı́an utilizar dichas medidas para variar los umbrales de forma dinámica. Si quisiéramos ya mayor precisión, se podrı́a utilizar otro algoritmo de reconocimien36.

(43) to distinto, como tratar de reconocer objetos particulares de la imagen. Sin embargo, dado que los resultados obtenidos con el algoritmo utilizado son aceptables, no se ha considerado llegar más allá.. 37.

(44) Apéndice A Portabilidad a Android Una de las ideas del proyecto era el funcionamiento de la aplicación en una plataforma portátil, de forma que se pueda realizar con facilidad la identificación y localización de los lugares en tiempo real. Para ello, se ha trabajado en adaptar el código de clasificación desarrollado a una plataforma con sistema Android. El desarrollo en pc ha sido utilizando Python, con lo que, para realizar pruebas preliminares de funcionamiento en la plataforma, se ha intentado realizar un port lo más directo posible del código Python desarrollado. Para ello se ha utilizado Kivy, una librerı́a de código abierto que permite el desarrollo de aplicaciones multiplataforma con Python de forma sencilla. Para el funcionamiento correcto de la aplicación ha sido necesario reconstruir un dataset nuevo, ya que las diferencias de color entre las imágenes obtenidas para construir el dataset original y las imágenes extraı́das de la cámara desde la aplicación hacı́an que fallase la localización. El dataset nuevo es más reducido que el original utilizado para el resto del proyecto, con 200 imágenes por nodo aproximandamente, ya que la aplicación es básicamente una prueba de concepto. Los resultados obtenidos con las pruebas a tiempo real han sido bastante satisfactorios, ya que la capacidad de mover la cámara para enfocar con precisión ayuda en gran medida a la localización. A continuación se presentan varias imágenes de la aplicación en funcionamiento, 38.

(45) ası́ como el código utilizado.. Figura A.1: Muestra de imágenes de la aplicación en los distintos nodos. 39.

(46) A.1 from from from from from. main.py k i v y . app import App k i v y . l a n g import B u i l d e r k i v y . u i x . camera import Camera k i v y . u i x . b o x l a y o u t import BoxLayout k i v y . p r o p e r t i e s import L i s t P r o p e r t y , NumericProperty. import cv2 import numpy as np import c o l l e c t i o n s from mapa import ∗. c l a s s Cam( Camera ) : def. i n i t ( s e l f , ∗∗ kwargs ) : super (Cam, s e l f ) . i n i t (∗∗ kwargs ). def g e t t e x t u r e ( s e l f ) : return s e l f . t e x t u r e def b i n d t e x t u r e ( s e l f , method ) : s e l f . camera . bind ( o n t e x t u r e=method ). c l a s s C l a s s i f i e r ( BoxLayout ) : t h r e s H Or i g = NumericProperty ( 0 ) symbols = L i s t P r o p e r t y ( [ ] ) def. i n i t ( s e l f , ∗∗ kwargs ) : super ( BoxLayout , s e l f ) . i n i t. (∗∗ kwargs ). s e l f . i d s . camera . b i n d t e x t u r e ( s e l f . c l a s s i f y ) s e l f . t h r e s H O r ig = 0 . 0 0 0 5 5 s e l f . graph = mapLoader ( ’ . / mapaSec . map ’ ) 40.

(47) self self self self. . c l a s s i f i e r = cv2 . KNearest ( ) . oldNode = Node ( ” P l a c e H o l d e r ” ) . workingNode = Node ( ” P l a c e H o l d e r ” ) . usingNodes = s e l f . graph . n o d e L i s t. s e l f . d a t a s e t = None s e l f . group = None for i in range ( len ( s e l f . graph . n o d e L i s t ) ) : s i z e = s e l f . graph . n o d e L i s t [ i ] . imageData . shape [ 0 ] s e l f . usingNodes . append ( s e l f . graph . n o d e L i s t [ i ] ) nGroup = np . a r r a y ( [ i ] ∗ s i z e ) . r e s h a p e ( ( s i z e , 1 ) ). i f s e l f . d a t a s e t == None : s e l f . d a t a s e t = s e l f . graph . n o d e L i s t [ i ] . imageData s e l f . group = nGroup else : s e l f . d a t a s e t = np . c o n c a t e n a t e ( ( s e l f . d a t a s e t , s e l f . graph . n o d e s e l f . group = np . c o n c a t e n a t e ( ( s e l f . group , nGroup ) ) s e l f . c l a s s i f i e r . t r a i n ( s e l f . d a t a s e t , s e l f . group ). def c h a n g e t h r e s H ( s e l f , num ) : s e l f . t h r e s H O r ig += num def g e t t e x t u r e ( s e l f ) : s n a p s h o t = s e l f . i d s . camera . g e t t e x t u r e ( ) i f snapshot : img = np . f r o m s t r i n g ( s n a p s h o t . p i x e l s , dtype=np . u i n t 8 ) a = np . r e s h a p e ( img , ( 4 8 0 , 6 4 0 , 4 ) ) return a return s n a p s h o t def c l a s s i f y ( s e l f , ∗ l a r g s ) : neighN = 1 thresH = s e l f . t h re s H O r i g image = s e l f . g e t t e x t u r e ( ) 41.

(48) i f image == None : return −1 gray = cv2 . c v t C o l o r ( image , cv2 .COLOR RGB2GRAY) h i s t = cv2 . c a l c H i s t ( [ gray ] , [ 0 ] , None , [ 2 5 6 ] , [ 0 , 2 5 6 ] ) normhist = h i s t / f l o a t (sum( h i s t ) ) normhist = np . a r r a y ( [ normhist . r a v e l ( ) ] ) . a s t y p e ( np . f l o a t 3 2 ) i f s e l f . workingNode . name != s e l f . oldNode . name : s e l f . oldNode = s e l f . workingNode s e l f . usingNodes = [ s e l f . workingNode ] s e l f . d a t a s e t = s e l f . workingNode . imageData s e l f . group = np . a r r a y ( [ 0 ] ∗ s e l f . d a t a s e t . shape [ 0 ] ) . r e s h a p e ( ( s e l f . count = 1 for node in s e l f . graph . a d j a c e n t [ s e l f . workingNode . name ] : s i z e = node [ 0 ] . imageData . shape [ 0 ] s e l f . usingNodes . append ( node [ 0 ] ) nGroup = np . a r r a y ( [ count ] ∗ s i z e ) . r e s h a p e ( ( s i z e , 1 ) ). s e l f . d a t a s e t = np . c o n c a t e n a t e ( ( s e l f . d a t a s e t , node [ 0 ] . imageDa s e l f . group = np . c o n c a t e n a t e ( ( s e l f . group , nGroup ) ) count += 1 s e l f . c l a s s i f i e r . t r a i n ( s e l f . d a t a s e t , s e l f . group ). r e t , r e s u l t s , n e i g h b o u r s , d i s t = s e l f . c l a s s i f i e r . f i n d n e a r e s t ( normh temp = r e s u l t s [ 0 , 0 ] symbols = [ s e l f . workingNode . name ]. i f d i s t < [ [ thresH ] ] and s e l f . usingNodes [ int ( temp ) ] . name != s e l f . wo symbols . append ( s e l f . usingNodes [ int ( temp ) ] . name ) s e l f . workingNode = s e l f . usingNodes [ int ( temp ) ]. 42.

(49) symbols . append ( s t r ( d i s t ) ) symbols . append ( s e l f . usingNodes [ int ( temp ) ] . name ) s e l f . symbols. = symbols. c l a s s ClassCamera (App ) : def b u i l d ( s e l f ) : c l a s s i f i e r = C l a s s i f i e r () return c l a s s i f i e r if. name. == ’. main. ’:. ClassCamera ( ) . run ( ). 43.

(50) A.2. mapa.py. # −∗− c o d i n g : u t f −8 −∗− import c P i c k l e as p i c k l e. c l a s s Mapa : init ( self ): def s e l f . nodeList = [ ] s e l f . a d j a c e n t = {} def addNode ( s e l f , node , a d j L i s t ) : s e l f . n o d e L i s t . append ( node ) s e l f . a d j a c e n t [ node . name ] = a d j L i s t def saveMap ( s e l f , f i l e n a m e ) : with open ( f i l e n a m e , ’wb ’ ) as output : p i c k l e . dump( s e l f , output , p i c k l e .HIGHEST PROTOCOL) c l a s s Node : i n i t ( s e l f , name = ”” ) : def s e l f . name = name s e l f . imageData = ’ ’. def mapLoader ( f i l e L o c ) : graph = ’ ’ with open ( f i l e L o c , ’ rb ’ ) as input : graph = p i c k l e . l o a d ( input ) return graph. 44.

(51) A.3. classcamera.kv. < C l a s s i f i e r >: orientation : ’ vertical ’ Cam: i d : camera r e s o l u t i o n : ( 6 4 0 , 4 80) play : False Label : t e x t : ’\\ n ’ . j o i n (map( r e p r , r o o t . symbols ) ) s i z e h i n t y : None h e i g h t : ’ 1 0 0 dp ’ ToggleButton : t e x t : ’ Play ’ o n p r e s s : camera . p l a y = not camera . p l a y s i z e h i n t y : None h e i g h t : ’ 4 8 dp ’ BoxLayout : s i z e h i n t y : None h e i g h t : ’ 4 8 dp ’ Button : t e x t : ’ Decrement ’ o n p r e s s : r o o t . c h a n g e t h r e s H ( −0.00001) Label : t e x t : s t r ( r o o t . t h r e s H Or i g ) Button : t e x t : ’ Increment ’ on press : root . change thresH (0.00001). 45.

(52) Bibliografı́a [1] Dijkstra, E. W. (1959). A note on two problems in connexion with graphs. Numerische mathematik, 1(1), 269-271. [2] Hart, P. E., Nilsson, N. J., Raphael, B. (1968). A formal basis for the heuristic determination of minimum cost paths. IEEE transactions on Systems Science and Cybernetics, 4(2), 100-107. [3] de Lope, J. “Arquitecturas de Robots Moviles.̈ Apuntes de la asignatura Robots Autonomos del MUIA, curso 2015-2016 [4] Maravall, D. N̈avegacion mediante Mapas Topológicos visuales.̈ Apuntes de la asignatura Robots Autónomos del MUIA, curso 2015-2016 [5] Maravall, D., de Lope, J., Fuentes, J. P. (2015, June). Visual Bug Algorithm for Simultaneous Robot Homing and Obstacle Avoidance Using Visual Topological Maps in an Unmanned Ground Vehicle. In International Work-Conference on the Interplay Between Natural and Artificial Computation (pp. 301-310). Springer International Publishing. [6] Peterson, L. E. (2009). K-nearest neighbor. Scholarpedia, 4(2), 1883. [7] Thrun, S., Bücken, A. (1996). Learning Maps for Indoor Mobile Robot Navigation (No. CMU-CS-96-121). CARNEGIE-MELLON UNIV PITTSBURGH PA DEPT OF COMPUTER SCIENCE. [8] Trudeau, R. J. (2013). Introduction to graph theory. Courier Corporation.. 46.

(53)

Referencias

Documento similar