• Coche RC autónomo (V) - Instalando OpenCV (visión por computador)

    El siguiente paso en el proyecto de construir un coche RC autónomo es el de instalar las librerías necesarias para poder procesar las imágenes que recibamos de la cámara de la Raspberry Pi. La librería de visión por computador en cuestión es OpenCV, que puede ser usada muy fácilmente mediante programación en Python.

    OpenCV - Raspberry Pi

    La idea principal es instalar la versión más reciente de Python (versión python3.5), así como la versión más reciente de OpenCV (opencv-3.3.0). Aunque existen paquetes en Debian / Ubuntu que se pueden instalar directamente con apt-get, voy a realizar la instalación de forma manual para poder integrar ciertas funcionalidades que no vienen en los paquetes por defecto (además de que no suelen estar actualizados a las últimas versiones).

    Instalaré estas librerías tanto en la Raspberry Pi (ya que lo necesitará el coche para ser completamente autónomo) como en el ordenador (ya que así es más fácil realizar las pruebas). Para ello, seguiré los tutoriales de PyImageSearch - Raspberry Pi y PyImageSearch - Ubuntu 16.04. En el fondo son muy parecidos los dos, por lo que pondré los pasos principales.

    Se va a instalar un entorno virtualizado para Python, lo que nos permitirá acceder a un entorno u otro por si queremos instalar otras versiones de Python (como python2.7). Hay que tener en cuenta que de la versión 2 a la 3 de Python se han realizado muchas actualizaciones no compatibles, por lo que si estás siguiendo este tutorial y usando el código que voy subiendo a Github - jorgecasas/autonomous-rc-car has de tener en cuenta que yo estoy usando la versión python3.5.

    Antes de nada, si no lo hicimos al configurar la Raspberry Pi, tendremos que expandir el sistema de ficheros para ocupar todo el espacio de la tarjeta SD (porque OpenCV requiere más espacio del original). Para ello accedemos a raspi-config y seleccionando la opción de Expand filesystem. Tras guardar los cambios tendremos que reiniciar la Raspberry Pi.

    El primer paso en la instalación es actualizar el sistema y eliminar algún paquete no necesario que ocupa mucho espacio (si es que está instalado). En la Raspberry Pi actualizaremos hasta el firmware, e instalaremos paquetes requeridos de desarrollo:

    sudo apt-get purge wolfram-engine
    sudo apt-get update
    sudo apt-get upgrade -y 
    
    sudo apt-get install build-essential cmake pkg-config
    sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
    sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
    sudo apt-get install libxvidcore-dev libx264-dev
    sudo apt-get install libgtk2.0-dev
    sudo apt-get install libatlas-base-dev gfortran
    sudo apt-get install python2.7-dev python3-dev
    
    

    Instalamos la herramienta pip, que nos permitirá instalar fácilmente paquetes y librerías Python mediante comandos como pip install paquete. Acto seguido instalaremos los paquetes para crear los entornos virtuales de Python que hemos comentado:

    wget https://bootstrap.pypa.io/get-pip.py
    sudo python get-pip.py
    
    sudo pip install virtualenv virtualenvwrapper
    sudo rm -rf ~/.cache/pip get-pip.py
    

    Actualizaremos el fichero ~/.profile (en Ubuntu / Debian el equivalente es ~/.bashrc) con las siguientes líneas al final del todo:

    # virtualenv and virtualenvwrapper
    export WORKON_HOME=$HOME/.virtualenvs
    source /usr/local/bin/virtualenvwrapper.sh
    

    Recargamos el fichero ~/.profile (o ~/.bashrc) con el comando source, o bien cerrando y abriendo un nuevo terminal:

    source ~/.profile
    

    Y creamos un entorno virtual para nuestros procesados. Lo vamos a denominar cv (por Computer Vision), podríamos crear otros entornos con otro nombre y versión de Python (nosotros vamos a usar la 3, como ya hemos comentado):

    mkvirtualenv cv -p python3
    

    Al crear este entorno virtual, nos aparecerá en la línea de comandos (cv) $ para indicar que estamos dentro del entorno virtualizado. Ahora ya lo tenemos creado, por lo que en las próximas ocasiones ya no tendremos que volver a crearlo, simplemente lo activaremos mediante el comando:

    workon cv
    

    Una vez dentro del entorno virtualizado, instalamos los paquetes de desarrollo de Python en la versión 3.5 y la librería numpy.

    sudo apt-get install python3.5-dev
    sudo pip install numpy
    

    Ahora vamos a descargar de Github las fuentes de OpenCV (versión 3.3.0, la más reciente) y OpenCV_contrib (también la versión 3.3.0), para luego compilarla:

    wget -O opencv.zip https://github.com/opencv/opencv/archive/3.3.0.zip
    wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/3.3.0.zip
    unzip opencv.zip
    unzip opencv_contrib.zip
    

    Nos habrá creado dos directorios opencv-3.3.0 y opencv_contrib-3.3.0. Accedemos al directorio opencv-3.3.0 y creamos lo necesario para la compilación. Hay que tener en cuenta tanto las rutas como la versión correspondiente en el parámetro OPENCV_EXTRA_MODULES_PATH del comando cmake:

    cd opencv-3.3.0
    mkdir build
    cd build
    cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_PYTHON_EXAMPLES=ON -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.3.0/modules -D BUILD_EXAMPLES=ON ..
    

    Si todo se ejecuta correctamente, aparecerán unas líneas al final indicando que está instalado Python 3 y que tiene Interpreter, Libraries, numpy y packages path correctos. Si no aparece alguno de ellas (por ejemplo, numpy), es que no está instalada la librería (numpy) o el paquete de desarrollo de python3-dev correspondiente. En estos casos, instalamos el paquete faltante y eliminamos el directorio build y lo volvemos a crear, volviendo a ejecutar cmake.

    Si todo ha ido bien, ejecutamos el siguiente comando mientras nos vamos a tomar un café, porque le costará una hora como mínimo:

    make -j4
    

    Si falla la compilación será debido al parámetro -j4 que hemos usado para indicar que utilice todos núcleos de la Raspberry Pi y se han dado condiciones de carrera. En este caso, tendremos que ejecutar los siguientes comandos y nos vamos a por otro café:

    make clean
    make
    

    Tras compilar, lo instalamos:

    sudo make install
    sudo ldconfig
    

    Accederemos ahora al directorio /usr/local/lib/python3.5/site-packages/ (o al correspondiente a la versión de Python que estemos usando), y veremos que existe un fichero con un nombre similar a cv2.XXXX.so (en mi caso, cv2.cpython-35m-arm-linux-gnueabihf.so. Crearemos un enlace simbólico que apunte a dicha librería y que se llame cv2.so, y lo enlazaremos también desde el directorio de nuestro entorno virtualizado (o no lo encontraremos al importar la librería en dicho entorno):

    cd /usr/local/lib/python3.5/site-packages/
    ln -s cv2.cpython-35m-arm-linux-gnueabihf.so cv2.so
    
    cd ~/.virtualenvs/cv/lib/python3.5/site-packages/
    ln -s /usr/local/lib/python3.5/site-packages/cv2.so cv2.so
    

    Por último probamos que podemos utilizar OpenCV desde Python. Abrimos el intérprete python y ejecutamos en el shell:

    $ python
    Python 3.5.3 (default, Jan 19 2017, 14:11:04)
    
    >>> import cv2
    >>> cv2.__version__
    '3.3.0'
    

    Nos indica así que podemos importar la librería. Si nos diera error, probablemente es que no hemos creado correctamente los enlaces simbólicos de los pasos anteriores.

    En el próximo post veremos cómo utilizar OpenCV desde script Python. ¡Os espero!

    Más información sobre el proyecto

  • Construyendo con Arduino

    Además de estar realizando poco a poco el proyecto Coche RC autónomo, junto con Bruno estamos aprendiendo a realizar pequeños proyectos con Arduino: Aprendemos a programar y un poco de electrónica, además de aprender cómo funcionan las cosas. Por ejemplo, hoy hemos hecho un semáforo

    Arduino

    En Internet hay miles de recursos y tutoriales (además de los mil ejemplos que vienen incluidos en el IDE de programación de Arduino), como pueden ser los blogs y recursos de Programar Fácil, Prometec o Fábrica Digital

    Los proyectos que vayamos realizando los iremos compartiendo en Github - jorgecasas/arduino-projects. En cada carpeta se indica en el fichero README.md los pasos, materiales necesarios… junto con el código para ser cargado y modificado.

    Primeros pasos con Arduino

    Si queremos aprender, además de un Arduino habrá que tener cables, resistencias, algún sensor, diodos led… Hay kits de iniciación Arduino bastante completos (aun siendo clones del Arduino original, de menor calidad… pero para empezar sobra)

    Podemos descargar el IDE de Arduino (o bien directamente desde el IDE web) e instalarlo, o bien desde repositorio. En Ubutnu / Debian:

    sudo apt-get install arduino
    

    Una vez instalado, podemos seleccionar de los menús la placa Arduino que vayamos a utilizar (por ejemplo, Arduino UNO) y cargar el programa de ejemplo Blink (que es tan simple que sólo enciende y apaga el led integrado de la placa, pero que permite comprobar que la comunicación entre el ordenador y la placa es correcta mediante el cable USB). Una vez cargado el programa, pulsando el icono de Cargar / Load del IDE podremos transferir el programa al Arduino, y el led comenzará a parpadear.

    Si tenemos niños pequeños o estamos aprendiendo a programar, podemos realizar la programación mediante bloques (similar a Scratch). Descargamos S4A (Scratch For Arduino) del apartado de descargas. En Ubuntu / Debian es un paquete .deb, por lo que tras su descarga habrá que instalarlo mediante el comando:

    sudo dpkg -i S4A16.deb
    

    En el caso de que dé errores (falta alguna librería), podremos ejecutar el siguiente comando para que se instalen de forma automatizada:

    sudo apt-get install -f
    

    También hay que instalar un firmware adicional para comunicar el Arduino con el IDE S4A. En el apartado de descargas nos descargamos dicho firmware, que no deja de ser un fichero .ino (similar a un proyecto). Lo abriremos con el IDE de Arduino y lo cargaremos en la placa, y una vez cargado podremos abrir ya el IDE S4A para programar mediante bloques.

    Y ahora sólo queda la imaginación (y un poco de tiempo)…

  • Coche RC autónomo (IV) - Configurando la videocámara en la Raspberry Pi

    En esta cuarta entrega del proyecto Construyendo un coche RC autónomo voy a detallar cómo configurar la cámara y sensores infrarrojos en la Raspberry Pi 3 para poder obtener vídeo que procesar. Trataré de poder enviar el vídeo en streaming con la menor latencia / delay posible al ordenador principal utilizando el adaptador WiFi que ya viene incluido en la Raspberry Pi

    Raspberry Pi y la cámara

    Accederemos a la Raspberry Pi mediante SSH (ver post Coche RC autónomo (III)). Tras conectar la cámara a la Raspberry Pi, tendremos que activar el módulo de la cámara en el menú correspondiente de la aplicación de configuración:

    sudo raspi-config
    
    # Y activamos la opción Enable Camera
    

    Grabando vídeos

    Para grabar vídeos de forma manual y ver que todo funciona, podemos ejecutar el siguiente comando:

    raspivid -w 640 -h 480 -vf -b 10000000 -fps 30 -n -o testvideo.h264
    
    • -w: Width (en pixels)
    • -h: Height (en pixels)
    • -o: Nombre del fichero de salida (con extensión .h264)
    • -vf: Voltear verticalmente la imagen (si estamos tomando imágenes boca abajo)
    • -b: Bitrate en bits/segundo (25Mbps = 25000000)
    • -fps: Frames por segundo
    • -n: Desactivar modo de previsualización

    Retransmitiendo en streaming

    Al conectarnos por SSH, queremos visualizar en nuestro ordenador el vídeo en tiempo real. Hay varias formas para enviarlo.

    Por ejemplo, podemos crear scripts (en Python, requiere cargar varias librerías como python-picamera) tanto en el servidor (nuestro ordenador que recibirá las imágenes) como en la Raspberry Pi (cliente con la cámara que enviará las imágenes). De esta forma podremos configurar en el cliente la IP y puerto (que tendrá que estar abierto en el cortafuegos de nuestro ordenador) para visualizar en streaming el vídeo obtenido por la cámara mediante una aplicación como VLC.

    Pero como mi ordenador tiene GNU/Linux, bastará con ejecutar los siguientes comandos en nuestro ordenador (servidor) y en la Raspberry Pi (cliente). La idea es que el ordenador (que tiene la IP 192.168.1.100) escuche por el puerto 8000 lo que le vaya enviando la Raspberry Pi. Este método es muy sencillo pero puede producirse demasiado lag en la visualización de las imágenes en el ordenador de control de incluso varios segundos si se utiliza la aplicación vlc, por lo que habrá utilizar en su lugar mplayer con los siguientes parámetros de configuración:

    # Comando para el servidor (nuestro 
    # ordenador) a 6 frames por segundo para 
    # que en cuanto lleguen imágenes de la 
    # Raspberry Pi (que emite a 30fps) las muestre
    nc -l 8000 | mplayer -fps 60 -cache 1024 -
    
    # Comando para el cliente (Raspberry Pi 
    # con la cámara, donde 192.168.1.100 es la 
    # IP del ordenador, con -t 0 para duración ilimitada)
    raspivid -w 640 -h 480 -t 0 -o - | nc 192.168.1.100 8000
    

    El resultado será el siguiente: Un terminal donde hemos arrancado nuestro servidor de vídeo utilizando netcat (nc) para recibir las imágenes, un terminal conectado mediante SSH a la Raspberry Pi donde habremos arrancado el envío de vídeo al servidor (nuestro ordenador) y una pantalla de mplayer donde veremos en tiempo real lo que vaya viendo y enviando mediante la red WiFi el coche autónomo.

    Martina programando la cámara

    Si da error en el ordenador indicando Failed to open VDPAU backend libvdpau_va_gl.so: no se puede abrir el archivo del objeto compartido, se soluciona instalando los siguientes paquetes:

    sudo apt-get install libvdpau-va-gl1
    

    Asimismo, si no tenemos instalado mplayer, lo podemos instalar fácilmente:

    sudo apt-get install mplayer
    

    Podéis encontrar muchísima más información sobre el uso de la cámara y ejemplos prácticos en el ejemplar de la revista MagPi - Camera Module Essentials.

    En los próximos posts del proyecto se detallará cómo acceder al streaming de la cámara usando Python para ser analizado con OpenCV. ¡Os espero!

    Videocámara en acción

    Más información sobre el proyecto