Nube de puntos (Point Cloud) con Kinect

Una nube de puntos es una serie de datos en un espacio de cualquier número de dimensiones que se encuentran dispersos. Típicamente hablamos de nube de puntos en espacios 2D/3D cuando nos referimos a los datos (profundidad, color, textura, forma…) que obtenemos mediante sensores (cámaras, láseres, sónares…). Los puntos que representan un espacio 3D (y para los cuales no existe información del 100% de los puntos) se le llama nube de puntos, puntos salteados que representan un espacio 3D.

Para trabajar con la nube de puntos que Kinect nos proporciona hay que añadir unos cambios al código anterior.

Esta vez, preguntaremos a SimpleOpenNI por un array mas sofisticado que el que contenía valores de profundidad, el cual teníamos que recorrer  a través del eje x e y de la imagen.

SimpleOpenNI nos proporcionará un array con los puntos en tres dimensiones, por lo que en cada posición del array tendremos un vector con las posiciones x, y, z de un punto.

Para ello lo almacenaremos en un array de vectores con la clase PVector de Processing. y se recorre para obtener todos los puntos de la nube de puntos.

PVector [] puntosProfundidad =kinect.depthMapRealWorld();

Resumiendo, los cambios para poder obtener la nube de puntos son estos:

-En el setup  se añade el motor P3D:

  void setup(){
size(640, 480,P3D); //cuando se trabaja con dimensión z o 3D

-En el draw, centramos(width/2,height/2), alejamos (-1000), y posicionamos la imagen en el centro de la pantalla.

translate(width/2,height/2,-1000);         //centramos la imagen en x, y, z

Rotamos en X(volteamos verticalmente). La función depthMapRealWorld nos da los vectores de puntos que necesitamos en 3dimensiones de la escena que está enfrente de la Kinect. Al contrario que las otras funciones, esta es procesada de diferente manera, eliminando distorsión y proyectándola en un espacio realista 3D. Debido a esta proyección, depthMapRealWorld devuelve los valores movidos en la dirección Y. Para arreglar este problema, rotamos nuestro sketch en el eje X y volteamos los pixeles a través del eje Y para estar en su lugar.

rotateX(radians(180));// rotamos en el eje X al “mundo real”

Solo se mostrarán si los rellenamos con un color, sino aparecerían puntos invisibles.

stroke(255);

Creamos un array de vectores y almacenamos los datos:

PVector [] puntosProfundidad =kinect.depthMapRealWorld(); //recoger datos de profundidad como puntos 3D.

Recorremos el array los puntos y los almacenamos en un vector para obtener punto a punto el espacio 3D

    for (int i=0; i<puntosProfundidad.length; i++) {
    PVector puntoActual=puntosProfundidad[i];//obtener el punto actual.

Dibujamos los 3 puntos en cada interaccion del for:

point(puntoActual.x,puntoActual.y,puntoActual.z);

}

}

Podemos observar que cuanto mas cercano es el objeto, los puntos mas pegados están y parece un objeto solido y al contrario, cuando se aleja, los puntos se hacen mas dispersos.

A partir de este sketch se realizarán pruebas junto a box2D para poder unirlo con la lluvia interactiva.

Nube de puntos con Kinect from Miriam Esteve on Vimeo.

Etiquetas: , , , ,

About Miriam Esteve

Ingeniera & creativa. Amiga de mis amigos. Me gustan las cosas bonitas, el diseño, el video y la fotografía, cocinar, reír y disfrutar de la vida! Spain&Germany www.control-art.com

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: