Búsqueda del punto mas cercano con el Kinect utilizando Processing y Simple-OpenNI

Introducción

El siguiente paso lógico consiste en identificar cual es el punto mas cercano al Kinect, presumiblemente el usuario que interactúa con el sketch, para utilizar este valor como coordenada de entrada.

Su implementación se reduce simplemente a recorrer el mapa de profundidad de alta resolución (context.depthMap()) que provee la cámara de profundidad y obtener de allí la coordenada cuyo valor sea menor pero mayor a cero ya que este corresponde a las áreas no medidas.  Para mayores detalles acerca de la implementación referirse a la función int[] findClosestPoint(int, int).

Para hacerlo un poco mas interesante se agregaron dos barras de desplazamiento en la parte inferior que sirven para limitar la profundidad de los objetos que van a ser realmente tenidos en cuenta en la determinación del punto mas cercano, esto con el fin de aislar otras zonas de acuerdo a su distancia que no quieran ser tenidas en cuenta y puedan estar produciendo interferencia.  Hacia la izquierda de las barras de desplazamiento la distancia es menor (mas cerca del Kinect) y hacia la derecha la distancia crece (se aleja del Kinect).

Basado en esta característica se agregó la funcionalidad de aislar las porciones de la imagen de los objetos que no se encuentran ubicados en el rango de profundidad válido.  Para conmutar entre imagen completa e imagen parcial sólo es necesario presionar la letra ‘t‘ (toggle) en el sketch.

Screenshot

Punto mas cercano al Kinect filtrado por un rango de distancia
Punto mas cercano al Kinect filtrado por un rango de distancia
Separación de la imagen mostrando sólo los objetos ubicados en la distancia válida
Separación de la imagen mostrando sólo los objetos ubicados en la distancia válida

Enlaces

Prueba de las cámaras del Kinect utilizando Processing

Introducción

Este sketch es una demostración simple del uso de las cámaras del Kinect utilizando Processing y la librería Simple-OpenNI.  Se incluyen las siguientes características.

  • Mostrar las imágenes provenientes de la cámara de profundidad
  • Mostrar las imágenes provenientes de la cámara RGB (video convencional)
  • Mostrar la información de color/brillo de un punto específico de una imagen
  • Calcular la distancia física entre la cámara y el punto elegido en el mundo real.

Requisitos

  1. Librería OpenNI
    http://blog.jorgeivanmeza.com/2011/12/instalacion-openni-sensor-kinect-y-nite-en-gnulinux-ubuntu-11-10-desde-fuentes/
  2. Librería Simple-OpenNI para Processing
    http://blog.jorgeivanmeza.com/2012/01/construccion-de-la-libreria-simple-openni-para-processing-bajo-ubuntu-de-32-bits/
  3. Processing
    http://www.processing.org/

Screenshot

Demostración imágenes de profundidad y RGB
Demostración imágenes de profundidad y RGB

Al hacer clic izquierdo sobre cualquiera de las imágenes se obtiene información del color/brillo del pixel seleccionado y en el caso de la imagen de profundidad se obtiene además el cálculo de la distancia física entre la cámara y el punto elegido en el mundo real.

Bright: r = 175
Distance: 2443 mm/96.18111 inches

Bright: r = 81
Distance: 2609 mm/102.71654 inches

Color: r = 49; g = 66; blue = 51

Color: r = 73; g = 53; blue = 11

Enlaces

Construcción de la librería Simple-OpenNI para Processing bajo Ubuntu de 32 bits

Introducción

Simple-OpenNI es una librería de Processing que actúa como un recubrimiento (wrapper) para utilizar fácilmente OpenNI desde este lenguaje de programación.

La distribución binaria de esta librería puede ser descargada directamente desde el sitio web del proyecto.  En el presente artículo se describirán los pasos necesarios para construír esta librería a partir de su distribución de fuentes lo cual resulta interesante para garantizar compatibilidad con las versiones de las librerías nativas instaladas y mantener la última versión disponible, así como utilizar arquitecturas cuyas distribuciones binarias no se encuentren disponibles.

Prerequisitos

