Windows Phone Summit meetup at MIC - 20th June 2012

7. June 2012 15:39 by Renaud in   //  Tags:   //   Comments (0)

As you may know, the 20th June is a very important day ! This is the day of the Windows Phone Summit event, happening in San Francisco. This is a conference about the futur of Windows Phone, and we can expect some awesome news !

That's why I'm very happy to invite you to spend your evening at the Microsoft Innovation Center, in Mons ! We could watch the event all together, share our first impressions, talk about mobile technologies and share our experiences on the Windows Phone platform. Of course that night wouldn't be a success without some beer and a few pizzas !

Registrations are open and free : http://events.mic-belgique.be/event/windows-phone-summit-live-mic-belgique

Save the date and join us to discover what the future of Windows Phone will be made of !

Windows Phone Summit meetup au MIC - 20 juin 2012

7. June 2012 14:06 by Renaud in   //  Tags:   //   Comments (0)

Comme vous le savez peut-être, le 20 juin prochain est une date importante ! C’est ce jour-là qu’aura lieu le Windows Phone Summit : il s’agit d’une conférence parlant de l’avenir de la plateforme Windows Phone, avec de très belles annonces en perspective !

C’est pourquoi j’ai le plaisir de vous inviter à venir passer la soirée au MIC pour suivre l’événement en direct sur grand écran et partager vos impressions avec d’autres développeurs. On pourra parler technologies mobiles sans langue de bois, s’échanger nos expériences et nos applications WP7… tout en buvant un verre et en grignotant des pizzas dans une ambiance sympathique !

L'inscription est gratuite et se fait via ce lienhttp://events.mic-belgique.be/event/windows-phone-summit-live-mic-belgique

Venez nous rejoindre pour découvrir ensemble de quoi le futur de Windows Phone sera fait !

Kinect SDK 1.5 - Face tracking in C#

1. June 2012 20:06 by Renaud in   //  Tags:   //   Comments (23)

 

The SDK 1.5 has been released and with it come a lot of new features such as the very nice face tracking toolkit : Microsoft.Kinect.Toolkit.FaceTracking !

The idea is awesome and will probably open the door to a lot of new ways of using the Kinect ! It makes it easy to animate a 3D face model, and the result is quite awesome !

I wanted to test it by myself and see what I could do with my amazing artistic skills. I'll show you what I did and how !

 

This is a drawing made with a few shapes in a WPF application. We will use the face tracking functionality to animate it ! In this application, we will use only a few of the information we can get from the Kinect, but the aim is to show how easy it is, and how it works.

You can download the full project right here and play with it : http://sdrv.ms/KMjNMQ


Install the resources

For implementing face tracking, we need the SDK 1.5 and the toolbox. You can download both of them on the Kinect for Windows website : http://www.microsoft.com/en-us/kinectforwindows/develop/developer-downloads.aspx.

When it is installed, you can see that line in the config panel :

The Toolkit will install Kinect Studio, a few projects samples in C#/VB.Net/C++, and two libraries for face tracking ( compiled in 32 and 64 bits) :

  • FaceTrackData.dll
  • FaceTrackLib.dll

Everything stands in the same folder as the SDK : 

If you develop a C++ application, you can directly use the face tracking libraries in your project. In the other case, you should use a wrapper that exposes the libraries in managed code.

By chance, the Developer Toolkit gives you a project sample that you can use to start directly ! Launch the "Developer Toolkit Browser", and goes under the Components menu. Then, you'll find two projects :

  • Microsoft.Kinect.Toolkit
  • Microsoft.Kinect.Toolkit.FaceTracking

You can install them somewhere on your hard drive, so that you have a copy that you can reuse in your own projects.

Create a new WPF/C# project

To be able to use the Face Tracking capabilities in my new project modestly called AwesomeFaceTracking, I have to include the Microsoft.Kinect.Toolkit.FaceTracking sample project in the solution, and then add it as a reference to my project.

It is also necessary to add to your project the two face tracking libraries installed with the SDK ! We can find them by default in the folder : C:Program FilesMicrosoft SDKsKinectDeveloper Toolkit v1.5.0Redist. Those .dll files must be placed in the same folder as the executable application.

You need those libraries because the wrapper project will use them !

Then we will also add a reference to the Microsoft.Kinect assembly, and finally we can add those two namespaces to the MainWindows class :

using Microsoft.Kinect;
using Microsoft.Kinect.Toolkit.FaceTracking;

Initialize the KinectSensor and the FaceTracker

To increase our chances to detect a face, we will use all the possibilities of the Kinect ! In the application, once a KinectSensor is found, we will enable all the different streams : ColorImageStream, DepthImageStream and SkeletonStream.

                // Initialize all the necessary streams:
                // - ColorStream with default format
                // - DepthStream with Near mode and lowest resolution
                // - SkeletonStream with tracking in NearReange and Seated mode.

                kinectSensor.ColorStream.Enable();

                kinectSensor.DepthStream.Range = DepthRange.Near;
                kinectSensor.DepthStream.Enable(DepthImageFormat.Resolution80x60Fps30);

                kinectSensor.SkeletonStream.EnableTrackingInNearRange = true;
                kinectSensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;
                kinectSensor.SkeletonStream.Enable(
                    new TransformSmoothParameters() {
                        Correction = 0.5f, 
                        JitterRadius = 0.05f, 
                        MaxDeviationRadius = 0.05f, 
                        Prediction = 0.5f, 
                        Smoothing = 0.5f 
                    });

                // Listen to the AllFramesReady event to receive KinectSensor's data.
                kinectSensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(kinectSensor_AllFramesReady);

                // Initialize data arrays
                colorPixelData = new byte[kinectSensor.ColorStream.FramePixelDataLength];
                depthPixelData = new short[kinectSensor.DepthStream.FramePixelDataLength];
                skeletonData = new Skeleton[6];

                // Starts the Sensor
                kinectSensor.Start();

                // Initialize a new FaceTracker with the KinectSensor
                faceTracker = new FaceTracker(kinectSensor);

I suppose you know what those lines are for. The only novelty here is the last one initializing a FaceTracker object. We also use the lowest resolution for the DepthImageStream as it gives a smoother result.

All the job will happen in the eventhandler of the AllFramesReady event !

        void kinectSensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            // The code extracts below must be added here ;)
        }

Get a face frame

In the toolkit, the object that represents the face is FaceTrackFrame. To get one, we will use the Track method of the FaceTracker object by giving him all the data we can get from the Kinect. The FaceTracker object will the process all that data and try to find a face in it !

We first retrieve the data from all the different frames. To be sure the data is synchronized, we will only reach the end of the process if all of the streams give us a frame AND that a tracked skeleton has been found !

            using (ColorImageFrame colorImageFrame = e.OpenColorImageFrame())
            {
                if (colorImageFrame == null)
                    return;
                colorImageFrame.CopyPixelDataTo(colorPixelData);
            }

            using (DepthImageFrame depthImageFrame = e.OpenDepthImageFrame())
            {
                if (depthImageFrame == null)
                    return;
                depthImageFrame.CopyPixelDataTo(depthPixelData);
            }

            using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
            {
                if (skeletonFrame == null)
                    return;
                skeletonFrame.CopySkeletonDataTo(skeletonData);
            }

            var skeleton = skeletonData.FirstOrDefault(s => s.TrackingState == SkeletonTrackingState.Tracked);
            if (skeleton == null)
                return;

If we are here at the execution time, it means that we have enough data to expect detecting a face !

We will then use the FaceTracker and provide him the image, the depth data, and the tracked skeleton for which we would like to detect the face.

            FaceTrackFrame faceFrame = faceTracker.Track(kinectSensor.ColorStream.Format, colorPixelData,
                                              kinectSensor.DepthStream.Format, depthPixelData,
                                              skeleton);

In the faceFrame variable, you'll get an object of type FaceTrackFrame, which represents the tracked face. For a fully detailed description, have a look at this post on MSDN : http://msdn.microsoft.com/en-us/library/jj130970. Here are the basics :

First of all, TrackSuccessful is a boolean that tells you whether the face has been detected or not ! FaceRect is the rectangle zone in which the face stands.

But the most important is certainly the methods: they allow you to get up to 87 points representing the face. Those points can be retrieved in a 2-dimensional or a 3-dimensional space. You can also retrieve a few more information about the facial expressions of the user !

Get3DShape() returns a collection of 87 points in 3D.

GetProjected3DShape() returns the same collection but in a 2D referential corresponding to a 640x480 pixels image.

GetAnimationUnitCoefficients() returns the values describing the facial expressions. That's what we are going to use in the next part of this project.  For more information on this, you can read : Animation Units on MSDN.

GetTriangles() is a method that you can use in association with the Get3DShape method. It will return you a collection of triangles, and for each triangles 3 indices corresponding that indicates which points in the collection returned by Get3DShape are vertices of the triangle. For those of you who are used to work with 3D modeling, it will be helpful to create an draw an animated model of the whole face !

Simple face drawing

In this part, we will just write a few lines of XAML to draw something that looks like a human face. We will also add some Transformations (Translations, Rotations, Scales, ...) that will be used with the Animation Units coeff to animate the drawing.

The RenderTransform objects allows you to change the rendering of a visual UI element after it has been created. Look for example at the Ellipse which stands for the mouth (Ellipse with x:Name="Mouth") : it has a ScaleTransform object that can be scaled over the X or Y axis. We will use it to mimic the opening of the mouth.

<Window x:Class="AwesomeFaceTracking.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid>
            <Canvas x:Name="MainCanvas" Width="500" Height="500">
                <Canvas.RenderTransform>
                    <TransformGroup>
                        <RotateTransform x:Name="CanvasRotate" CenterX="250" CenterY="250" />
                    </TransformGroup>
                </Canvas.RenderTransform>
                <Ellipse Width="300" Height="300" x:Name="Face"  StrokeThickness="2" Stroke="Black" Canvas.Left="105" Canvas.Top="6" />
                <Ellipse Width="30" Height="30" x:Name="LeftEye" Stroke="Black" StrokeThickness="2" Canvas.Left="289" Canvas.Top="102" />
                <Ellipse Canvas.Left="194" Canvas.Top="102" x:Name="RightEye" Height="30" Stroke="Black" StrokeThickness="2" Width="30" />
                <Ellipse Canvas.Left="224" Canvas.Top="239" Height="18" x:Name="Mouth" Stroke="Black" StrokeThickness="2" Width="64" >
                    <Ellipse.RenderTransform>
                        <ScaleTransform x:Name="MouthScaleTransform" CenterX="32" CenterY="9" ScaleX="1" ScaleY="1"/>
                    </Ellipse.RenderTransform>
                </Ellipse>

                <Rectangle Width="70" Stroke="Black" Fill="Black" StrokeThickness="10" Height="5" Canvas.Left="169" Canvas.Top="80">
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <TranslateTransform x:Name="RightBrow" />
                            <RotateTransform x:Name="RightBrowRotate" CenterX="50" Angle="0" />
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>

                <Rectangle  Width="70" Stroke="Black" Fill="Black" StrokeThickness="10" Height="5" Canvas.Left="274" Canvas.Top="80" >
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <TranslateTransform x:Name="LeftBrow" />
                            <RotateTransform x:Name="LeftBrowRotate" CenterX="20" Angle="0" />
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
                <Rectangle Canvas.Left="207" Canvas.Top="148" Fill="Black" Height="5" Stroke="Black" StrokeThickness="10" Width="50">
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <RotateTransform Angle="-70" CenterX="50" />
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
                <Rectangle Canvas.Left="246" Canvas.Top="190" Fill="Black" Height="5" Stroke="Black" StrokeThickness="10" Width="15">
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <RotateTransform Angle="0" CenterX="50" />
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
            </Canvas>
        </Grid>
    </Grid>
</Window>

Consume the frame

