// ====================================================================
// Ref des librairies Microsoft.Kinect
// ====================================================================
using Microsoft.Kinect;
using Microsoft.Kinect.Toolkit.FaceTracking;
// ====================================================================
// Initialisation du KinectSensor et du FaceTracker
// ====================================================================
// 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(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);
// ====================================================================
//Obtenir une représentation du visage
// ====================================================================
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;
FaceTrackFrame faceFrame = faceTracker.Track(kinectSensor.ColorStream.Format, colorPixelData,
kinectSensor.DepthStream.Format, depthPixelData,
skeleton);
// ====================================================================
//Dessin simplifié du visage
// ====================================================================
<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>
// ====================================================================
// Consommation de la frame !
// ====================================================================
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;
}