Esqueleto Básico

Embed Size (px)

Citation preview

  • Kinect

    Crea un nuevo proyecto tipo WPF.

    Aade la referencia Microsoft.Kinect.dll

    Nos vamos a la seccin MainWindow.xaml.cs

    Lo primero que necesitamos es ir armando el esqueleto con las figuras y

    dimensiones que este necesita, Estas lneas de cdigo van antes del

    MainWindow()

    Ancho de salida de dibujo

    private const float RenderWidth = 640.0f;

    Altura de nuestra salida de dibujo private const float RenderHeight = 480.0f; Espesor de lneas trazadas de conjuntas private const double JointThickness = 3;

  • Kinect

    Grueso de la elipse de centro del cuerpo private const double BodyCenterThickness = 10; Espesor de rectngulos de borde de clip private const double ClipBoundsThickness = 10; Pincel utilizado para dibujar el punto central del esqueleto private readonly Brush centerPointBrush = Brushes.Blue; Pincel utilizado para la elaboracin de las articulaciones que actualmente se realiza un seguimiento private readonly Brush trackedJointBrush = new SolidColorBrush(Color.FromArgb(255, 68, 192, 68)); Pincel utilizado para la elaboracin de las articulaciones que actualmente se infieren private readonly Brush inferredJointBrush = Brushes.Yellow; Utilizado para la elaboracin de huesos que actualmente se realiza un seguimiento de la pluma private readonly Pen trackedBonePen = new Pen(Brushes.Green, 6); Utilizado para la elaboracin de huesos que actualmente se deducen de la pluma private readonly Pen inferredBonePen = new Pen(Brushes.Gray, 1);

    Activa el sensor private KinectSensor sensor; Grupo de dibujo para la salida de la representacin del esqueleto private DrawingGroup drawingGroup; Dibujando Imagen de dibujo que nos mostrar private DrawingImage imageSource;

    Una vez declarado las dimensiones y figuras del esqueleto es hora de dibujar

    los indicadores que muestran los bordes estn en el recorte de datos del

    esqueleto el esqueleto con el siguiente mtodo

    private static void RenderClippedEdges(Skeleton skeleton, DrawingContext drawingContext) { if (skeleton.ClippedEdges.HasFlag(FrameEdges.Bottom)) { drawingContext.DrawRectangle( Brushes.Red, null,

  • Kinect

    new Rect(0, RenderHeight - ClipBoundsThickness, RenderWidth, ClipBoundsThickness)); } if (skeleton.ClippedEdges.HasFlag(FrameEdges.Top)) { drawingContext.DrawRectangle( Brushes.Red, null, new Rect(0, 0, RenderWidth, ClipBoundsThickness)); } if (skeleton.ClippedEdges.HasFlag(FrameEdges.Left)) { drawingContext.DrawRectangle( Brushes.Red, null, new Rect(0, 0, ClipBoundsThickness, RenderHeight)); } if (skeleton.ClippedEdges.HasFlag(FrameEdges.Right)) { drawingContext.DrawRectangle( Brushes.Red, null, new Rect(RenderWidth - ClipBoundsThickness, 0, ClipBoundsThickness, RenderHeight)); } }

    Ahora ejecutamos las tareas de encendido y apagado con los siguientes

    mtodos.

    private void WindowLoaded(object sender, RoutedEventArgs e) { //Cree el grupo de dibujo que usaremos para dibujar this.drawingGroup = new DrawingGroup(); // Crear una fuente de imagen que podemos utilizar en nuestro control de imagen this.imageSource = new DrawingImage(this.drawingGroup); // Muestra el dibujo utilizando nuestro control de imagen Image.Source = this.imageSource; // Mira a travs de todos los sensores y comenzar la primera que se conecte.

  • Kinect

    // Esto requiere que un Kinect est conectado en el momento de inicio de aplicacin. foreach (var potentialSensor in KinectSensor.KinectSensors) { if (potentialSensor.Status == KinectStatus.Connected) { this.sensor = potentialSensor; break; } } if (null != this.sensor) { // Recibe las tramas esqueleto this.sensor.SkeletonStream.Enable(); // Agregar un controlador de eventos que se llamar siempre que haya nuevos datos del marco de color this.sensor.SkeletonFrameReady += this.SensorSkeletonFrameReady; // Inicia el sensor try { this.sensor.Start(); } catch (IOException) { this.sensor = null; } } if (null == this.sensor) { this.statusBarText.Text = Properties.Resources.NoKinectReady; } }

    private void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e) { if (null != this.sensor) { this.sensor.Stop(); } }

    Controlador de eventos para el evento de SkeletonFrameReady del sensor de Kinect

  • Kinect

    Creamos el evento para controlar el SkeletonFrameReady del sensor Kinect.

    private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) { Skeleton[] skeletons = new Skeleton[0]; using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame()) { if (skeletonFrame != null) { skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength]; skeletonFrame.CopySkeletonDataTo(skeletons); } } using (DrawingContext dc = this.drawingGroup.Open()) { // Dibujar un fondo transparente para establecer el tamao de render dc.DrawRectangle(Brushes.Black, null, new Rect(0.0, 0.0, RenderWidth, RenderHeight)); if (skeletons.Length != 0) { foreach (Skeleton skel in skeletons) { RenderClippedEdges(skel, dc); if (skel.TrackingState == SkeletonTrackingState.Tracked) { this.DrawBonesAndJoints(skel, dc); } else if (skel.TrackingState == SkeletonTrackingState.PositionOnly) { dc.DrawEllipse( this.centerPointBrush, null, this.SkeletonPointToScreen(skel.Position), BodyCenterThickness, BodyCenterThickness); } } } // evita que el dibujo fuera de nuestra rea de procesamiento this.drawingGroup.ClipGeometry = new RectangleGeometry(new Rect(0.0, 0.0, RenderWidth, RenderHeight)); } }

  • Kinect

    Ahora solo resta dibujar los huesos y articulaciones del esqueleto de la

    siguiente manera

    private void DrawBonesAndJoints(Skeleton skeleton, DrawingContext drawingContext) { // Representar el Torso this.DrawBone(skeleton, drawingContext, JointType.Head, JointType.ShoulderCenter); this.DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.ShoulderLeft); this.DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.ShoulderRight); this.DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.Spine); this.DrawBone(skeleton, drawingContext, JointType.Spine, JointType.HipCenter); this.DrawBone(skeleton, drawingContext, JointType.HipCenter, JointType.HipLeft); this.DrawBone(skeleton, drawingContext, JointType.HipCenter, JointType.HipRight); // Brazo izquierdo this.DrawBone(skeleton, drawingContext, JointType.ShoulderLeft, JointType.ElbowLeft); this.DrawBone(skeleton, drawingContext, JointType.ElbowLeft, JointType.WristLeft); this.DrawBone(skeleton, drawingContext, JointType.WristLeft, JointType.HandLeft); // Brazo derecho this.DrawBone(skeleton, drawingContext, JointType.ShoulderRight, JointType.ElbowRight); this.DrawBone(skeleton, drawingContext, JointType.ElbowRight, JointType.WristRight); this.DrawBone(skeleton, drawingContext, JointType.WristRight, JointType.HandRight); // Pierna izquierda this.DrawBone(skeleton, drawingContext, JointType.HipLeft, JointType.KneeLeft); this.DrawBone(skeleton, drawingContext, JointType.KneeLeft, JointType.AnkleLeft); this.DrawBone(skeleton, drawingContext, JointType.AnkleLeft, JointType.FootLeft); // Pierna derecha this.DrawBone(skeleton, drawingContext, JointType.HipRight, JointType.KneeRight);

  • Kinect

    this.DrawBone(skeleton, drawingContext, JointType.KneeRight, JointType.AnkleRight); this.DrawBone(skeleton, drawingContext, JointType.AnkleRight, JointType.FootRight); // Procesar las juntas foreach (Joint joint in skeleton.Joints) { Brush drawBrush = null; if (joint.TrackingState == JointTrackingState.Tracked) { drawBrush = this.trackedJointBrush; } else if (joint.TrackingState == JointTrackingState.Inferred) { drawBrush = this.inferredJointBrush; } if (drawBrush != null) { drawingContext.DrawEllipse(drawBrush, null, this.SkeletonPointToScreen(joint.Position), JointThickness, JointThickness); } } }

    Ahora tenemos que verificar si el objeto est dentro de nuestro espacio donde

    el Kinect lo puede ver y convertir los datos a puntos que sern las

    articulaciones del esqueleto.

    private Point SkeletonPointToScreen(SkeletonPoint skelpoint) { // Convertir punto en espacio de profundidad. No estamos utilizando profundidad directamente, pero queremos los puntos en nuestra resolucin de salida de 640 x 480. DepthImagePoint depthPoint = this.sensor.CoordinateMapper.MapSkeletonPointToDepthPoint(skelpoint, DepthImageFormat.Resolution640x480Fps30); return new Point(depthPoint.X, depthPoint.Y); }

    Ahora vamos a dibujar nuestras lneas entre dos articulaciones para armar el

    esqueleto, para ello emplearemos 4 variables:

  • Kinect

    Skeleton.- para dibujar los huesos.

    drawingContext.- contexto de dibujo para dibujar a

    jointType0.- articulacin para empezar a dibujar desde

    jointType1.- Junta para terminar el dibujo en

    Una vez que ya sabemos para qu emplearemos las variables es hora de

    ingresar el mtodo para la creacin del esqueleto.

    private void DrawBone(Skeleton skeleton, DrawingContext drawingContext, JointType jointType0, JointType jointType1) { Joint joint0 = skeleton.Joints[jointType0]; Joint joint1 = skeleton.Joints[jointType1]; //Si no podemos encontrar cualquiera de estas juntas, salir if (joint0.TrackingState == JointTrackingState.NotTracked || joint1.TrackingState == JointTrackingState.NotTracked) { return; } // No llamar si ambos puntos se deducen if (joint0.TrackingState == JointTrackingState.Inferred && joint1.TrackingState == JointTrackingState.Inferred) { return; } // Asumimos que todos los huesos dibujados se infieren a menos que ambas juntas se realiza un seguimiento Pen drawPen = this.inferredBonePen; if (joint0.TrackingState == JointTrackingState.Tracked && joint1.TrackingState == JointTrackingState.Tracked) { drawPen = this.trackedBonePen; } drawingContext.DrawLine(drawPen, this.SkeletonPointToScreen(joint0.Position), this.SkeletonPointToScreen(joint1.Position)); }

  • Kinect

    Y para terminar solo falta el mtodo de comprobacin por si el usuario est sentado.

    private void CheckBoxSeatedModeChanged(object sender, RoutedEventArgs e) { if (null != this.sensor) { if (this.checkBoxSeatedMode.IsChecked.GetValueOrDefault()) { this.sensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated; } else { this.sensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Default; } } }

    Y listo hemos terminado con el cdigo.

    Si depuras el cdigo vers que te aparece un error en la lnea

    this.statusBarText.Text = Properties.Resources.NoKinectReady;

    Para arreglar este error nos vamos a Properties > Resoutces >

    Resources.Designer.cs

    Agregamos el siguiente cdigo, este busca una cadena localizada similar a No

    Kinect

    internal static string NoKinectReady { get { return ResourceManager.GetString("NoKinectReady", resourceCulture); } }

  • Kinect

    Ahora nos vamos con el diseo, damos clic en MainWindow.xamlpara ingresar el

    siguiente cdigo de diseo, en esta ocasin he tomado como referencia las imgenes y

    archivos de los ejemplos del SDK para hacer mi interfaz

  • Kinect

  • Kinect

    RESULTADO FINAL

    ~ HASTA LA PRXIMA ~