Instalación de un Nano Lynx Wireless-N USB 2.0 en una Raspberry Pi

Introducción

Los controladores para los adaptadores NanoLynx Wireless-N USB 2.0 ya se encuentran incluidos en las distribuciones actuales de Linux (Raspbian y DietPi entre otras) para la Raspberry Pi.

En caso de no tenerse se deberán obtener los controladores para rt2800 mediante la instalación del paquete firmware-ralink.

Verificación

Para verificar que el hardware se encuentra instalado y que ha sido reconocido exitosamente se debe ejecutar el siguiente comando.

$ lsusb

    Bus 001 Device 007: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter

Así mismo es conveniente verificar que los controladores necesarios hayan sido cargados exitosamente.

$ lsmod | grep rt2

    rt2800usb         18832    0 
    rt2800lib         81962    1    rt2800usb
    rt2x00usb         11918    1    rt2800usb
    rt2x00lib         47354    3    rt2x00usb,rt2800lib,rt2800usb
    mac80211         594951    3    rt2x00lib,rt2x00usb,rt2800lib
    cfg80211         477515    2    mac80211,rt2x00lib
    crc_ccitt          1620    1    rt2800lib

Configuración

La configuración de la interfaz de red se puede realizar mediante la herramienta de configuración de la red inalámbrica que viene con el sistema operativo o se puede realizar manualmente como se describe a continuación.

Instalar el paquete de wpasupplicant en caso de no tenerse aún.

# apt-get install wpasupplicant

Ejecute el siguiente comando reemplazando la palabra ssid por el identificador de la red inalámbrica a la cual se desea conectar y password por su respectiva contraseña.

$ wpa_passphrase ssid password 

Copie el resultado de la ejecución del comando anterior y agregue (o reemplace) la sección network en el archivo /etc/wpa_supplicant.conf.  Es posible que este archivo esté ubicado en /etc/wpa_supplicant/wpa_supplicant.conf (DietPi Jessie).

# vi /etc/wpa_supplicant.conf

 network={
   ssid="MiRed"
   psk=945609aab2413e64d57daef00eb5fab3acdde716e1e440981c004bc61dccc98c
 }

Para verificar la conexión con la configuración establecida en el paso anterior, ejecute el siguiente comando.  Una vez desee terminar la verificación presione CTRL+C.

$ wpa_supplicant -Dwext -iwlan0 -c/etc/wpa_supplicant.conf

Ajustar la configuración de las interfaces de red para incluir la información de wlan0 agregando la siguiente información.

# vi /etc/network/interfaces

    auto wlan0
    iface wlan0 inet dhcp
    wpa-driver wext
    wpa-conf /etc/wpa_supplicant.conf

Una vez terminados los ajustes, iniciar la interfaz de red para que tome la nueva configuración.

#  ifup wlan0

Finalmente si desea verificar los datos de configuración con los que se encuentra funcionando la interfaz de red inalámbrica ejecutar el siguiente comando.

# wpa_cli status

Recursos

  1. RPi Ralink WLAN devices
    http://elinux.org/RPi_Ralink_WLAN_devices
  2. RPi USB Wi-Fi Adapters
    http://elinux.org/RPi_USB_Wi-Fi_Adapters
  3. Rpi USB check-list (posible solución al bug de desconexión)
    http://elinux.org/Rpi_USB_check-list

Detectando movimiento con GSVideo y Processing

Introducción

De manera análoga a como se realizó inicialmente con OpenCV, se realizó el proceso de detección de movimiento básico utilizando Processing y la librería de GSVideo instalada hace poco.  Esta librería se especializa en la captura, grabación y reproducción del video mas que en su procesamiento así que la manipulación de las imágenes se realiza manualmente con las facilidades que provee el lenguaje.

