[#KINECTSDK] HowTo: Pintar un skeleton

image

Buenas,

hace un par de días me preguntaban como hacer para pintar un skeleton con el nuevo KinectSDK, en este post. El post de hoy explica en pocos pasos los conceptos básicos para pintar el skeleton.

Para este ejemplo utilizaremos un formulario WPF, en el que agregaremos un Canvas donde pintaremos el skeleton.

   1: <Window x:Class="KinectSkeleton01.MainWindow"

   2:         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   3:         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   4:         Title="MainWindow" Height="480" Width="640">

   5:     <Grid>

   6:         <Canvas Name="skeletonCanvas" 

   7:                 Height="480" Width="640" 

   8:                 HorizontalAlignment="Center"/>

   9:     </Grid>

  10: </Window>

Lo siguiente a tener en cuenta es trabajar con el sensor Kinect como una variable local del form. En este post (link) hable un poco al respecto.

Una vez controlado el estado del Kinect, lo siguiente es inicializar la captura de skeleton (línea 6 y 7) y suscribirse al evento de cambio de frame para el skeleton (línea 8).

En la implementación de este evento, en primer lugar limpiaremos el canvas (línea 14) y una vez validado el frame recibido (línea 19) copiaremos el array de skeletons a una variable local (línea 21 y 22).

Las líneas finales verifican el estado del Joint de la cabeza para ver si el seguimiento es correcto y luego utilizan un helper de ElBruno.Kinect para pintar el skeleton.

   1: void MainWindowLoaded(object sender, RoutedEventArgs e)

   2: {

   3:     if(KinectSensor.KinectSensors.Count == 0)

   4:         return;

   5:     _kinect = KinectSensor.KinectSensors[0];

   6:     _kinect.SkeletonStream.Enable();

   7:     _kinect.Start();

   8:     _kinect.SkeletonFrameReady += KinectSkeletonFrameReady;

   9: }

  10:  

  11: void KinectSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)

  12: {

  13:     // Remove the old skeleton

  14:     skeletonCanvas.Children.Clear();

  15:     Skeleton[] skeletons = null;

  16:  

  17:     using (var frame = e.OpenSkeletonFrame())

  18:     {

  19:         if (frame != null)

  20:         {

  21:             skeletons = new Skeleton[frame.SkeletonArrayLength];

  22:             frame.CopySkeletonDataTo(skeletons);

  23:         }

  24:     }

  25:  

  26:     if (skeletons == null) return;

  27:  

  28:     foreach (var skeleton in skeletons)

  29:     {

  30:         if (skeleton.TrackingState != SkeletonTrackingState.Tracked) continue;

  31:         var headJoint = skeleton.Joints[JointType.Head];

  32:         if (headJoint.TrackingState != JointTrackingState.NotTracked)

  33:         {

  34:             var skeletonDraw = new SkeletonDraw();

  35:             skeletonDraw.DrawSkeleton(_kinect, skeletonCanvas, skeleton);

  36:         }

  37:     }

  38: }

La clase encargada de pintar el skeleton básicamente pinta líneas entre cada uno de los joints del mismo. Como podemos ver en el siguiente código las líneas se pintan entre 2 puntos con el canvas y el sensor como elementos de referencia.

   1: void AddLine(KinectSensor kinectSensor, Canvas drawCanvas, Joint j1, Joint j2)

   2:  

   3:    var boneLine = new Line {Stroke = SkeletonBrush, StrokeThickness = 5};

   4:  

   5:    var j1P = kinectSensor.MapSkeletonPointToDepth(j1.Position, DepthImageFormat.Resolution640x480Fps30);

   6:    boneLine.X1 = j1P.X;

   7:    boneLine.Y1 = j1P.Y;

   8:  

   9:    DepthImagePoint j2P = kinectSensor.MapSkeletonPointToDepth(j2.Position, DepthImageFormat.Resolution640x480Fps30);

  10:    boneLine.X2 = j2P.X;

  11:    boneLine.Y2 = j2P.Y;

  12:  

  13:    drawCanvas.Children.Add(boneLine);

  14:  

  15:  

  16: ublic  float JointDistance(Joint first, Joint second)

  17:  

  18:    float dx = first.Position.X - second.Position.X;

  19:    float dy = first.Position.Y - second.Position.Y;

  20:    float dz = first.Position.Z - second.Position.Z;

  21:  

  22:    return (float)Math.Sqrt((dx * dx) + (dy * dy) + (dz * dz));

El código de ejemplo se puede descargar desde

https://skydrive.live.com/redir.aspx?cid=bef06dffdb192125&resid=BEF06DFFDB192125!3903&parid=BEF06DFFDB192125!1932&authkey=!AKQC01rb-avYBVg

 

Saludos @ Home

El Bruno

image image image

Recursos

http://elbruno.com/2012/03/06/kinectsdk-howto-detectar-el-cambio-de-estado-o-desconexion-del-sensor/

About these ads

Un pensamiento en “[#KINECTSDK] HowTo: Pintar un skeleton

Deja un comentario

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