We will first the check that the tracking succeeded. If it did, we will retrieve the Animation Units coefficients. Those values will tell us whether the tracked face has an opened or closed mouth or it is smiling, whether its brows are raised or not, and so on...

                if (faceFrame.TrackSuccessful)
                {
                    // Gets the AU coeffs
                    var AUCoeff = faceFrame.GetAnimationUnitCoefficients();

                    // -1 <= x <= 0  => mouth is closed
                    // 0 < x < 1 => mouth is opening
                    // x == 1 => mouth is fully opened
                    var jawLowerer = AUCoeff[AnimationUnit.JawLower];
                    jawLowerer = jawLowerer < 0 ? 0 : jawLowerer;
                    MouthScaleTransform.ScaleY = jawLowerer * 5 + 0.1;
                    MouthScaleTransform.ScaleX = (AUCoeff[AnimationUnit.LipStretcher] + 1);

                    // Brows raising
                    LeftBrow.Y = RightBrow.Y = (AUCoeff[AnimationUnit.BrowLower]) * 40;

                    // brows angle
                    RightBrowRotate.Angle = (AUCoeff[AnimationUnit.BrowRaiser] * 20);
                    LeftBrowRotate.Angle = -RightBrowRotate.Angle;

                    // Face angle on the Z axis
                    CanvasRotate.Angle = faceFrame.Rotation.Z;
                }

In the above code, we adapt the values to create a nice animation because all of the coefficients values are within the range of -1 and 1.


That's all for face tracking ! You can see that it is really easy to use, and the tracking seems precise and smooth.

We could regret that - despite the fact that it is a recurrent request from developers - there is still no hand tracking API, but Face Tracking is already a great improvement and seeing how fast the Kinect Team delivered that release, maybe we could expect a good surprise for the next version. However, nothing has been announced in that direction. Wait and see!

Kinect SDK 1.5 - Le FaceTracking en C#

1. June 2012 15:45 by Renaud in   //  Tags:   //   Comments (3)

 Avec la sortir du SDK 1.5, on a droit à quelques nouveautés bien sympathiques, dont le très appréciable toolkit de détection faciale : Microsoft.Kinect.Toolkit.FaceTracking !

L'idée est excellente et pourra certainement apporter de nouvelles utilisations intéressantes de la Kinect !

J'ai voulu moi aussi tester cette API et voir ce que je pouvais en tirer en combinant mes talents d'artistes à mes compétences en programmation... Le résultat est bluffant ! :D Je vous montre !

 

Ce visage a été grossièrement dessiné à partir de quelques formes en WPF, et on va utiliser la fonctionnalité de détection faciale pour l'animer ! Dans cette application, on n'utilisera qu'une petite partie des informations que l'on peut obtenir grâce à la Kinect, mais l'intérêt est surtout de montrer comment tout cela fonctionne !

Vous pouvez télécharger le projet ici pour tester par vous même : http://sdrv.ms/KMjNMQ


Installation des ressources

Pour pouvoir utiliser la détection faciale, il faut d'abord installer le SDK 1.5 ainsi que la boîte à outils (Kinect for Windows Developer Toolkit). Le tout est téléchargeable sur le site de référence:

http://www.microsoft.com/en-us/kinectforwindows/develop/developer-downloads.aspx.

Une fois installé, vous pourrez retrouver cette ligne dans le panneau de configuration:

Le Toolkit installera notamment Kinect Studio, une flopée de projets d'exemples en C#/VB.Net/C++, et deux librairies pour la détection faciale (compilées en 32 et 64 bits) :

  • FaceTrackData.dll
  • FaceTrackLib.dll

Le tout se trouve dans le même dossier d'installation que le SDK : 

Si vous développez une application C++, vous pouvez directement utiliser les deux librairies citées ci-dessus. Dans le cas contraire, il faudra utilisé un wrapper pour exposer ces librairies en code managé.

Par chance, pour pouvoir commencer rapidement, le Developer Toolkit en propose également un ! Lancez le "Developer Toolkit Browser", et allez dans la rubrique Components. Là, vous trouverez deux projets :

  • Microsoft.Kinect.Toolkit
  • Microsoft.Kinect.Toolkit.FaceTracking

