"Kinect technologies permit us dream with the future"  [ESPAÑOL]  [ENGLISH]

Using RGB Camera with Polling



[pullquote align="left"]Utilizando la cámara RGB de Kinect con el método de programación Polling[/pullquote]
En este artículo intentaremos explicar qué es el Polling, para que se usa y como nos puede ayudar a la hora de implementar aplicaciones que utilicen el controlador de juegos Kinect. Primero debemos contextualizar que el desarrollo de este ejercicio está pensado para un WFP en Visual Studio 2010/2012.

¿Qué es el Polling?

En programación el término Polling define una forma de programación que se utiliza para obtener un flujo de datos constantes de una fuente. Generalmente, y en particular en este caso, de un dispositivo hardware: Kinect.

¿Por qué queremos usar Polling?

Para poder desarrollar una aplicación que utilice (síncrona o asíncronamente) datos captados por el controlador de juegos Kinect, necesitaremos hacer uso de él en el momento que nuestra aplicación o proyecto lo necesite, y no de forma constante consumiendo recursos hardware. Para ello necesitamos que Kinect esté permanentemente “preparado” para que le solicitemos información pero no necesariamente recopilando datos de forma continua.

¿Qué es tener preparado al dispositivo Kinect?

A grandes rasgos, deberemos de proteger a nuestra aplicación para que si por algún motivo el dispositivo no está “preparado” para darnos información, nuestra aplicación no produzca un error que altere de forma inesperada el funcionamiento de nuestra aplicación.

Que no esté preparado puede deberse por ejemplo a que se desconecte del conector USB, de la corriente e incluso que tenga un problema de Hardware y tengamos que reemplazarlo.

Para ello deberemos inicializar correctamente nuestro dispositivo Kinect, y mantener una comunicación (dialogo constante) con su propiedad “StatusChanged”.

¿Qué es un ColorImageFrame?

Un ColorImageFrame es un Objeto que contiene una imagen en formato RAW de la última captura que nos devuelve la cámara RGB del sensor Kinect.

[quote style="1"]*La cámara RGB de Kinect realiza 30 capturas por segundo según las especificaciones. Es decir, 1 frame cada 30 ms utilizando la resolución (formato) estándar del sensor: 640×480 RGB.[/quote]

Una imagen en formato RAW es un tipo de fichero que contiene un array con la totalidad de píxeles que ha capturado un sensor de una cámara digital, en este caso la cámara de Kinect.

Esta información se caracteriza por contener los datos “crudos”, sin tratar y por lo tanto sin  comprimir ni alterar su contenido mediante cualquier tipo de filtro, de la imagen. Normalmente a partir de este fichero es con el que se trabaja para utilizar esa información (imagen) para nuestro propósito.

Funcionamiento normal de la recuperación de una ColorImageFrame

Primero deberemos haber activado e inicializado a nuestro gusto la propiedad de Kinect colorStream:

[sourcecode language="csharp"]
ColorImageStream colorStream = sensor.ColorStream;
// El colorImageFormat en este caso lo dejamos en el estándar
// RgbResolution640x480Fps30  Si no lo introdujésemos explícitamente
// se inicializaría en este modo, puesto que es el estándar.
colorStream.Enable(ColorImageFormat. RgbResolution640x480Fps30);
[/sourcecode]

Polling para utilizar el ColorImageStream (cámara RGB)

Kinect a través del evento ColorFrameReady nos indica cuando tiene “lista” una frame, una captura, de la RGB Camera.

En nuestro caso, suscribiremos cada Data Stream al método OpenNextFrame. Cuando llamamos al método OpenNextFrame le podemos indicar un tiempo, en milisegundos, para indicar el timeout de forma subjetiva, si se cumple ese timeout el método devolverá un null, con el que podremos controlar que las cosas han ido mal.

Por lo tanto, para poder obtener una frame datos de la cámara RGB debemos seguir este proceso:

1) Primero deberemos definir el comportamiento de nuestra Main Window en nuestro proyecto WPF

[sourcecode language="csharp"]
#region Constructor

public MainWindow()
{
// Arranco XAML
InitializeComponent();
CompositionTarget.Rendering += CompositionTarget_Rendering;
}

#endregion Constructor
[/sourcecode]

2) EVENT HANDLER: Antes de que se Renderice el CompositionTarget (nuestra imagen del XAML) se ejecuta la siguiente función

[sourcecode language="csharp"]
private void CompositionTarget_Rendering(object sender, EventArgs e)
{
DiscoverKinectSensor();
// En este punto, podríamos definir cuando llamamos a la función que hace el Polling, para este ejemplo no pondremos ningún condicionante, pero es aquí donde se produciría la llamada asíncrona.
PollColorImageStream();
}
[/sourcecode]

