image

Buenas,

Hoy toca cerrar el viernes con un tutorial de los interesantes > como pintar un skeleton en WPF utilizando la Beta 2 del Kinect for Windows SDK. La base de un skeleton en Kinect es una colección de Joints con los que luego podemos “armar el skeleton”. Además es posible armar y pintar más de un skeleton, para este ejemplo, pues solo pintamos el skeleton[0] en amarillo.

 

Tutorial

1. Crear un nuevo proyecto de tipo WPF Application en Visual Studio 2010.

2. Agregamos las siguientes referencias

  • Microsoft.Research.Kinect
    <%Program Files%>\Microsoft SDKs\Kinect\v1.0 Beta2\Assemblies\Microsoft.Research.Kinect.dll

3. Modificamos la MainWindow para mostrar un título y un Canvas donde mostraremos el skeleton

   1: <Window x:Class="ElBruno.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="360">

   5:     <Grid>

   6:         <TextBlock Text="El Bruno - Skeleton Viewer" 

   7:                    FontSize="20" HorizontalAlignment="Center" />

   8:         <Canvas x:Name="Skeleton" Margin="10,40,10,10" 

   9:                 Background="Black" />

  10:     </Grid>

  11: </Window>

La ventana queda similar a la siguiente

image

4. Agregamos un manejador para el evento Load() de la Window. Además agregamos un runtime para trabajar contra el Kinect e inicializamos el mismo con las opciones básicas de trabajo.

   1: private Runtime _kinect;

   2:  

   3: public MainWindow()

   4: {

   5:     InitializeComponent();

   6:     Loaded += MainWindowLoaded;

   7: }

   8:  

   9: void MainWindowLoaded(object sender, RoutedEventArgs e)

  10: {

  11:     InitKinect();

  12: }

  13:  

  14: void InitKinect()

  15: {

  16:     if (Runtime.Kinects.Count == 0)

  17:         return;

  18:  

  19:     _kinect = Runtime.Kinects[0];

  20:     _kinect.Initialize(RuntimeOptions.UseDepthAndPlayerIndex | 

  21:       RuntimeOptions.UseSkeletalTracking | RuntimeOptions.UseColor);

  22:  

  23:         _kinect.VideoStream.Open(ImageStreamType.Video, 2, 

  24:                 ImageResolution.Resolution640x480, ImageType.Color);

  25:         _kinect.DepthStream.Open(ImageStreamType.Depth, 2, 

  26:                 ImageResolution.Resolution320x240, ImageType.DepthAndPlayerIndex);

  27:     _kinect.SkeletonFrameReady += KinectSkeletonFrameReady;

  28: }

En este ejemplo no he puesto ningún tipo de gestión de excepciones, trabajando con una Beta deberíamos agregar algo después.

5. A continuación sólo nos queda pintar nuestro esqueleto en Kinect. Para esto utilizaremos la colección de Joints que nos retorna el Runtime y en el evento KinectSkeletonFrameReady pintaremos los Joints y los Bones que unen los mismos.

   1: void KinectSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)

   2: {

   3:     foreach (var skeleton in 

   4:              e.SkeletonFrame.Skeletons.Where

   5:             (skeleton => 

   6:                       SkeletonTrackingState.Tracked == skeleton.TrackingState))

   7:     {

   8:         Skeleton.Children.Clear();

   9:         PaintBones(skeleton);

  10:         PaintJoints(skeleton);

  11:     }

  12: }

6. Obviamente para que funcione la rutina anterior hace falta la implementación de PaintJoins y de PaintBones. Como pueden ver en el siguiente fragmento de código, es bastante simple ya que solo se recorren las colecciones y se pinta a partir de las mismas.

   1: private void PaintJoints(SkeletonData skeleton)

   2: {

   3:     foreach (Joint joint in skeleton.Joints)

   4:     {

   5:         var jointPos = _kinectCanvas.GetDisplayPosition(joint);

   6:         var jointLine = new Line

   7:                             {

   8:                                 X1 = jointPos.X - 3

   9:                             };

  10:         jointLine.X2 = jointLine.X1 + 6;

  11:         jointLine.Y1 = jointLine.Y2 = jointPos.Y;

  12:         jointLine.Stroke = KinectCanvas.JointColors[joint.ID];

  13:         jointLine.StrokeThickness = 6;

  14:         Skeleton.Children.Add(jointLine);

  15:     }

  16: }

  17:  

  18: private void PaintBones(SkeletonData skeleton)

  19: {

  20:     var brush = new SolidColorBrush(Colors.Yellow);

  21:     Skeleton.Children.Add(_kinectCanvas.GetBodySegment

  22:         (skeleton.Joints, brush, JointID.HipCenter, 

  23:         JointID.Spine, JointID.ShoulderCenter, JointID.Head));

  24:     Skeleton.Children.Add(_kinectCanvas.GetBodySegment

  25:         (skeleton.Joints, brush, JointID.ShoulderCenter, 

  26:         JointID.ShoulderLeft, JointID.ElbowLeft, JointID.WristLeft, JointID.HandLeft));

  27:     Skeleton.Children.Add(_kinectCanvas.GetBodySegment

  28:         (skeleton.Joints, brush, JointID.ShoulderCenter,

  29:         JointID.ShoulderRight, JointID.ElbowRight, JointID.WristRight, JointID.HandRight));

  30:     Skeleton.Children.Add(_kinectCanvas.GetBodySegment

  31:         (skeleton.Joints, brush, JointID.HipCenter, JointID.HipLeft,

  32:         JointID.KneeLeft, JointID.AnkleLeft, JointID.FootLeft));

  33:     Skeleton.Children.Add(_kinectCanvas.GetBodySegment

  34:         (skeleton.Joints, brush, JointID.HipCenter, JointID.HipRight,

  35:         JointID.KneeRight, JointID.AnkleRight, JointID.FootRight));

  36: }

En el ejemplo completo pueden ver la clase KinectCanvas() que es la que posee las definiciones para convertir joints en points y bones en lineas.

7. Si ejecutamos la aplicación y somos rápidos para sacar un screenshot podremos algo similar a

image

El ejemplo completo se puede descargar desde

https://skydrive.live.com/embedicon.aspx/Code%20Samples/2011%2011%2011%20-%20Kinect%20Skeleton%2001.zip?cid=bef06dffdb192125&sc=documents

 

Saludos @ Here

El Bruno

   

7 responses to “[#KINECT] HowTo: Pintar un skeleton en WPF”

  1. […] y Páginas Populares [MICROPOST] Mi Libro de Visual Studio 2010 disponible en PDF[#KINECT] HowTo: Pintar un skeleton en WPF[TFS2010] HowTo: Configurar un servicio SMTP que envie alertas utilizando una cuenta de […]

    Like

  2. […] del post de ayer donde mostré como pintar en un Canvas un skeleton a partir de los datos que nos brinda Kinect, me han llegado un par de preguntas donde me preguntan […]

    Like

  3. […] – Lenguaje orientado a objetos en Español[# KINECT] HowTo: Paint 2 skeletons in a WPF Canvas[#KINECT] HowTo: Pintar un skeleton en WPF[TFS2010] HowTo: Configurar un servicio SMTP que envie alertas utilizando una cuenta de […]

    Like

  4. […] [#KINECT] HowTo: Pintar un skeleton en WPF […]

    Like

  5. Hola
    Me gustaria hacer lo mismo pero no necesito dibujar los puntos, solo saber cuales són. Como puedo copiar estos puntos que aparecen en pantalla a un fichero xml para cada frame y parte del cuerpo?
    El sample players es el que da todos los puntos de la parte del cuerpo y necessito extraer esos puntos y guardarlos para cada frame en un fichero
    Muchas gracias

    Like

    1. David buenas,

      pues si interceptas el skeleton en cada refresco de un frame, dentro del mismo tienes toda la informacion de los puntos. Ahora si los quieres guardar en un fichero, solo deberias serializar los mismos.

      Saludos
      El BRuno

      Like

      1. Hola,
        Primero gracias y segundo, a qué te refieres con serializar los mismos?

        Like

Leave a reply to [#KINECT] HowTo: Pintar 2 skeletons en un Canvas WPF | El Bruno Cancel reply

Discover more from El Bruno

Subscribe now to keep reading and get access to the full archive.

Continue reading