Resumen del proyecto 4




descargar 419.67 Kb.
títuloResumen del proyecto 4
página9/14
fecha de publicación28.11.2015
tamaño419.67 Kb.
tipoResumen
med.se-todo.com > Derecho > Resumen
1   ...   6   7   8   9   10   11   12   13   14

3.2Localización mediante visión artificial

3.2.1Introducción


La primera decisión que tuvimos que tomar llegados a la etapa de implementación fue si debíamos implementar nosotros mismos los algoritmos de tratamiento de imagen y captura de vídeo desde una cámara o si utilizábamos los ofrecidos por alguna librería.

Al final nos decantamos por utilizar las funciones ofrecidas por alguna librería de código abierto para así ahorrarnos tiempo en la implementación de los algoritmos. Otra de las razones por las que decidimos utilizar librerías fue la mayor fiabilidad y eficiencia que ofrecen sus algoritmos si la librería es robusta y contrastada.

La necesidad de disponer de un paquete de visión por computador y procesamiento de imágenes lo suficientemente flexible y potente como para proporcionar herramientas de alto nivel para el desarrollo de nuestro sistema de localización propició una búsqueda incesante de software que cumpliera dichas características y sobre todo que fuese gratuito, estuviese soportado/revisado por personal cualificado y además se le intuyese una larga vida. Al principio tuvimos algunos problemas que comentamos más extensamente en el apartado 3.2.5, ya que no conseguíamos dar con la librería adecuada.

Después de investigar bastante y de encontrarnos con multitud de problemas como ya hemos comentado, al final escogimos la librería de código abierto OpenCV (Intel® Open Source Computer Vision Library).

Esta librería proporciona un marco de trabajo de alto nivel para el desarrollo de aplicaciones de visión por computador en tiempo real: estructuras de datos, procesamiento y análisis de imágenes, análisis estructural, etc. Este marco de trabajo facilita en gran manera la implementación de distintas técnicas de visión por computador, aislando al desarrollador de las peculiaridades de los distintos sistemas de visión.

Además, es la única librería gratuita de las que conseguimos encontrar que proporciona bibliotecas de tipos de datos estáticos y dinámicos (matrices, grafos, árboles, etc.), herramientas con la posibilidad de trabajar con la mayoría de las capturadoras/cámaras del mercado, entornos de desarrollo fáciles e intuitivos y todo ello, corriendo en dos de los sistemas operativos más utilizados del mundo Microsoft® Windows y Linux, un requisito imprescindible para nuestro proyecto. Se puede encontrar más información sobre esta librería en el apéndice A.

Una vez que teníamos clara la especificación y diseño de nuestro sistema y las herramientas necesarias para implementarlo, comenzamos la fase de implementación que explicamos con más detalle a continuación para cada una de las partes principales en que hemos dividido el sistema.

3.2.2Captación de imágenes


El fin perseguido por esta parte de la aplicación es obtener imágenes a partir de una cámara conectada al sistema. Es una tarea fundamental, ya que sin ella, el programa no puede comenzar.

La implementación de esta parte es la que más problemas nos dio, por la dificultad de encontrar unas librerías que se adaptasen a nuestros requisitos. Esta parte se explica de forma más detallada en el apartado 3.2.5.1 Problemas encontrados. Se realizaron diversos prototipos con muchas librerías pero ninguno de ellos se ajustaba a nuestro objetivo de forma totalmente precisa. El mejor resultado lo obtuvimos con unas librerías realizadas por unos compañeros de años anteriores, pero su integración con nuestro sistema resultaba demasiado complicada, además de complicar el diseño e implementación del mismo por lo que decidimos abandonar esta alternativa.

Finalmente, conseguimos encontrar la solución con la misma librería que utilizábamos para el tratamiento de la imagen. Esto hecho hizo que la unión entre la parte de captación de imágenes y la parte de preprocesamiento fuese más sólida, sencilla y eficiente y que sus barreras fronterizas estuviesen más cercanas.