Para poder construír la librería bajo GNU/Linux Ubuntu es necesario contar con los siguientes requisitos previamente instalados.

  1. OpenNI y NITE
  2. Java Development Kit.
    $ sudo aptitude install openjdk-6-jdk openjdk-6-jre openjdk-6-jre-headless openjdk-6-jre-lib
    Activar la versión recién instalada: /usr/lib/jvm/java-6-openjdk/jre/bin/java
    $ sudo update-alternatives –config java
  3. CMake
    $ sudo aptitude install cmake
  4. Swig >= v2.0.2
    $ sudo aptitude install swig
  5. Eigen >= v3.0
    $ sudo aptitude install libeigen3-dev
  6. Boost >= v1.46 (use the static build)
    $ sudo aptitude install libboost-all-dev

Procedimiento

Obtener la última versión del código fuente de la librería.

$ svn checkout http://simple-openni.googlecode.com/svn/trunk/ simple-openni-read-only

$ cd simple-openni-read-only/SimpleOpenNI/

Ajustar el script de construcción modificando la invocación a cmake de la siguiente manera.  (Ajustar las rutas que se consideren convenientes, en especial a DP5_JAR)

$ vi buildLinux32.sh

(actualizar)

cmake -DOPEN_NI_INCLUDE=/usr/include/ni/
      -DXN_NITE_INCLUDE=/usr/include/nite/
      -DXN_NITE_LIB=/usr/lib/
      -DEIGEN3D_INCLUDE=/usr/include/eigen3/
      -DP5_JAR=~/Processing/2.0a4/lib/core.jar
      -JAVA_INCLUDE_PATH=/usr/lib/jvm/java-6-openjdk/include/
      -JAVA_INCLUDE_PATH2=/usr/lib/jvm/java-6-openjdk/include/linux
      ..

Realizar la construcción de la librería.

$ ./buildLinux32.sh

Instalar la librería recién construída.

$ ./installLinux.sh

Verificar la instalación de la librería

El procedimiento anterior construye e instala la librería de Simple-OpenNI bajo ~/sketchbook/libraries/SimpleOpenNI/ dejándola lista para ser utilizada con Processing.

$ tree -d ~/sketchbook/libraries/SimpleOpenNI/

/home/jimezam/sketchbook/libraries/SimpleOpenNI/
├── documentation
│   ├── resources
│   └── SimpleOpenNI
├── examples
│   ├── eclipse
│   ├── Nite
│   │   ├── CircleCtrl
│   │   ├── Hands
│   │   └── Slider2d
│   └── OpenNI
│       ├── AlternativeViewpoint3d
│       ├── DepthImage
│       ├── DepthImageXml
│       │   └── data
│       ├── DepthInfrared
│       ├── DepthMap3d
│       ├── Hands3d
│       ├── MultiCam
│       ├── RecorderPlay
│       ├── Scene
│       ├── SceneDepth
│       ├── Threaded
│       ├── User
│       ├── User3d
│       ├── User3dCallback
│       ├── UserSaveCalib
│       └── UserScene3d
└── library

Enlaces

Instalación OpenNI, Sensor Kinect y NITE en GNU/Linux Ubuntu 11.10 desde fuentes

Introducción

OpenNI (Open Natural Interaction) es una organización sin ánimo de lucro enfocada en el desarrollo de tecnologías para la interacción natural con dispositivos.  Uno de sus principales participantes es PrimeSense, una empresa israelí responsable del desarrollo del Kinect y dispositivos similares junto con la firma Asus.

Su framework provee una infraestructura genérica basada en APIs de código abierto para acceder a los dispositivos de interacción natural, sobre él se instala el Sensor que permite acceder específicamente a los servicios provistos por el Kinect.  Adicionalmente esta empresa desarrolla el middleware NITE el cual no es de código abierto y permite acceder a funcionalidades avanzadas como seguimiento del esqueleto en tiempo real y  reconocimiento de gestos entre otras cosas.

Este proedimiento fue verificado en equipos utilizando GNU/Linux Ubuntu 11.10 y Mint 12.

Aviso!  Se instalarán las versiones inestables de OpenNI y NITE ya que actualmente así lo sugiere el módulo de SensorKinect modificado por avin2.

Prerequisitos

$ sudo aptitude install build-essential python libusb-1.0-0-dev freeglut3-dev openjdk-7-jdk doxygen graphviz

Si se desea instalar el soporte para .NET es necesario contar previamente con el soporte para Mono instalado.

$ sudo aptitude install mono-complete

Instalar OpenNI

$ mkdir ~/kinect ; cd ~/kinect

$ git clone https://github.com/OpenNI/OpenNI.git -b unstable

Aviso!  Si hay problemas con la siguiente ruta verificar si existe el directorio Linux o Linux-x86 ya que he visto algunas variaciones entre las pruebas que realicé a finales de diciembre del año pasado y esta versión mas reciente.