En términos generales el procedimiento se basa en capturar el video proveniente de la cámara web a través de una instancia de la clase GSCapture provista por la librería GSVideo.  Cada una de las imágenes obtenidas es comparada con la imagen inmediatamente anterior.  De cada uno de sus píxeles se toma el color en forma de tripleta RGB y se determina su cantidad de variación utilizando la fórmula de distancia (función dist en Processing).  De esta manera se determina si en ese punto específico sucedió movimiento o no y es traducido a un píxel de color blano o negro respectivamente.

Screenshot

Imagen de movmiento sobre el objetivo
Imagen de movmiento sobre el objetivo

Enlaces

Detectando movimiento con OpenCV y Processing

Introducción

Una de las características que quería aprender a implementar con OpenCV era la detección de movimiento, esto me permitirá implementar formas de interacción interesantes (y bastante simples de generar) entre el usuario y el sketch a través de la cámara web.

En pocas palabras, la técnica para detectar movimiento que se describe a continuación se basa en generar una imagen monocromática con los píxeles que han cambiado entre dos cuadros del video.  Para hacer esto se siguen los pasos mostrados a continuación.

  1. Obtener una nueva imagen de la cámara web
  2. Invertir la imagen horizontalmente (opcional)
  3. Calcular la diferencia entre la imagen recién obtenida y la almacenada en memoria (recordada)
  4. Procesar la imagen para facilitar su manejo: convertirla a escala de grises, suavizar la imagen y reducir el ruido eliminando los valores demasiado altos o bajos.
  5. Mostrar la imagen de movimiento (opcional)
  6. Recordar la imagen actual para ser procesada nuevamente en la siguiente iteración

opencv.read();

opencv.flip(OpenCV.FLIP_HORIZONTAL);

opencv.absDiff();

opencv.convert(OpenCV.GRAY);

opencv.blur(OpenCV.BLUR, 3);

opencv.threshold(20);

image(opencv.image(), 0, 0);

opencv.remember(OpenCV.SOURCE, OpenCV.FLIP_HORIZONTAL); 

Para verificar si ha sucedido movimiento en una determinada área de la imagen se debe verificar si los píxeles que pertenecen a esa área se encuentran blancos (si hubo) o no.  Esta información se obtiene utilizando el método get(int x, int y) del objeto PImage el cual retorna el color del píxel seleccionado.  Por facilidad se recomienda que se obtenga el brillo (brightness(color)) de este píxel para su comparación.

El siguiente código revisa un área cuadrada de píxeles en búsqueda de movimiento en esa zona.

for(int px=x; px<x+size; px++)  
    for(int py=y; py<y+size; py++)     
        if (px < width && px > 0 && py < height && py > 0)       
            if (brightness(mImage.get(px, py)) > 127)
                count ++;

Screenshot

Imagen de movmiento sobre el objetivo (modo buffer)
Imagen de movmiento sobre el objetivo (modo buffer)

 

Enlaces

Poniendo sombreros a las personas con OpenCV y Processing

Introducción

Como una versión un poco mas elaborada de la publicación anterior he preparado este sketch que toma el flujo de video proveniente de la cámara web,  encuentra en él los rostros de las personas y les pone un sombrero.  Se incluyen diferentes sombreros que pueden cambiarse mediante el teclado.

q – terminar el sketch
a – mostrar/ocultar el rectángulo rojo alrededor de cada cara encontrada
s – mostrar/ocultar la máscara sobre cada cara encontrada
z/x – alternar entre las imágenes de máscaras disponibles

Screenshots

Demostración con varias personas en la misma imagen
Demostración con varias personas en la misma imagen
Demostración con la foto de un rostro
Demostración con la foto de un rostro

Agradecimientos para Martha, Diego y Jennifer Connerlly por participar como modelos para las fotos del artículo.

Acerca de la ubicación de los rostros

Hasta el momento el perfil que mejores resultados me ha dado para ubicar los rostros de las personas ha sido OpenCV.CASCADE_FRONTALFACE_ALT_TREE (haarcascade_frontalface_alt_tree.xml).  Este encuentra los rostros con el menor número de errores (identificación equivocada de un objeto inanimado como si fuera un rostro), sin embargo parece tener poca tolerancia a las variaciones de posición del rostro de las personas, si ellas agachan o rotan un poco la cara probablemente ya no serán renocidas.  Un trabajo a futuro consistirá en encontrar como mejorar estos resultados de la ubicación de rostros.

