Archivos para 11/11/11

[#KINECT] HowTo: Draw the Kinect skeleton in WPF

image

Hi,

Today plays close on Friday with a tutorial on the interesting > how to paint a skeleton in WPF using the 2 Kinect Beta for Windows SDK. The basis of a skeleton in Kinect is a collection of Joints that then we can "assemble the skeleton". It is also possible to assemble and paint more than one skeleton, for this example, because we only paint skeleton [0] in yellow.

Tutorial

1. Create a new type WPF Application project in Visual Studio 2010.

2 Add the following references

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

3 We modify the MainWindow to display a title and a Canvas where we’ll show you the 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>

The window is similar to the following

image

4 Add a handler for the event Load() for the Window. We also added a runtime to work against the Kinect and initialize it with the basic options of work.

   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: }

In this example I have not put any kind of exception handling, working with a Beta we should add something later.

5. Below we can only paint our skeleton in Kinect. For this we will use the collection of Joints that returns us the Runtime and in the event KinectSkeletonFrameReady brush the Joints and Bones that unite them.

   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. Course for this to work the previous routine requires implementation of PaintJoins and PaintBones. As you can see in the following code fragment, it is quite simple because only run through the collections and paints from them.

   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: }

In the full example you can see the KinectCanvas() class which is you own definitions to convert points joints and bones in lines.

7. If we run the application and are quick to take a screenshot can something similar to

image

The complete example can be downloaded from

https://SkyDrive.live.com/embedicon.aspx/code%20Samples/2011%2011%2011%20-%20Kinect%20Skeleton%2001.zip?CID=bef06dffdb192125 & sc = documents

Greetings @ Here

The Bruno

1 comentario

[#KINECT] HowTo: Pintar un skeleton en WPF

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 comentarios

Seguir

Get every new post delivered to your Inbox.

Únete a otros 898 seguidores