Una vez dispusimos de una librería que se ajustaba perfectamente a nuestros requisitos comenzamos la implementación definitiva de este apartado. Esta implementación fue realizada de forma incremental, de manera que comenzó con un prototipo básico que después se fue refinando y mejorando para conseguir llegar a la mejor solución para el problema de la forma más sencilla posible.

El hecho de disponer de una buena librería hizo que la implementación final sea bastante robusta, sencilla y fácil de comprender para cualquier posterior desarrollador que necesite comprenderla. A continuación, explicamos los pasos seguidos para llevar a cabo esta tarea:

  1. Iniciar la captura desde la webcam. Para ello utilizamos la función cvCaptureFromCAM de la librería OpenCV. De esta forma, la webcam comienza la captura de vídeo de forma permanente hasta la finalización del programa. Si por algún motivo esta captura no se consiguiese iniciar, se mostraría por pantalla el correspondiente aviso.

  2. El siguiente paso es comenzar la ejecución de un bucle infinito que se repite cada 200 ms (5 veces por segundo) y que finaliza cuando termina la ejecución de la aplicación. Cómo ya comentamos anteriormente, la frecuencia de repetición del bucle puede aumentarse o disminuirse para adaptarse a situaciones concretas.

  3. Dentro del bucle, obtenemos un frame de la captura que será la imagen a la que le serán aplicadas las distintas técnicas de tratamiento.

  4. Liberación en memoria de las imágenes una vez que han sido tratadas y sabemos perfectamente que nos las vamos a volver a utilizar.

  5. Vuelta al paso 2.

  6. Al finalizar el bucle detenemos la captura y la liberamos de memoria.


Como se puede observar, se obtienen 5 imágenes por segundo. Estas imágenes serán procesadas con las técnicas que se explican en el siguiente apartado y son las que servirán a nuestra aplicación para obtener la orientación y la posición en cada momento.

Es muy importante liberar la memoria cada vez que no se vaya a utilizar más una imagen. De lo contrario, esta imagen permanecerá en memoria de forma indefinida. Al cabo de un tiempo, todas las imágenes capturadas se encontraran en memoria, y llegará un momento en que no quede espacio libre. El sistema se puede volver inestable, incluso detener su ejecución por falta de memoria. En las primeras versiones que implementamos no tuvimos esto en cuenta de forma estricta. Esto ocasionaba que cuando la aplicación llevaba un tiempo en funcionamiento, el computador que la albergaba se quedaba sin memoria y se producía un error de memoria insuficiente. Por ello resaltamos la importancia de este factor.

3.2.3Preprocesamiento e interpretación de imágenes


La imagen que nos llega del apartado anterior tiene que ser tratada para conseguir identificar las líneas rectas que se encuentran en ella, ya que estas líneas son las que nos ayudarán a deducir la posición y la orientación en la que nos encontramos en cada momento.

La implementación de este apartado ha sufrido diversos cambios y modificaciones desde su comienzo hasta su implementación final debido a que según comenzábamos a implementar los primeros diseños llegábamos a resultados poco satisfactorios y que tenían que ser mejorados.

La primera implementación realizada con la librería OpenCV obtenía buenos resultados. Sin embargo, no era lo suficientemente robusta cómo nos hubiese gustado y decidimos mejorarla, primero rehaciendo el diseño y después implementando este nuevo diseño mejorado. Los principales puntos débiles de esta primera implementación eran los siguientes:

  • Se trataba de una implementación bastante complicada, ya que había que distinguir multitud de casos dependiendo del tipo de imagen.

  • La luz afectaba mucho a la hora de detectar los bordes.

  • Los dos factores anteriores unidos a otros hacían que en algunas imágenes no se detectasen todas las líneas rectas posibles, o que se detectasen como líneas rectas partes de la imagen que no lo eran.

El nuevo diseño, mejoraba prácticamente todos los puntos débiles comentados arriba y por ello fue el que finalmente se siguió para la implementación definitiva. A continuación, explicamos con más rigor los detalles de esta nueva implementación. Es una implementación más sencilla y que consigue una solución a nuestro problema bastante fiable. Consta de las siguientes partes:

  1. Convertir la imagen a escala de grises. Este paso es necesario porque las imágenes en color utilizan 3 matrices para almacenarse (R, G, B). Cómo en nuestro caso, nos es indiferente el color, trataremos con una imagen en escala de grises que ocupa menos espacio y es más sencillo su tratamiento.

  2. Obtener el histograma de la imagen y la varianza. Este paso es necesario para distinguir entre distintos tipos de imágenes. Por ejemplo una imagen tomada debajo de un fluorescente tendrá una varianza mayor que otra que no esté influenciada por ninguna fuente de luz.

  3. A continuación aplicamos un suavizado Gaussiano para reducir el ruido. Es importante para que el algoritmo de detección de bordes sea más efectivo.

  4. Después, empleamos el algoritmo de detección de bordes de Canny. En la primera implementación probamos con dos algoritmos diferentes, el operador de Sobel y la Laplaciana. Sin embargo, después de utilizar el algoritmo de Canny nos dimos cuenta que se comportaba mejor y además se adaptaba perfectamente al nuevo diseño. Este paso es muy importante ya que dependiendo de su resultado, se podrán detectar mejor o peor las rectas de la imagen con las que realizaremos el cálculo de la posición y la orientación.

  5. Una vez detectados los bordes de la imagen, ya sólo queda averiguar cuales de ellos son líneas rectas. Para ello utilizamos la transformada de Hough. Esta función devuelve todas las líneas rectas encontradas en una estructura llamada lineas de tipo CvSeq*.

Para resolver cada uno de los apartados anteriores, utilizamos una serie de funciones de la librería OpenCV y otras definidas por nosotros que están especificadas en el apartado 2.4.3 y que hacen uso también de las funciones que ofrece la librería. Vamos a comentar de forma más detallada su implementación:

  • funHistograma (imagen) » Se define el rango del histograma (256 niveles de gris) y una estructura de tipo CvHistogram* proporcionada por la librería. Posteriormente se llama a la función de la librería que calcula el histograma pasándole como parámetro la imagen y el histograma. Una vez obtenido el histograma calculamos la varianza asociada mediante la siguiente fórmula:



  • funBordes (imagen, umbralCanny1, umbralCanny2) » Definimos una imagen auxiliar con un tamaño acorde con el soportado por la función CvCanny ofrecida por la librería donde clonamos la imagen original. Posteriormente definimos otra imagen a la que denominamos imagenBordes que será la imagen resultante de aplicar el algoritmo de Canny sobre la imagen original. Para finalizar llamamos a la función CvCanny con la imagen auxiliar, imagenBordes y los umbrales especificados.

  • funHough (imagen, umbralHough) » Definimos una imagen auxiliar con un tamaño acorde con el soportado por la función CvHoughLines2 ofrecida por la librería donde clonamos imagenBordes. Después llamamos a la función con los parámetros necearios y almacenamos su salida en la variable lineas comentada anteriormente.

  • funDibujarLineas (imagen, rectas) » Recorre las rectas devueltas por el algoritmo de Hough, obtiene dos puntos de cada una de ellas y las dibuja en la imagen con la función CvLine.

  • funBrilloContrast (imagen, brillo, contraste): Esta función no es utilizada en la implementación final del algoritmo pero si que se utilizó en las primeras versiones. Sin embargo nos ha parecido interesante mantenerla, ya que puede resultar útil en un futuro. El algoritmo utilizado en esta función es muy parecido al utilizado en el conocido programa de retoque de fotográfico Photoshop.

    Una vez completada esta parte, disponemos de todo lo necesario para realizar el cálculo de la posición y la orientación que se comenta en el siguiente apartado.

3.2.4Cálculo de la posición y la orientación


El objetivo final de un sistema de localización es informar de la posición y orientación en la que se encuentra en cada momento. En los dos subapartados siguientes explicamos cómo nuestro sistema realiza esta tarea realizando una distinción entre el cálculo de la orientación y el de la posición.

3.2.4.1Cálculo de la orientación


Como ya se ha comentado anteriormente en esta memoria, la orientación devuelta por nuestra aplicación, se expresa en referencia a una orientación inicial. Si se produce un giro hacia la izquierda, la orientación irá disminuyendo hasta alcanzar el mínimo de -180º y si gira hacia la derecha la orientación aumentará hasta alcanzar un máximo de 180º. Toda la especificación y diseño de esta parte se encuentran en el apartado 2.4.4.1. A continuación mostramos la implementación del algoritmo en pseudocódigo:

orientación = orientación anterior

{Inicializamos minDist con la distancia entre la orientación anterior y la primera recta}

minDist = Distancia entre la orientación anterior y la orientación de la

primera línea detectada por la transformada de Hough
{Recorremos todas las rectas detectadas por el algoritmo de Hough}

para i = 0 hasta (total de líneas) hacer
theta = ángulo de la recta i (entre 0º y 180º);

theta2 = -(180º - theta);
si ((-10 <= orientación <= 10) OR (orientacion >= 170) OR

orientación <= -170)) entonces {La orientación se encuentra próxima a 0º ó a 180º por lo que podría cambiar de signo}
{Comprobamos si la distancia entre alguno de los ángulos con la orientación anterior es menor que minDist y en caso afirmativo minDist cambiará de valor}

si ((abs(theta - abs(orientacion)) <= (minDist)) OR

(abs(abs(theta2) - abs(orientacion)) <= (minDist))) entonces

si (abs(theta - abs(orientacion)) < abs(abs(theta2) –

abs(orientacion))) entonces {Comprobamos cual de los dos ángulos de la recta está más próximo a la orientación anterior}

minDist = abs(theta - abs(orientacion));

sino

minDist = abs(abs(theta2) - abs(orientacion));

fsi

fsi

sino si (orientacion > 0) entonces {La orientación es positiva y no está próxima a 0º ni a 180º, por lo que la nueva orientación seguirá siendo positiva}

si ((abs(theta - abs(orientacion)) <= (minDist)))

entonces

minDist = abs(theta - abs(orientacion));

fsi;
sino {La orientación es negativa y no está próxima a 0º ni a 180º, por lo que la nueva orientación seguirá siendo negativa}
si ((abs(abs(theta2) - abs(orientacion)) <= (minDist)))

entonces

minDist = abs(abs(theta2) - abs(orientacion));

fsi

fsi

fpara
orientación nueva = orientación de la línea que minimiza minDist;
Una vez implementado el algoritmo es importante darse cuenta de que cuando la cámara gira hacia la izquierda, la foto que captura gira hacia la derecha, por lo que la orientación obtenida no es la real, sino que está cambiada de signo. La solución a este problema es trivial y consiste en multiplicar por -1 la orientación obtenida.

Para el cálculo de la posición es imprescindible conocer la orientación en la que nos encontramos.

3.2.4.2Cálculo de la posición


El algoritmo de cálculo de posición tiene cuatro partes claramente diferenciadas:

  • Calculo del punto de referencia. Supone hallar el punto de corte de rectas perpendiculares más cercano al robot.

  • Seguimiento de un punto de referencia anterior.

  • Calculo de la fiabilidad en cada paso.

  • Seguimiento de balizas absolutas.

El cálculo del punto de referencia más cercano al robot, tenemos que realizar dos pasos:

Primero se calcula la ecuación de la recta más cercana al robot y si se encuentra una recta, se busca la siguiente recta más cercana al robot que forme con la anterior alrededor de 90º. El cálculo de la recta más cercana al robot se hace siguiendo el esquema ilustrado a continuación:



A continuación, se halla el punto de corte de las dos rectas encontradas.

Para realizar el seguimiento de un punto de referencia, debemos realizar el seguimiento de las rectas con las que se calculo dicho punto. Para ello, suponiendo que en la iteración anterior se guardaron los parámetros de las rectas halladas, se procede buscando la primera recta, y si se encontró, entonces se busca la segunda.