Estos son los perfiles de reconocimiento disponibles a través de OpenCV según la instalación que se realizó de la librería.

Los siguientes perfiles se encuentran disponibles como constantes asociadas a la clase OpenCV de Processing.

  public static final String CASCADE_FRONTALFACE_ALT_TREE
  public static final String CASCADE_FRONTALFACE_ALT
  public static final String CASCADE_FRONTALFACE_ALT2
  public static final String CASCADE_FRONTALFACE_DEFAULT
  public static final String CASCADE_PROFILEFACE
  public static final String CASCADE_FULLBODY
  public static final String CASCADE_LOWERBODY
  public static final String CASCADE_UPPERBODY

A continuación se listan todos los archivos XML de los perfiles de reconocimiento que también pueden ser utilizados directamente en Processing.

  haarcascade_eye_tree_eyeglasses.xml   
  haarcascade_frontalface_default.xml  
  haarcascade_mcs_eyepair_small.xml  
  haarcascade_mcs_upperbody.xml
  haarcascade_eye.xml                   
  haarcascade_fullbody.xml             
  haarcascade_mcs_lefteye.xml        
  haarcascade_profileface.xml
  haarcascade_frontalface_alt2.xml      
  haarcascade_lefteye_2splits.xml      
  haarcascade_mcs_mouth.xml          
  haarcascade_righteye_2splits.xml
  haarcascade_frontalface_alt_tree.xml  
  haarcascade_lowerbody.xml            
  haarcascade_mcs_nose.xml           
  haarcascade_upperbody.xml
  haarcascade_frontalface_alt.xml       
  haarcascade_mcs_eyepair_big.xml      
  haarcascade_mcs_righteye.xml 

Enlaces

Ubicando caras en una webcam con OpenCV y Processing

Introducción

En este sketch se aprovecha la agilidad para desarrollar en Processing con la facilidad que provee OpenCV para ubicar los rostros de las personas en el flujo de video proveniente de una cámara web.  En este caso el sketch mostrará una cara sonriente cuando se encuentra acompañado por una persona y una cara triste cuando está solo.

Screenshots

Sketch feliz
Sketch feliz

Sketch triste
Sketch triste

Enlaces

Instalación de la librería de OpenCV en Processing bajo GNU/Linux Mint 12

Introducción

En el presente artículo se describirán los pasos necesarios para instalar el software de OpenCV y su correspondiente librería para desarrollar sketches con él utilizando Processing.

Durante el desarrollo de la instalación se utilizó GNU/Linux Mint 12 sin emgbargo el procedimiento debe ser compatible con Ubuntu.

Aviso! La versión de OpenCV que se encuentra en los repositorios del sistema operativo (2.1.0-7build1) es un poco antigua, sin embargo se encontraron problemas para compilar la parte nativa de la librería con una versión mas reciente.  Por este motivo se decidió utilizar la versión disponible y experimentar posteriormente una posible actualización.

Procedimiento

Instalar OpenCV

$ sudo aptitude install libcv-dev libhighgui-dev libcvaux-dev opencv-doc

Instalar la librería de Processing

Nota!  Se recomienda descargar la última versión disponible de la página web del desarrollador.  En este caso se utilizó opencv_01.zip.

Crear el directorio donde se almacenarán las librerías de Processing del usuario.

$ mkdir -p ~/sketchbook/libraries ; cd ~/sketchbook/libraries

Descargar la librería y los ejemplos de la misma.

$ wget http://ubaa.net/shared/processing/opencv/download/opencv_01.zip
$ wget http://ubaa.net/shared/processing/opencv/download/opencv_examples.zip

Descomprimir los paquetes recién descargados

$ unzip opencv_01.zip
$ rm opencv_01.zip
$ unzip opencv_examples.zip
$ rm opencv_examples.zip