Vous pouvez les installer quelque part sur votre disque pour en avoir une copie.

Création d'un nouveau projet WPF/C#

Pour utiliser la détection faciale dans mon nouveau projet modestement appelé AwesomeFaceTracking, il faut inclure le projet Microsoft.Kinect.Toolkit.FaceTracking dans la solution et ensuite l'ajouter en référence au projet AwesomeFaceTracking.

Il est également nécessaire d'ajouter au projet les deux librairies de tracking installées avec le SDK. On les retrouve par défaut dans ce dossier: C:Program FilesMicrosoft SDKsKinectDeveloper Toolkit v1.5.0Redist . 

Vous avez besoin de ces librairies parce que le projet du Toolkit précédemment ajouté à votre solution n'est qu'un Wrapper, ce qui signifie qu'il va servir d'adaptateur et permettre d'utiliser les fonctionnalités des librairies non-managées directement dans notre application .NET.

On va également ajouter une référence à la librairie Microsoft.Kinect, et on peut finalement ajouter les espaces de noms nécessaires dans la classe MainWindow :

using Microsoft.Kinect;
using Microsoft.Kinect.Toolkit.FaceTracking;

Initialisation du KinectSensor et du FaceTracker

Pour augmenter nos chances de détecter un visage, on ne va pas hésiter et on a va utiliser toutes les capacités de la Kinect ! Dans l'application, une fois qu'on a récupéré un objet Kinect, on va donc activer les différents flux: ColorImageStream, DepthImageStream et SkeletonStream.

                // Initialize all the necessary streams:
                // - ColorStream with default format
                // - DepthStream with Near mode and lowest resolution
                // - SkeletonStream with tracking in NearReange and Seated mode.

                kinectSensor.ColorStream.Enable();

                kinectSensor.DepthStream.Range = DepthRange.Near;
                kinectSensor.DepthStream.Enable(DepthImageFormat.Resolution80x60Fps30);

                kinectSensor.SkeletonStream.EnableTrackingInNearRange = true;
                kinectSensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;
                kinectSensor.SkeletonStream.Enable(
                    new TransformSmoothParameters() {
                        Correction = 0.5f, 
                        JitterRadius = 0.05f, 
                        MaxDeviationRadius = 0.05f, 
                        Prediction = 0.5f, 
                        Smoothing = 0.5f 
                    });

                // Listen to the AllFramesReady event to receive KinectSensor's data.
                kinectSensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(kinectSensor_AllFramesReady);

                // Initialize data arrays
                colorPixelData = new byte[kinectSensor.ColorStream.FramePixelDataLength];
                depthPixelData = new short[kinectSensor.DepthStream.FramePixelDataLength];
                skeletonData = new Skeleton[6];

                // Starts the Sensor
                kinectSensor.Start();

                // Initialize a new FaceTracker with the KinectSensor
                faceTracker = new FaceTracker(kinectSensor);

J'imagine que vous savez à quoi servent toutes ces lignes. La seule nouveauté ici est la dernière qui initialise l'objet FaceTracker. Aussi, j'utilise la plus petite résolution pour le DepthImageStream. La détection fonctionne aussi et il semble que le traitement des données mette beaucoup moins de temps (avec la résolution par défaut, le résultat est saccadé).

Tout va se passer maintenant dans l'eventhandler de l'événement AllFramesReady !

        void kinectSensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            // Tout le code qui suit est à introduire ici ;)
        }

Obtenir une représentation du visage

Dans le toolkit, l'objet représentant une photographie du visage est de type FaceTrackFrame. Pour l'obtenir on va utiliser la méthode Track de la classe FaceTracker en lui passant toutes les données dont on dispose et qui seront utilisées par le tracker pour détecter le visage.

On commence par récupérer les données de chacune des frames. Pour que les données soient concordantes, on ne va au bout de processus que si on a bien reçu des données de chaque flux.

