📝 plus d'explications

bodyStream
Nicolas FRANCO 1 year ago
parent 22bdfb72ff
commit d26575451e

@ -101,11 +101,12 @@ namespace KinectConnection
public BodyImageStream() : base()
{
this.coordinateMapper = this.KinectSensor.CoordinateMapper;
frameDescription = this.KinectSensor.DepthFrameSource.FrameDescription;
displayHeight = frameDescription.Height;
displayWidth = frameDescription.Width;
// Torso
// Torse
this.bones.Add(new Tuple<JointType, JointType>(JointType.Head, JointType.Neck));
this.bones.Add(new Tuple<JointType, JointType>(JointType.Neck, JointType.SpineShoulder));
this.bones.Add(new Tuple<JointType, JointType>(JointType.SpineShoulder, JointType.SpineMid));
@ -115,30 +116,31 @@ namespace KinectConnection
this.bones.Add(new Tuple<JointType, JointType>(JointType.SpineBase, JointType.HipRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.SpineBase, JointType.HipLeft));
// Right Arm
// Bras droit
this.bones.Add(new Tuple<JointType, JointType>(JointType.ShoulderRight, JointType.ElbowRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.ElbowRight, JointType.WristRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.WristRight, JointType.HandRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.HandRight, JointType.HandTipRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.WristRight, JointType.ThumbRight));
// Left Arm
// Bras gauche
this.bones.Add(new Tuple<JointType, JointType>(JointType.ShoulderLeft, JointType.ElbowLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.ElbowLeft, JointType.WristLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.WristLeft, JointType.HandLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.HandLeft, JointType.HandTipLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.WristLeft, JointType.ThumbLeft));
// Right Leg
// Jambe droite
this.bones.Add(new Tuple<JointType, JointType>(JointType.HipRight, JointType.KneeRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.KneeRight, JointType.AnkleRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.AnkleRight, JointType.FootRight));
// Left Leg
// Jambe gauche
this.bones.Add(new Tuple<JointType, JointType>(JointType.HipLeft, JointType.KneeLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.KneeLeft, JointType.AnkleLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.AnkleLeft, JointType.FootLeft));
// Couleurs
this.bodyColors.Add(new Pen(Brushes.Red, 6));
this.bodyColors.Add(new Pen(Brushes.Orange, 6));
this.bodyColors.Add(new Pen(Brushes.Green, 6));
@ -188,6 +190,7 @@ namespace KinectConnection
/// <param name="e">event arguments</param>
private void Reader_BodyFrameArrived(object sender, BodyFrameArrivedEventArgs e)
{
// flag pour savoir si la donnée est reçu ou pas
bool dataReceived = false;
using (BodyFrame bodyFrame = e.FrameReference.AcquireFrame())
@ -196,27 +199,32 @@ namespace KinectConnection
{
if (this.bodies == null)
{
// ajouter des corps en fonction du bodyCount
this.bodies = new Body[bodyFrame.BodyCount];
}
// The first time GetAndRefreshBodyData is called, Kinect will allocate each Body in the array.
// As long as those body objects are not disposed and not set to null in the array,
// those body objects will be re-used.
// Une fois que GetAndRefreshBodyData est appele le Kinect va allouer chaque body dans le tableau
// Tant que le body est toujours dans le cadre il ne sera pas supprimé donc les body deja alloues
// seront réutilisé
bodyFrame.GetAndRefreshBodyData(this.bodies);
// flag
dataReceived = true;
}
}
// Si on reçoit de la donnée, alors dessiner le body
if (dataReceived)
{
using (DrawingContext dc = this.drawingGroup.Open())
{
// Draw a transparent background to set the render size
// Fond transparent
dc.DrawRectangle(Brushes.Black, null, new Rect(0.0, 0.0, displayWidth, displayHeight));
int penIndex = 0;
foreach (Body body in this.bodies)
{
// pour avoir des couleurs differentes pour chaque body
Pen drawPen = this.bodyColors[penIndex++];
if (body.IsTracked)
@ -230,8 +238,8 @@ namespace KinectConnection
foreach (JointType jointType in joints.Keys)
{
// sometimes the depth(Z) of an inferred joint may show as negative
// clamp down to 0.1f to prevent coordinatemapper from returning (-Infinity, -Infinity)
// parfois la profondeur Z peut venir negatif
// avec 0.1 on evite les coordonées negatives du coordinateMapper
CameraSpacePoint position = joints[jointType].Position;
if (position.Z < 0)
{
@ -242,14 +250,16 @@ namespace KinectConnection
jointPoints[jointType] = new Point(depthSpacePoint.X, depthSpacePoint.Y);
}
// dessiner les joints
this.DrawBody(joints, jointPoints, dc, drawPen);
// dessiner les mains
this.DrawHand(body.HandLeftState, jointPoints[JointType.HandLeft], dc);
this.DrawHand(body.HandRightState, jointPoints[JointType.HandRight], dc);
}
}
// prevent drawing outside of our render area
// empeche de dessiner hors du cadre
this.drawingGroup.ClipGeometry = new RectangleGeometry(new Rect(0.0, 0.0, displayWidth, displayHeight));
}
}
@ -260,13 +270,13 @@ namespace KinectConnection
/// </summary>
private void DrawBody(IReadOnlyDictionary<JointType, Joint> joints, IDictionary<JointType, Point> jointPoints, DrawingContext drawingContext, Pen drawingPen)
{
// Draw the bones
// Dessiner les os (lignes entre les joints)
foreach (var bone in this.bones)
{
this.DrawBone(joints, jointPoints, bone.Item1, bone.Item2, drawingContext, drawingPen);
}
// Draw the joints
// Dessiner les joints
foreach (JointType jointType in joints.Keys)
{
Brush drawBrush = null;
@ -318,14 +328,13 @@ namespace KinectConnection
Joint joint0 = joints[jointType0];
Joint joint1 = joints[jointType1];
// If we can't find either of these joints, exit
// Si ces joints n'existent pas, return (pas besoin de dessiner)
if (joint0.TrackingState == TrackingState.NotTracked ||
joint1.TrackingState == TrackingState.NotTracked)
{
return;
}
// We assume all drawn bones are inferred unless BOTH joints are tracked
Pen drawPen = this.inferredBonePen;
if ((joint0.TrackingState == TrackingState.Tracked) && (joint1.TrackingState == TrackingState.Tracked))
{

@ -21,27 +21,22 @@ namespace KinectConnection
private const int MapDepthToByte = 8000 / 256;
/// <summary>
/// Active Kinect sensor
/// </summary>
private KinectSensor kinectSensor = null;
/// <summary>
/// Reader for depth frames
/// Reader pour les données
/// </summary>
private DepthFrameReader depthFrameReader = null;
/// <summary>
/// Description of the data contained in the depth frame
/// Description du cadre (hauteur/largeur)
/// </summary>
private FrameDescription depthFrameDescription = null;
/// <summary>
/// Bitmap to display
/// Le bitmap permettant d'afficher l'image
/// </summary>
private WriteableBitmap depthBitmap = null;
/// <summary>
/// Intermediate storage for frame data converted to color
/// Stockage intermediare des données avant de convertir en couleurs
/// </summary>
private byte[] depthPixels = null;
@ -155,17 +150,17 @@ namespace KinectConnection
/// <param name="maxDepth">La plus fiable valeur maximale pour la frame</param>
private unsafe void ProcessDepthFrameData(IntPtr depthFrameData, uint depthFrameDataSize, ushort minDepth, ushort maxDepth)
{
// depth frame data is a 16 bit value
// la donnée du dephtFrame est une valeur de 16 bits
ushort* frameData = (ushort*)depthFrameData;
// convert depth to a visual representation
// traduit la profondeur en une representation visuelle
for (int i = 0; i < (int)(depthFrameDataSize / this.depthFrameDescription.BytesPerPixel); ++i)
{
// Get the depth for this pixel
// obtenir la profondeur d'un pixel
ushort depth = frameData[i];
// To convert to a byte, we're mapping the depth value to the byte range.
// Values outside the reliable depth range are mapped to 0 (black).
// Pour convertir en bytes on doit traduire la profondeur en bytes
// Des valeurs qui n'est pas dans la portée valide on met 0
this.depthPixels[i] = (byte)(depth >= minDepth && depth <= maxDepth ? (depth / MapDepthToByte) : 0);
}
}

@ -16,47 +16,47 @@ namespace KinectConnection
public class InfraredImageStream : KinectStream
{
/// <summary>
/// Maximum value (as a float) that can be returned by the InfraredFrame
/// Valeur maximale (en tant que float) que peut renvoyer InfraredFrame.
/// </summary>
private const float InfraredSourceValueMaximum = (float)ushort.MaxValue;
/// <summary>
/// The value by which the infrared source data will be scaled
/// La valeur par laquelle les données de la source infrarouge seront ajustées.
/// </summary>
private const float InfraredSourceScale = 0.75f;
/// <summary>
/// Smallest value to display when the infrared data is normalized
/// Plus petite valeur à afficher lorsque les données infrarouges sont normalisées.
/// </summary>
private const float InfraredOutputValueMinimum = 0.01f;
/// <summary>
/// Largest value to display when the infrared data is normalized
/// Plus grande valeur à afficher lorsque les données infrarouges sont normalisées.
/// </summary>
private const float InfraredOutputValueMaximum = 1.0f;
/// <summary>
/// Active Kinect sensor
/// Capteur Kinect actif.
/// </summary>
private KinectSensor kinectSensor = null;
/// <summary>
/// Reader for infrared frames
/// Lecteur pour les images infrarouges.
/// </summary>
private InfraredFrameReader infraredFrameReader = null;
/// <summary>
/// Description (width, height, etc) of the infrared frame data
/// Description (largeur, hauteur, etc.) des données du cadre infrarouge.
/// </summary>
private FrameDescription infraredFrameDescription = null;
/// <summary>
/// Bitmap to display
/// Bitmap à afficher.
/// </summary>
private WriteableBitmap infraredBitmap = null;
/// <summary>
/// Current status text to display
/// Texte d'état actuel à afficher.
/// </summary>
private string statusText = null;
@ -76,10 +76,10 @@ namespace KinectConnection
/// </summary>
public InfraredImageStream()
{
// get FrameDescription from InfraredFrameSource
// Obtient la description du cadre infrarouge à partir de InfraredFrameSource
this.infraredFrameDescription = this.KinectSensor.InfraredFrameSource.FrameDescription;
// create the bitmap to display
// Crée la bitmap à afficher
this.infraredBitmap = new WriteableBitmap(this.infraredFrameDescription.Width, this.infraredFrameDescription.Height, 96.0, 96.0, PixelFormats.Gray32Float, null);
}
@ -90,12 +90,12 @@ namespace KinectConnection
{
if (this.KinectSensor != null)
{
// open the reader for the depth frames
// Ouvre le lecteur pour les trames infrarouges
this.infraredFrameReader = this.KinectSensor.InfraredFrameSource.OpenReader();
if (this.infraredFrameReader != null)
{
// wire handler for frame arrival
// Lie le gestionnaire pour l'arrivée de la trame
this.infraredFrameReader.FrameArrived += this.Reader_InfraredFrameArrived;
}
}
@ -110,30 +110,30 @@ namespace KinectConnection
{
this.infraredFrameReader.FrameArrived -= this.Reader_InfraredFrameArrived;
// Dispose the reader to free resources.
// If we don't dispose manualy, the gc will do it for us, but we don't know when.
// Libère le lecteur pour libérer des ressources.
// Si nous ne le faisons pas manuellement, le GC le fera pour nous, mais nous ne savons pas quand.
this.infraredFrameReader.Dispose();
this.infraredFrameReader = null;
}
}
/// <summary>
/// Méthode appelée lors de l'arrivée d'un nouveau frame infrarouge.
/// Méthode appelée lors de l'arrivée d'un nouveau cadre infrarouge.
/// </summary>
/// <param name="sender">object sending the event</param>
/// <param name="e">event arguments</param>
/// <param name="sender">objet envoyant l'événement</param>
/// <param name="e">arguments de l'événement</param>
private void Reader_InfraredFrameArrived(object sender, InfraredFrameArrivedEventArgs e)
{
// InfraredFrame is IDisposable
// InfraredFrame est IDisposable
using (InfraredFrame infraredFrame = e.FrameReference.AcquireFrame())
{
if (infraredFrame != null)
{
// the fastest way to process the infrared frame data is to directly access
// the underlying buffer
// La manière la plus rapide de traiter les données du cadre infrarouge est d'accéder directement
// au tampon sous-jacent
using (Microsoft.Kinect.KinectBuffer infraredBuffer = infraredFrame.LockImageBuffer())
{
// verify data and write the new infrared frame data to the display bitmap
// Vérifie les données et écrit les nouvelles données du cadre infrarouge sur la bitmap d'affichage
if (((this.infraredFrameDescription.Width * this.infraredFrameDescription.Height) == (infraredBuffer.Size / this.infraredFrameDescription.BytesPerPixel)) &&
(this.infraredFrameDescription.Width == this.infraredBitmap.PixelWidth) && (this.infraredFrameDescription.Height == this.infraredBitmap.PixelHeight))
{
@ -150,31 +150,31 @@ namespace KinectConnection
/// Cette fonction nécessite l'option /unsafe du compilateur car nous utilisons un accès direct
/// à la mémoire native pointée par le pointeur infraredFrameData.
/// </summary>
/// <param name="infraredFrameData">Pointeur vers les données d'image InfraredFrame</param>
/// <param name="infraredFrameDataSize">Taille des données d'image InfraredFrame</param>
/// <param name="infraredFrameData">Pointeur vers les données du cadre infrarouge</param>
/// <param name="infraredFrameDataSize">Taille des données du cadre infrarouge</param>
private unsafe void ProcessInfraredFrameData(IntPtr infraredFrameData, uint infraredFrameDataSize)
{
// infrared frame data is a 16 bit value
// Les données du cadre infrarouge sont une valeur de 16 bits
ushort* frameData = (ushort*)infraredFrameData;
// lock the target bitmap
// Verrouille la bitmap cible
this.infraredBitmap.Lock();
// get the pointer to the bitmap's back buffer
// Obtient le pointeur vers le tampon arrière de la bitmap
float* backBuffer = (float*)this.infraredBitmap.BackBuffer;
// process the infrared data
// Traite les données infrarouges
for (int i = 0; i < (int)(infraredFrameDataSize / this.infraredFrameDescription.BytesPerPixel); ++i)
{
// since we are displaying the image as a normalized grey scale image, we need to convert from
// the ushort data (as provided by the InfraredFrame) to a value from [InfraredOutputValueMinimum, InfraredOutputValueMaximum]
// Comme nous affichons l'image en niveaux de gris normalisés, nous devons convertir de
// la donnée ushort (fournie par InfraredFrame) à une valeur de [InfraredOutputValueMinimum, InfraredOutputValueMaximum]
backBuffer[i] = Math.Min(InfraredOutputValueMaximum, (((float)frameData[i] / InfraredSourceValueMaximum * InfraredSourceScale) * (1.0f - InfraredOutputValueMinimum)) + InfraredOutputValueMinimum);
}
// mark the entire bitmap as needing to be drawn
// Marque toute la bitmap comme nécessitant un redessin
this.infraredBitmap.AddDirtyRect(new Int32Rect(0, 0, this.infraredBitmap.PixelWidth, this.infraredBitmap.PixelHeight));
// unlock the bitmap
// Déverrouille la bitmap
this.infraredBitmap.Unlock();
}
}

Loading…
Cancel
Save