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

11 responses to “[#KINECT] HowTo: Utilizar Face Recognition con #KinectSdk (III)”

  1. Alejandro Guevara Avatar
    Alejandro Guevara

    Saludos desde Ecuador!
    Excelente proyecto!!, soy novato en el uso del C# y quiero hacer un proyecto con KINECT FaceTracking.
    Quiero encender una luz al momento que el usuario gire la cabeza al lado izquierdo, para eso creo que necesito el vector que tiene los puntos 3D, el mismo que posee los numeros de cada punto, para poder manejarme con ellos.
    Por favor dame alguna sugerencia para lograrlo.
    Muchas gracias!!

    Like

    1. Alejandro, pues lo que comentas no es complicado de hacer. Con el Kinect SDK lo podrás hacer fácilmente. Cuando lo temines me avisas así lo vemos 😀

      Saludos

      Like

  2. comodin2002 Avatar
    comodin2002

    Buenas Bruno,
    Como puedo hacer que una vez reconocida la cara me dibuje otro tipo de mascara? una mascara estática 3D? que tipo de formato debe de tener?
    Me gustaría comenzar pudiendo añadir simples objetos 3d a la cara de los usuarios como gorros, bigotes y pelucas. Crees que esto es posible?
    Muchas gracias por tu ayuda.

    Like

    1. Buenas,
      La misma respuesta que en el post anterior.
      Buenas comodin

      pues la verdad que no sabría decirte como poner una máscara estática 3D en una app WPF. No soy un experto en WPF y mucho menos en modelados 3D.
      El Toolkit tiene varios ejemplos y uno de ellos agrega una proyección de la cara de la persona, lo puedes ver en http://kinectforwindowsorg, dentro de las descargas del Toolkit. El ejemplo es FaceTracking 3D-WPF (http://msdn.microsoft.com/en-us/library/jj131043) y tal vez pueda servirte como punto de partida.

      Saludos
      /Bruno

      Like

  3. Hola, que buen proyecto, interesante vaya que el kinect tiene infinidad de posibilidades de uso de sus diferentes sensores…
    Disculpa en que lugar del código iría ese filtro??

    gracias

    Like

  4. Juandelrazo Avatar
    Juandelrazo

    Gracias por la aportación pero me gustaría saber en que parte del código aplico el filtro de los puntos????

    Like

    1. Veo que el codigo se ve horrible con el formato nuevo de WP despues de 7 años.
      Y no entiendo la pregunta, a que te refieres con que parte del codigo? Esto tiene 7 años y era para el kinect “viejo”

      Like

      1. razoo_beis@hotmail.com Avatar
        razoo_beis@hotmail.com

        Esq no he podido implementar el filtro para los puntos bro
        Me puedes ayudar con eso?

        Like

      2. razoo_beis@hotmail.com Avatar
        razoo_beis@hotmail.com

        Lo que pasa hermano esq estoy trabajando en el reconocimiento de emociones…. Pero no he logrado poner el filtro… Me refiero a que solo quiero que se muestren ciertos puntos de la cara y no todos…. Ayudame por favor

        Like

        1. Pues si quieres solo algunos puntos, filtra la coleccion con todos los puntos y solo muestra los que tu quieras.
          saludos

          Like

      3. Juandelrazo Avatar
        Juandelrazo

        No he podido implementar el filtro de los puntos en el programa… Me puedes ayudar con eso???
        Estoy trabajando en detección de emociones y solo me interesan unos puntos faciales en específico

        Like

Leave a reply to Juandelrazo Cancel reply

Discover more from El Bruno

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

Continue reading