Enfin, on cherche le premier objet Skeleton représentant une personne détectée par la Kinect.

            using (ColorImageFrame colorImageFrame = e.OpenColorImageFrame())
            {
                if (colorImageFrame == null)
                    return;
                colorImageFrame.CopyPixelDataTo(colorPixelData);
            }

            using (DepthImageFrame depthImageFrame = e.OpenDepthImageFrame())
            {
                if (depthImageFrame == null)
                    return;
                depthImageFrame.CopyPixelDataTo(depthPixelData);
            }

            using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
            {
                if (skeletonFrame == null)
                    return;
                skeletonFrame.CopySkeletonDataTo(skeletonData);
            }

            var skeleton = skeletonData.FirstOrDefault(s => s.TrackingState == SkeletonTrackingState.Tracked);
            if (skeleton == null)
                return;

Si on arrive à cet endroit du code durant l'exécution, c'est qu'on a toutes les données nécessaires pour pouvoir espérer détecter un visage !

On va donc faire appel au FaceTracker en lui donnant comme infos: l'image, la profondeur, leurs formats respectifs, et le skeleton suivi pour lequel on aimerait détecter le visage.

            FaceTrackFrame faceFrame = faceTracker.Track(kinectSensor.ColorStream.Format, colorPixelData,
                                              kinectSensor.DepthStream.Format, depthPixelData,
                                              skeleton);

La variable faceFrame va contenir un objet de type FaceTrackFrame, qui représente l'état d'un visage à un instant T. Pour avoir une description détaillée, vous pouvez lire la doc MSDN : http://msdn.microsoft.com/en-us/library/jj130970. Voici toutefois en substance ce qu'il faut savoir:

Tout d'abord, TrackSuccessful est un booléen indiquant si un visage a pu être détecté ! FaceRect contient la zone dans laquelle se trouve le visage.

Mais ce sont surtout les méthodes qui nous intéressent ! Il est possible d'obtenir les positions de 87 points représentants le visage, soit dans un espace en deux ou trois dimensions, ainsi que des informations supplémentaires sur les expressions du visage !

Get3DShape() retourne une collection de points en 3D.

GetProjected3DShape() retourne la même collection mais dans un espace 2D correspondant à une image de 640x480 pixels.

GetAnimationUnitCoefficients() retourne des valeurs spécifiques décrivant la déformation d'une partie du visage par rapport à sa position initiale. C'est ce qu'on va utiliser dans la suite de ce projet ;) Je vous invite encore une fois à lire la partie consacrée aix Animation Units sur MSDN.

GetTriangles() est à utiliser en association avec Get3DShape puisqu'elle retourne une collection de triangles décrits par des index des points de ce triangle dans la collection retournée par Get3DShape. Pour ceux qui ont l'habitude de travailler avec des objets 3D, on va ainsi pouvoir créer facilement des vertices et animer un modèle du visage tout entier !

Dessin simplifié du visage

Dans cette partie, on va simplement ajouter un peu de code dans la partie XAML de MainWindows pour y afficher quelque chose ressemblant à un visage. Pour pouvoir l'animer par la suite à partir des coefficients AU, on utilise des Transformations : Translations, Rotation, Étirement, etc...

Les RenderTransform permettent de modifier le rendu graphique d'un élément visuel après qu'il ait été créé. Remarquez par exemple la bouche (Ellipse appelée Mouth) : elle est accompagné d'un ScaleTransform qui permet de modifier l'échelle de l'axe des X ou des Y. On va l'utiliser pour reproduire les mouvements de la bouche qui s'ouvre et se ferme !

<Window x:Class="AwesomeFaceTracking.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid>
            <Canvas x:Name="MainCanvas" Width="500" Height="500">
                <Canvas.RenderTransform>
                    <TransformGroup>
                        <RotateTransform x:Name="CanvasRotate" CenterX="250" CenterY="250" />
                    </TransformGroup>
                </Canvas.RenderTransform>
                <Ellipse Width="300" Height="300" x:Name="Face"  StrokeThickness="2" Stroke="Black" Canvas.Left="105" Canvas.Top="6" />
                <Ellipse Width="30" Height="30" x:Name="LeftEye" Stroke="Black" StrokeThickness="2" Canvas.Left="289" Canvas.Top="102" />
                <Ellipse Canvas.Left="194" Canvas.Top="102" x:Name="RightEye" Height="30" Stroke="Black" StrokeThickness="2" Width="30" />
                <Ellipse Canvas.Left="224" Canvas.Top="239" Height="18" x:Name="Mouth" Stroke="Black" StrokeThickness="2" Width="64" >
                    <Ellipse.RenderTransform>
                        <ScaleTransform x:Name="MouthScaleTransform" CenterX="32" CenterY="9" ScaleX="1" ScaleY="1"/>
                    </Ellipse.RenderTransform>
                </Ellipse>

                <Rectangle Width="70" Stroke="Black" Fill="Black" StrokeThickness="10" Height="5" Canvas.Left="169" Canvas.Top="80">
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <TranslateTransform x:Name="RightBrow" />
                            <RotateTransform x:Name="RightBrowRotate" CenterX="50" Angle="0" />
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>

                <Rectangle  Width="70" Stroke="Black" Fill="Black" StrokeThickness="10" Height="5" Canvas.Left="274" Canvas.Top="80" >
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <TranslateTransform x:Name="LeftBrow" />
                            <RotateTransform x:Name="LeftBrowRotate" CenterX="20" Angle="0" />
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
                <Rectangle Canvas.Left="207" Canvas.Top="148" Fill="Black" Height="5" Stroke="Black" StrokeThickness="10" Width="50">
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <RotateTransform Angle="-70" CenterX="50" />
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
                <Rectangle Canvas.Left="246" Canvas.Top="190" Fill="Black" Height="5" Stroke="Black" StrokeThickness="10" Width="15">
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <RotateTransform Angle="0" CenterX="50" />
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
            </Canvas>
        </Grid>
    </Grid>
</Window>

Consommer la frame !

On va donc commencer par vérifier que la détection a correctement fonctionné. Si c'est le cas, on récupère les Animation Units. Ces données vont ainsi indiquer si la personne trackée ouvre ou ferme la bouche, hausse ou fronce les sourcils, fait un sourire ou a la bouche droite.

                if (faceFrame.TrackSuccessful)
                {
                    // Récupération des coefficients AU
                    var AUCoeff = faceFrame.GetAnimationUnitCoefficients();

                    // -1 <= x <= 0  => bouche fermée
                    // 0 < x < 1 => bouche entrouverte
                    // x == 1 => bouche entièrement ouverte
                    var jawLowerer = AUCoeff[AnimationUnit.JawLower];
                    jawLowerer = jawLowerer < 0 ? 0 : jawLowerer;
                    MouthScaleTransform.ScaleY = jawLowerer * 5 + 0.1;
                    MouthScaleTransform.ScaleX = (AUCoeff[AnimationUnit.LipStretcher] + 1);

                    // Élévation des sourcils
                    LeftBrow.Y = RightBrow.Y = (AUCoeff[AnimationUnit.BrowLower]) * 40;

                    // Ínclinaison des sourcils
                    RightBrowRotate.Angle = (AUCoeff[AnimationUnit.BrowRaiser] * 20);
                    LeftBrowRotate.Angle = -RightBrowRotate.Angle;

                    // Inclinaison du visage par rapport à l'axe Z
                    CanvasRotate.Angle = faceFrame.Rotation.Z;
                }

Dans cet exemple de code, on adapte un petit peu les coefficients pour donner un rendu sympathique à l'animation parce que tous les coefficients sont des valeurs comprises entre - 1 et 1.


Voilà donc pour la détection du visage ! On notera la simplicité d'utilisation. Il suffit de donner les bonnes informations à l'objet de détection faciale pour qu'il fasse tout le boulot. Cela montre bien l'intérêt de la Kinect et de la quantité importante de données qu'elle peut fournir ! En temps normal, la détection aurait dû se faire uniquement sur base des couleurs, mais ici on peut en plus utiliser les distances et la position du squelette pour cadrer et détecter les différentes parties du visage.

Concernant la détection des mains et des doigts maintenant - et même s'il est vrai que c'est une demande récurrente des développeurs - il n'y a toujours pas d'API dans le SDK Kinect. Étant donné la vitesse avec laquelle la release 1.5 a été publiée, on peut peut-être espérer une bonne surprise pour la prochaine version. Mais rien n'a été suggéré dans ce sens pour le moment.

Ça code partout en Belgique : les dates à ne pas manquer !

1. June 2012 13:06 by Renaud in   //  Tags:   //   Comments (0)

Si certains pensent encore qu'il ne se passe pas grand chose en Belgique, les voilà servis ! ^^

Cet été, il y a déjà au moins quatre événements majeurs à ne pas manquer ! Dans l'ordre, on retrouve:

  • Le Microsoft Community Day 2012, le 21 juin : l'événement qui regroupe toutes les communautés et users groups de Belgique ! Une journée gratuite pour apprendre plein de trucs cools: http://www.communityday.be/. Attention d'après un tweet récent (3 juin), il ne reste que 50 places ! Donc courrez vous inscrire ;)
  • BeMyApp, du 29 juin au 1 juillet : 48h de pour coder une killer app sur l'environnement de son choix (Windows Phone, iOS, Android, web) et défendre la Belgique dans une compétition mondiale !  Toutes les infos sont disponibles ici: http://be.bemyapp.com/. Ca ne s'adresse pas uniquement aux développeurs, mais aussi aux porteurs d'idées, aux designers, et aux supers touristes ! :D L'entrée est gratuite pour tout le monde. Donc sauf cas de force majeure, il n'y a pas vraiment à hésiter!
  • Windows 8 Summer App-a-thon, le 12 juillet : Coding on the beach, parce que c'est pas vrai qu'on a peur du soleil ! Une journée de dev à la mer du nord sous le soleil de Belgique. Faudra penser à apporter de quoi bien s'hydrater (ce n'est pas @svidouse qui me contredira !). La location exacte n'est pas encore annoncée, mais vous pouvez rester au courant en vous inscrivant déjà sur facebook: https://www.facebook.com/events/316680961739310
  • Windows 8 Summer App-a-thon , le 8 août : pour ceux qui n'auront pas eu la chance de participer à la première édition, ou ceux qui sont très motivés, voici la version Metropolitaine qui aura lieu du côté d'Anvers, dans un endroit encore tenu secret ! Vous pouvez suivre les nouvelles à propos de cet event ici: https://www.facebook.com/events/283129108449164/

Enfin, notez aussi ces quelques dates :

Sessions gratuites d'introduction au SDK Kinect 1.5  :

6 juin : @micbelgique, sur Mons : http://events.mic-belgique.be/event/kinect-sdk-hands-on--3 13 juin : @MICBrussels : http://micbru.fikket.com/event/kinect-sdk-hands-on--5 3 juillet : @MICBrussels : http://micbru.fikket.com/event/kinect-sdk-hands-on--6

Visionnage en live de la session #MeetAzure présentée par Scott Guthrie :

7 juin : @micbelgique, sur Mons : http://mic.fikket.com/event/meet-windows-azure-live


Il y a certainement encore beaucoup de choses à venir ! N'hésitez pas à me suivre sur twitter (@DumontRenaud) pour être tenus au courant !

Vous pouvez également suivre @DavidHernie et @micbelgique pour être les premiers informés ! ;)


Update 14/06 : Les inscriptions pour le Summer App-a-thon à la côté belge sont ouvertes !

TextBox

About the author

I'm a developer, blog writer, and author, mainly focused on Microsoft technologies (but not only Smile). I'm Microsoft MVP Client Development since July 2013.

Microsoft Certified Professional

I'm currently working as an IT Evangelist with an awesome team at the Microsoft Innovation Center Belgique, where I spend time and energy helping people to develop their projects. I also give training to enthusiastic developers and organize afterworks with the help of the Belgian community.

MIC Belgique

Take a look at my first book (french only): Développez en HTML 5 pour Windows 8

Développez en HTML5 pour Windows 8

Membre de l'association Fier d'être développeur

TextBox

Month List