Tras una buena cantidad de artículos sobre visión artificial llega
por fin el esperado sigue líneas con visión. Las dificultades que
implica el manejo de imágenes en tiempo real son muchas, sobre todo el
retardo entre que la cámara capta la imagen y nosotros la procesamos y
enviamos los datos por bluetooth. Estamos utilizando la cámara de un
iPhone 3G conectada mediante wifi al ordenador, enviado imágenes gracias
al programa Pocket Cam. Capturamos imágenes periódicamente gracias al
programa Yawcam, y las procesamos con LabVIEW, que finalmente enviará
las ordenes necesarias al NXT mediante Bluetooth.
Funcionalidades que hemos usado:
Si no estáis familiarizados con el LabVIEW os recomiendo que os leáis los artículos de la serie de LabVIEW, sobretodo LabVIEW para usuarios del NXT (I), (II) y (III), así como Manejo de imagenes y shift register en LabVIEW.
El uso de los shift register es fundamental para este programa, pues
lo necesitamos para ser capaces de detectar lineas. Así mismo lo son el
uso de bucles, sentencias case, manejo de imágenes, etc… Necesitaremos
hacer uso de múltiples variables de distintos tipos para ir guardando
valores que necesitaremos posteriormente.
Proceso de captura de imágenes:
El proceso de captura de las imágenes tiene varios pasos. En primer
lugar necesitamos capturar imágenes con el Iphone. Mediante el programa
Pocket Cam podemos capturar imágenes cada segundo por la cámara del
Iphone, y enviarlas por wifi al ordenador. A su vez tenemos otro
programa actuando en el PC denominado YawCam, que se encarga de recoger
estas imágenes enviadas por el Iphone por wifi, y guardarlas en el disco
duro (es capaz de hacerlo a varias imágenes por segundo, aunque debido a
la limitación del Pocket Cam del Iphone de una imagen por segundo
estamos limitados a esa velocidad máxima).
Una vez en disco ya podemos procesarla con LabVIEW, para esto tenemos toda la funcionalidad que explique en Manejo de imagenes y shift register en LabVIEW.
Procesado de la imagen:
Una vez tenemos la imagen ya podemos procesarla. Lo primero es
abrirla y usar la función unbound de clusters para poder acceder al
array donde se encuentran los datos de la imagen. Recorreremos una de
las líneas de la imagen, preferiblemente una intermedia, en busca de la
línea negra. Tendremos que escoger un valor RGB umbral para decidir que
es negro (línea) y que es blanco. Con que todos los valores estén por
debajo de 60 es suficiente. Recordar que no hay que iluminar la línea
negra desde arriba o creará reflejo. Buscaremos en la linea píxeles
negros que estén por debajo del umbral. Para que no detectemos un píxel
aislado como parte de la línea es importante que busquemos secuencias de
varios píxeles negros. Si por ejemplo detectamos 6 píxeles negros
seguidos sabremos que estamos ya sobre la línea.
Una vez que estamos sobre dicha línea seguimos buscando píxeles hasta
que detectemos el otro borde. Tenemos que guardar tanto el número del
primer píxel como el del último píxel de la línea para calcular el punto
medio. Sabiendo ya este punto medio, tenemos que ver su distancia con
el centro de la imagen, cuanto más lejos estemos del centro, más nos
estamos desviando de la línea. Que la diferencia entre el punto medio
calculado y el centro de la imagen sea positivo o negativo indica hacia
que lado nos estamos desviando (derecha o izquierda), y tendremos que
actuar en consecuencia, poniendo en funcionamiento unos u otros motores.
Este proceso se mete dentro de un bucle infinito, al que podremos
poner algún botón de control para pararlo. Mientras el bucle siga en
marcha seguiremos recorriendo la imagen y actuando en consecuencia.
Programa:
El programa es bastante largo, en el hemos usado toda la
funcionalidad descrita en anteriores artículos, como bucles, sentencias
case. shift registers, uso de variables… El programa sigue básicamente
el proceso descrito anteriormente. Aquí podéis ver el Block Diagram:
Y el Front Panel:
Debido al gran retardo entre que la imagen se captura en el Iphone, y
el robot actúa en consecuencia el robot no es perfecto, y se necesita
mover bastante lento para no salirse de la línea. Lo importante es que
es capaz de seguirla. Aquí tenéis un vídeo del experimento:
Espero que os haya gustado, ha sido difícil de implementar, pero ha merecido la pena
No hay comentarios:
Publicar un comentario