$ cd OpenNI/Platform/Linux/CreateRedist

$ bash RedistMaker

$ cd ../Redist/OpenNI-Bin-Dev-Linux-x86*/

$ sudo ./install.sh

Instalar Sensor Kinect

$ cd ~/kinect

$ git clone https://github.com/avin2/SensorKinect

$ cd SensorKinect/Platform/Linux/CreateRedist

$ bash RedistMaker

$ cd ../Redist/Sensor-Bin-Linux-x86*

$ sudo sh install.sh

Instalar NITE

Descargar la distribución binaria para GNU/Linux mas reciente desde la siguiente ubicación.

http://www.openni.org/Downloads/OpenNIModules.aspx

Descargar el módulo inestable de NITE
Descargar el módulo inestable de NITE

$ cd ~/kinect

$ tar jxvf nite-bin-linux-x86-v1.5.2.21.tar.bz2

$ cd NITE-Bin-Dev-Linux-x86*/Data

$ chmod a+w *

$ vi *.xml

<License vendor=”PrimeSense” key=”insert key here”/>
… reemplazar por …
<License vendor=”PrimeSense” key=”0KOIk2JeIBYClPWVnMoRKn5cdY4=”/>

$ cd ..

$ sudo ./install.sh

Probar los ejemplos

Es posible verificar el funcionamiento del software recién instalado con las aplicaciones de demostración que este incluye.  Para hacer esto se recomienda revisar los siguientes directorios.

  1. ~/kinect/OpenNI/Platform/Linux/Bin/x86-Release
  2. ~/kinect/NITE-Bin-Dev-Linux-x86*/Samples/Bin/x86-Debug

Solución de problemas

Verificar el reconocimiento del dispositivo

Una vez conectado el Kinect al puerto USB del computador y a la corriente eléctrica este debe ser reconocido por el sistema operativo.

$ dmesg


[  158.092116] usb 2-3: new high speed USB device number 4 using ehci_hcd

[  158.224738] hub 2-3:1.0: USB hub found
[  158.224915] hub 2-3:1.0: 3 ports detected
[  158.800196] usb 2-3.2: new full speed USB device number 5 using ehci_hcd
[  160.336252] usb 2-3.1: new high speed USB device number 6 using ehci_hcd
[  161.448177] usb 2-3.1: usbfs: USBDEVFS_CONTROL failed cmd mtp-probe rqt 128 rq 6 len 1024 ret -110
[  162.128178] usb 2-3.3: new high speed USB device number 7 using ehci_hcd
[  162.299863] gspca: v2.13.0 registered
[  162.301016] usbcore: registered new interface driver kinect

$ lsusb


Bus 002 Device 005: ID 045e:02b0 Microsoft Corp. Xbox NUI Motor
Bus 002 Device 006: ID 045e:02ad Microsoft Corp. Xbox NUI Audio
Bus 002 Device 007: ID 045e:02ae Microsoft Corp. Xbox NUI Camera

error CS0117: `OpenNI.CalibrationStatus’ does not contain a definition for `ManualAbort’

Si se está realizando una actualización de OpenNI probablemente sea buena idea desinstalar los archivos previos antes de realizar nuevamente los pasos descritos en este artículo.

$ sudo rm -rf /usr/include/ni/
$ sudo rm /usr/share/java/org.OpenNI.jar
$ sudo rm /usr/lib/libOpenNI.jni.so
$ sudo rm -rf /usr/lib/mono/gac/OpenNI.net
$ sudo rm /usr/lib/mono/2.0/OpenNI.net.dll
$ sudo rm /usr/lib/libOpenNI.so

Open failed: Failed to set USB interface!


Aparentemente los kernels incluyen un módulo para interactuar con el Kinect que interfiere con la ejecución de OpenNI.  Para verificar esto es necesario ejecutar el siguiente comando.

$ lsmod | grep gspca_kinect

gspca_kinect           12792  0
gspca_main             27610  1 gspca_kinect

En caso de existir este módulo debe ser removido de la siguiente manera.

$ sudo rmmod gspca_kinect

Para evitar permanentemente la carga de este módulo del Kernel es necesario agregarlo a la lista negra de la siguiente manera.

$ sudo vi /etc/modprobe.d/blacklist-kinect.conf

blacklist gspca_kinect

Esta modificación será tenida en cuenta tan pronto como se reinicie el sistema operativo.

Enlaces