3) Definimos la función DiscoverKinectSensor(); que se encargará de inicializar el sensor correctamente.

[sourcecode language="csharp"]
private void DiscoverKinectSensor()
{
if (this._Kinect != null && this._Kinect.Status != KinectStatus.Connected)
{
// If the sensor is no longer connected, we need to discover a new one.
// Es decir, si entramos aquí en algún momento ha estado conectado, pero ahora NO
this._Kinect = null;
}
if (this._Kinect == null)
{
//Find the first connected sensor
this._Kinect = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected);

// Si lo hemos encontrado
// Solo entramos una vez
if (this._Kinect != null)
{
Console.WriteLine("ENTRO la vez [" + contadorAUX + "]");
contadorAUX++;

//Initialize the found sensor
this._Kinect.ColorStream.Enable(); // Inicializo el STREAM de RGB Camera
this._Kinect.Start();

ColorImageElement.Source = this._ColorImageBitmap;

this._Kinect.Start();

// Creo el colorSTREAM para ir guandarndo los frames
ColorImageStream colorStream = this._Kinect.ColorStream;

// Creo el BITMAP de las dimensiones de lo que estoy capturando
this._ColorImageBitmap = new WriteableBitmap(colorStream.FrameWidth,
colorStream.FrameHeight,
96, 96, PixelFormats.Bgr32,
null);

// Creo el rectangulo donde voy a pintar el BITMAP
this._ColorImageBitmapRect = new Int32Rect(0, 0, colorStream.FrameWidth,
colorStream.FrameHeight);

// Cojo las dimensiones de STRIDE
this._ColorImageStride = colorStream.FrameWidth * colorStream.FrameBytesPerPixel;

// Imprimo en el ColorImageElement del XAML el BITMAP recogido de la RGB Camera
this.ColorImageElement.Source = this._ColorImageBitmap;

// Guardo el tamaño
this._ColorImagePixelData = new byte[colorStream.FramePixelDataLength];
}
}
}
[/sourcecode]

4) En último lugar, mostramos una de las opciones de implementar Polling para recoger datos de la cámara RGB:

[sourcecode language="csharp"]
private void PollColorImageStream()
{
if (this._Kinect == null)
{
//Display a message to plug-in a Kinect.
}
else
{
try
{
using (ColorImageFrame frame = this._Kinect.ColorStream.OpenNextFrame(0))
{
if (frame != null)
{
frame.CopyPixelDataTo(this._ColorImagePixelData);
// La preconfiguración de _ColorImageBitmapRect & _ColorImagePixelData & _ColorImageStride
// Ya las he hecho en el DiscoverKinectSensor, por lo que ahora los llamo cuando
// realmente lo necesito
this._ColorImageBitmap.WritePixels(this._ColorImageBitmapRect,
this._ColorImagePixelData,
this._ColorImageStride, 0);

// pinto en el Element
this.ColorImageElement.Source = this._ColorImageBitmap;
Console.WriteLine(">>> ENTRO la vez [" + contadorAUX2 + "]");
contadorAUX2++;
}
}
}
catch (Exception ex)
{
//Report an error message
}
}
}
[/sourcecode]

Conclusión

La idea de utilizar los datos que nos ofrecen los distintos sensores únicamente cuando nuestra aplicación nos hace falta, a muy bajo nivel, se haría de esta manera, utilizando Polling.

Sin embargo, nosotros os aconsejamos encarecidamente que para el desarrollo de cualquier aplicación que utilice Kinect, usemos el framework de Microsoft XNA, el cual te proporciona una manera muy organizada y jerarquizada de programar cada cosa en su lugar; en este caso las llamadas al sensor para recoger información puntual de alguno de sus STREAMS.





Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>



Últimos POST »

En Kinect for Developers trabajamos para tener actualizado nuestro Blog, con las últimas noticias y novedades sobre Kinect.
También vamos publicando información y detalles sobre todas las aplicaciones y proyectos que desarrollamos desde Kinect for Developers.

» Recomendamos visitar asiduamente nuestro Blog para estar a la última sobre Kinect.

Características Kinect 2

Dicen que lo bueno se hace esperar. Somos “pocos”los que hemos podido hacernos con un ejemplar del nuevo sensor de Microsoft, el Kinect for...

Kinect for Windows SDK 1.8

El 17 de septiembre salió a la luz la versión 1.8 del SDK para Kinect. Posiblemente este post debería haberse hecho entonces pero la...