Cada recta se busca como muestra el siguiente esquema de bloques:



Si se han encontrado las dos rectas, se busca el punto de corte de ambas.

La medida de similitud aplicada, tanto para rho como para theta, se puede configurar de forma dinámica en un fichero XML, ya que la distancia entre dos rectas depende tanto del retardo entre dos capturas consecutivas como de la velocidad del Robot.

El cálculo de la fiabilidad del algoritmo es una tarea sencilla, ya que se conocen las dos causas por las que el algoritmo podría obtener mediciones erróneas, estudiadas en la fase de análisis y diseño.

Si se pierde un punto de referencia debido a que en la nueva imagen no aparecen rectas similares a las halladas en la iteración anterior, y por lo tanto debiendo recalcular un punto de referencia nuevo perdiendo el posible incremento en la posición de esa captura, la fiabilidad debe disminuir.

Si en la imagen no hay rectas con las que calcular los puntos de corte, entonces evidentemente, no podremos realizar el seguimiento del punto de referencia anterior ni tampoco recalcular un punto de referencia nuevo, con lo cual la fiabilidad debe disminuir en mayor medida que en el caso anterior.

La disminución de fiabilidad es configurable mediante un XML, ya que al igual que ocurría con la medida de similitud, la magnitud del error de cálculo del algoritmo si se da una de las causas anteriores, es directamente proporcional a la velocidad que tenga el móvil que integre nuestro sistema y al retardo entre la captura de dos imágenes consecutivas. Se detallará este punto en el apartado de integración del sistema de visión.

Como se ha comentado en el apartado de especificación y diseño, nuestro sistema de visión es completamente autónomo, pero necesita un cálculo de posición aproximado aportado por una fuente externa para suplir los errores de cálculo cometidos cuando se da alguna de las situaciones de error comentadas anteriormente. Para integrarlo en el robot del museo, se ha considerado que la fuente externa que aporta dicho cálculo aproximado sea la combinación de los encoders y la brújula. Se detallará este punto también en el apartado de integración del sistema de visión.

El seguimiento de balizas absolutas debe ser configurable de forma dinámica, con lo cual se ha generado un fichero XML, que es leído por la aplicación al comienzo de la ejecución.







foco_1




foco_2




foco_3






Cada foco tiene un nombre asociado, para una depuración más cómoda del algoritmo, y posee cuatro argumentos.

Los dos primeros definen una de las esquinas del foco, en concreto la más cercana al punto origen del mapa que representa el mundo en que el robot se mueve. Los dos siguientes definen el punto opuesto en la diagonal que une ambos puntos.



Cuando encontramos una captura con varianza mayor que 6900, buscamos qué foco es el más cercano a la posición actual calculada, y de ese foco, a qué punto estamos más próximos, reconfigurando la posición calculada del robot a la posición del foco con fiabilidad 100%.

A continuación se muestra un esquema de bloques general que integra las cuatro partes del sistema funcionando en conjunto:


3.2.5Problemas encontrados

3.2.5.1Problemas en la captación de imágenes


El primer problema al que nos enfrentamos dentro de este proyecto de visión artificial fue de nivel tecnológico: debíamos encontrar la forma de manipular en nuestro propio software una fotografía tomada por la webcam que habíamos comprado. Para ello los bytes que componen la fotografía deberían estar situados en una estructura tratable.

Evidentemente, se trataba de investigar en profundidad para descubrir alguna librería de libre distribución que ofreciera este servicio. La tarea no fue nada fácil, debido a que casi todo el código encontrado estaba destinado a Visual Basic. Además, la librería debería ser válida tanto para Windows como para Linux.

Inicialmente un profesor de la Facultad de Informática nos recomendó utilizar la librería “avicap32.dll” de Windows, pero la documentación al respecto era escasa. Se probaron algunos códigos fuente de aplicaciones libres de internet, pero no llegaron a ser operativos. Incluso se pidió ayuda a un departamento de Robótica de la Universidad de Sevilla, ya que buscando en la red descubrimos que hacían cosas similares a lo que estábamos buscando. Esto tampoco resultó.

Después de hacer multitud de pruebas con lo poco que habíamos encontrado, nuestro tutor de proyecto nos remitió a un antiguo alumno de Sistemas Informáticos, ya que éste había trabajado en un problema similar algunos años antes.

En efecto, este alumno había desarrollado en su Proyecto Fin de Carrera una librería bastante completa en C para captar imágenes a partir de una webcam. Esta librería era intuitiva y fácil de utilizar, y válida tanto para Windows como para Linux, lo cual encajaba perfectamente con nuestros requisitos.

Tras estudiar la librería, nos dispusimos a realizar pruebas con ella. Primeramente se desarrolló un prototipo en Borland C++, pero lo interesante era integrarlo en el proyecto del robot. Cuando nos dispusimos a hacer esto, obtuvimos una serie de errores de configuración que nos resultaron realmente difíciles de eliminar. De hecho, en este punto resultó imprescindible la ayuda del autor de la librería.

Sin embargo, al poco tiempo de haber conseguido integrarla en el proyecto, otro componente de nuestro grupo de trabajo, que a la vez estaba investigando sobre librerías de tratamiento de imágenes, descubrió que la librería OpenCV podía obtener de manera cómoda una estructura con la información de una fotografía de la webcam. Por lo tanto, y teniendo en cuenta que esta última librería además resultaba de gran utilidad para otros aspectos del proyecto, decidimos finalmente hacer uso de la misma.

3.2.5.2Problemas en el preprocesamiento e interpretación


Uno de los principales problemas que tuvimos para dar con una buena solución consistió en las dificultades para encontrar una librería potente, sencilla, gratuita y fiable que se adaptase a nuestras necesidades. Tampoco queríamos que la inclusión de la librería en el proyecto implicase la instalación de otras tecnologías adicionales que lo harían más complicado.

Antes de decantarnos por OpenCV realizamos algunas primeras implementaciones con librerías tales como VIPS o ImageMagik. Las complicaciones encontradas para su utilización así cómo el hecho de que no se correspondían exactamente con nuestras necesidades, hicieron que abandonásemos estos caminos y buscásemos soluciones mejores.

Las razones que nos hicieron decantarnos finalmente por OpenCV se explican en el apartado de introducción 3.2.1.

Otro de los problemas que encontramos en este apartado, es la entrada de luz a la cámara en el momento de realizar la captura, ya que las imágenes captadas en esas circunstancias son muy complicadas de tratar. Se ha intentado que el algoritmo sea lo más robusto posible, pero sería conveniente que la cámara estuviese cubierta por los laterales para así evitar en cierta medida la exposición a la luz que le puede entrar desde por ejemplo las ventanas y evadir casos en los que el algoritmo de tratamiento no sea capaz de reconocer las líneas de forma correcta.

Comentar los problemas con la saturación del puerto USB en la captura de imágenes.
1   ...   6   7   8   9   10   11   12   13   14

similar:

Resumen del proyecto 4 iconResumen del proyecto

Resumen del proyecto 4 iconResumen del proyecto

Resumen del proyecto 4 iconResumen del proyecto

Resumen del proyecto 4 iconResúmen del Proyecto

Resumen del proyecto 4 iconResumen ejecutivo del proyecto 7

Resumen del proyecto 4 iconResumen del proyecto y caracteristicas del sitio

Resumen del proyecto 4 iconResumen el proyecto de investigación se centró en el estudio del aceite esencial de

Resumen del proyecto 4 iconResumen El diseño, desarrollo y divulgación de cocinas solares de...

Resumen del proyecto 4 iconEsquema de proyecto feria de ciencias denominación del proyecto (nombre)

Resumen del proyecto 4 iconResumen El presente proyecto surge como una necesidad de aplicar...


Medicina



Todos los derechos reservados. Copyright © 2015
contactos
med.se-todo.com