Ubicar correctamente el directorio con los ejemplos.

$ mv OpenCV examples/ OpenCV/examples

Recompilar el módulo nativo de la librería

La librería incluye una librería del sistema operativo (libOpenCV.so) enlazada dinámicamente con OpenCV.  La incluída con la distribución de la librería recién instalada fue compilada con versiones anteriores de OpenCV motivo por el cual no se cumplen sus dependencias y en el momento de compilar los sketches se obtiene el siguiente mensaje de error.

!!! required library not found : /home/jimezam/sketchbook/libraries/OpenCV/library/libOpenCV.so: libcxcore.so.1: cannot open shared object file: No such file or directory
Verify that the java.library.path property is correctly set and ‘libcxcore.so’, ‘libcv.so’, ‘libcvaux.so’, ‘libml.so’, and ‘libhighgui.so’ are placed (or linked) in one of your system shared libraries folder

Exception in thread “Animation Thread” java.lang.UnsatisfiedLinkError: hypermedia.video.OpenCV.capture(III)V
    at hypermedia.video.OpenCV.capture(Native Method)
    at hypermedia.video.OpenCV.capture(OpenCV.java:945)
    at sketch_jan12b.setup(sketch_jan12b.java:35)
    at processing.core.PApplet.handleDraw(Unknown Source)
    at processing.core.PApplet.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:662)

Por este motivo es necesario recompilar el módulo nativo con las versiones actuales.  Para hacer esto se deben seguir los siguientes pasos.

$ cd ~/sketchbook/libraries/OpenCV/library/

Crear una copia de seguridad del módulo nativo a recompilarse.

$ mv libOpenCV.so libOpenCV.so.OLD

Generar la cabecera del módulo nativo de Java (JNI).

$ javah -classpath OpenCV.jar -jni hypermedia.video.OpenCV

Recompilar el módulo nativo.

$ g++ -shared ../source/cpp/OpenCV.cpp -o libOpenCV.so -I/usr/include/opencv/ -I/usr/lib/jvm/java-1.6.0-openjdk/include/ -I. -lcv -lhighgui -fPIC

Finalmente se obtienen los siguientes archivos.

$ ls -l

-rw-rw-r– 1 jimezam jimezam  10748 2012-01-12 14:43 hypermedia_video_OpenCV.h
-rwxr-xr-x 1 jimezam jimezam  80088 2009-05-27 13:15 libOpenCV.jnilib
-rwxrwxr-x 1 jimezam jimezam  41953 2012-01-12 16:16 libOpenCV.so
-rwxr-xr-x 1 jimezam jimezam  42861 2009-05-27 13:15 libOpenCV.so.OLD
-rwxr—– 1 jimezam jimezam 515184 2009-05-27 13:15 OpenCV.dll
-rw-r–r– 1 jimezam jimezam  12116 2009-05-27 13:15 OpenCV.jar

Instalar los perfiles de reconocimiento

Los perfiles de reconocimiento son archivos XML donde se estructura el conocimiento que le permite a la librería reconocer rostros sin la necesidad de mayor entrenamiento.  La versión actual de los paquetes de OpenCV en los repositorios instala estos perfiles en una ubicación que no permite que sean utilizados fácilmente desde Processing.  Los siguientes pasos corrígen esta situación.

$ sudo cp -R /usr/share/doc/opencv-doc/examples/haarcascades /usr/share/opencv/
$ sudo gunzip /usr/share/opencv/haarcascades/*.gz

Sketch de prueba

Una vez instalada la librería se podrán desarrollar sketches con ella, a continuación se presenta el sketch mas sencillo posible que muestra la imagen proveniente de la cámara web utilizando OpenCV.

import hypermedia.video.*;

OpenCV opencv;

void setup()
{
  size(640, 480);

  opencv = new OpenCV(this);

  opencv.capture(width,height);
}

void draw()
{
    opencv.read();

    background(opencv.image());
}

Enlaces