9/8/2012 12:44 El Bruno

[#KINECT] HowTo: Utilizar Face Recognition con #KinectSdk (III)

image

Buenas,

después de los primeros 2 posts

hoy veremos como modificar la “red” que se dibuja en nuestro rostro utilizando el ejemplo del post anterior. Repasando un poco cómo está montado el mismo, vemos que el UserControl [FaceTracking.xaml] es el que muestra la red con la cara sobre una imagen en la que se muestra el output de la cámara del sensor Kinect.

image

Para pintar la red, la clase [SkeletonFaceTracker.cs] utiliza la rutina DrawFaceModel() que crea una colección de triángulos y luego pinta los mismos.

   1: public void DrawFaceModel(DrawingContext drawingContext)
   2: {
   3:     if (!LastFaceTrackSucceeded || _skeletonTrackingState != SkeletonTrackingState.Tracked)
   4:     {
   5:         _startFaceRecognition = DateTime.MinValue;
   6:         return;
   7:     }
   8:  
   9:     var faceModelPts = _facePoints.Select(t => new Point(t.X + 0.5f, t.Y + 0.5f)).ToList();
  10:  
  11:     var faceModel = _faceTriangles.Select(t => new FaceModelTriangle
  12:                                                    {
  13:                                                        P1 = faceModelPts[t.First], 
  14:                                                        P2 = faceModelPts[t.Second], 
  15:                                                        P3 = faceModelPts[t.Third]
  16:                                                    }).ToList();
  17:  
  18:     var faceModelGroup = new GeometryGroup();
  19:     for (var i = 0; i < faceModel.Count; i++)
  20:     {
  21:         var faceTriangle = new GeometryGroup();
  22:         faceTriangle.Children.Add(new LineGeometry(faceModel[i].P1, faceModel[i].P2));
  23:         faceTriangle.Children.Add(new LineGeometry(faceModel[i].P2, faceModel[i].P3));
  24:         faceTriangle.Children.Add(new LineGeometry(faceModel[i].P3, faceModel[i].P1));
  25:         faceModelGroup.Children.Add(faceTriangle);
  26:     }
  27:  
  28:     drawingContext.DrawGeometry(Brushes.BlueViolet, new Pen(Brushes.Red, 1.0), faceModelGroup);
  29:     if (_startFaceRecognition == DateTime.MinValue)
  30:     {
  31:         _startFaceRecognition = DateTime.Now;
  32:     }
  33:     else
  34:     {
  35:         if (DateTime.Now.Subtract(_startFaceRecognition).TotalSeconds > 5)
  36:         {
  37:             Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  38:             {
  39:                 System.Threading.Thread.Sleep(300);
  40:                 _startFaceRecognition = DateTime.MinValue;
  41:             }));
  42:         }
  43:     }
  44: }

Para la mejorar un poco este ejemplo, en lugar de pintar la red sobre la cara, lo que haremos es pintar los puntos y además en cada punto poner el número del mismo. Lo que hacemos es crear una nueva función llamada () con el siguiente código.

   1: public void DrawFaceFlat(DrawingContext drawingContext)
   2: {
   3:     if (!LastFaceTrackSucceeded || _skeletonTrackingState != SkeletonTrackingState.Tracked)
   4:     {
   5:         _startFaceRecognition = DateTime.MinValue;
   6:         return;
   7:     }
   8:  
   9:     var faceModelPts = _facePoints.Select(t => new Point(t.X + 0.5f, t.Y + 0.5f)).ToList();
  10:  
  11:     var faceModelGroup = new GeometryGroup();
  12:     for (var i = 0; i < faceModelPts.Count; i++)
  13:     {
  14:         var geometryGroup = new GeometryGroup();
  15:         var ellipseGeometry = new EllipseGeometry(faceModelPts[i], 1, 1);
  16:  
  17:         var formattedText = new FormattedText(i.ToString(), CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
  18: new Typeface("Verdana"), 12, Brushes.White);
  19:         geometryGroup.Children.Add(ellipseGeometry);
  20:         faceModelGroup.Children.Add(geometryGroup);
  21:     }
  22:  
  23:     drawingContext.DrawGeometry(Brushes.Yellow, new Pen(Brushes.Yellow, 1.0), faceModelGroup);
  24:  
  25:     for (var i = 0; i < faceModelPts.Count; i++)
  26:     {
  27:         var formattedText = new FormattedText(i.ToString(), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, new Typeface("Verdana"), 8, Brushes.White);
  28:         drawingContext.DrawText(formattedText, faceModelPts[i]);
  29:     }
  30:  
  31:     if (_startFaceRecognition == DateTime.MinValue)
  32:     {
  33:         _startFaceRecognition = DateTime.Now;
  34:     }
  35:     else
  36:     {
  37:         if (DateTime.Now.Subtract(_startFaceRecognition).TotalSeconds > 5)
  38:         {
  39:             Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  40:             {
  41:                 System.Threading.Thread.Sleep(300);
  42:                 _startFaceRecognition = DateTime.MinValue;
  43:             }));
  44:         }
  45:     }
  46: }

Luego cambiamos la ínvocación en [FaceTracking.xaml] para que utilice esta rutina y el resultado es el siguiente.

image

Ahora bien, como hay demasiados puntos para mostrar en un espacio tan pequeño, aplicaremos un filtro para solo motrar los puntos

var pointFilter = new List<int> {4, 8 , 39, 41, 42, 48, 54, 68, 86, 74, 80, 57, 51};

el resultado es un poco más simpático …Open-mouthed smile

image

Saludos @ La Finca

El Bruno

image image image

Archivado en: ,,,
Comparte este post: