You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

365 lines
14 KiB

using Lib;
using Microsoft.Kinect;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp
{
/// <summary>
/// Logique d'interaction pour MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private KinectSensor kinectSensor = null;
// Attribut captor color
private ColorFrameReader colorFrameReader = null;
private WriteableBitmap colorBitmap = null;
// Attribut captor Body
private BodyFrameReader bodyFrameReader = null;
private Body[] bodies = null;
// Attribut captor Depth
private DepthFrameReader depthFrameReader = null;
private WriteableBitmap depthBitmap = null;
private byte[] depthPixels;
// Attribut captor InfraRouge
private InfraredFrameReader infraredFrameReader = null;
private byte[] infraredPixels;
private WriteableBitmap infraredBitmap;
// Propriété publique pour le binding
public WriteableBitmap ColorBitmap
{
get { return this.colorBitmap; }
}
public WriteableBitmap DepthBitmap
{
get { return this.depthBitmap; }
}
public WriteableBitmap InfraredBitmap
{
get { return this.infraredBitmap; }
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
// Initialiser la Kinect
this.kinectSensor = KinectSensor.GetDefault();
// Capteur couleur
// Ouvrir le lecteur de flux de couleur
this.colorFrameReader = this.kinectSensor.ColorFrameSource.OpenReader();
// Frame description pour les images de couleur
FrameDescription colorFrameDescription = this.kinectSensor.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);
// Créer le bitmap pour afficher l'image
this.colorBitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);
// Gérer l'événement FrameArrived pour le flux de couleur
this.colorFrameReader.FrameArrived += this.Reader_ColorFrameArrived;
// Initialisation du BodyFrameReader
this.bodyFrameReader = this.kinectSensor.BodyFrameSource.OpenReader();
this.bodyFrameReader.FrameArrived += this.Reader_BodyFrameArrived;
// Initialiser le tableau des corps
this.bodies = new Body[this.kinectSensor.BodyFrameSource.BodyCount];
/* Capteur profondeur
// Initialisation du DepthFrameReader
this.depthFrameReader = this.kinectSensor.DepthFrameSource.OpenReader();
this.depthFrameReader.FrameArrived += this.Reader_DepthFrameArrived;
FrameDescription depthFrameDescription = this.kinectSensor.DepthFrameSource.FrameDescription;
// Initialisez depthPixels pour stocker les données de chaque pixel
this.depthPixels = new byte[depthFrameDescription.Width * depthFrameDescription.Height];
// Initialisez depthBitmap pour afficher les données de profondeur
this.depthBitmap = new WriteableBitmap(depthFrameDescription.Width, depthFrameDescription.Height, 96.0, 96.0, PixelFormats.Gray8, null);
// Capteur infra
// Initialisation du InfraredFrameReader
this.infraredFrameReader = this.kinectSensor.InfraredFrameSource.OpenReader();
this.infraredFrameReader.FrameArrived += this.Reader_InfraredFrameArrived;
FrameDescription infraredFrameDescription = this.kinectSensor.InfraredFrameSource.FrameDescription;
// Initialisez infraredPixels pour stocker les données de chaque pixel
this.infraredPixels = new byte[infraredFrameDescription.Width * infraredFrameDescription.Height];
// Initialisez infraredBitmap pour afficher les données infrarouges
this.infraredBitmap = new WriteableBitmap(infraredFrameDescription.Width, infraredFrameDescription.Height, 96.0, 96.0, PixelFormats.Gray8, null);
*/
// Ouvrir la Kinect
this.kinectSensor.Open();
}
private void Reader_ColorFrameArrived(object sender, ColorFrameArrivedEventArgs e)
{
using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
{
if (colorFrame != null)
{
FrameDescription colorFrameDescription = colorFrame.FrameDescription;
using (KinectBuffer colorBuffer = colorFrame.LockRawImageBuffer())
{
this.colorBitmap.Lock();
// Vérifier si la taille de l'image a changé
if ((colorFrameDescription.Width == this.colorBitmap.PixelWidth) && (colorFrameDescription.Height == this.colorBitmap.PixelHeight))
{
colorFrame.CopyConvertedFrameDataToIntPtr(
this.colorBitmap.BackBuffer,
(uint)(colorFrameDescription.Width * colorFrameDescription.Height * 4),
ColorImageFormat.Bgra);
this.colorBitmap.AddDirtyRect(new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight));
}
this.colorBitmap.Unlock();
}
}
}
}
// Assurez-vous de fermer correctement le lecteur et le capteur Kinect lors de la fermeture de la fenêtre
private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (this.colorFrameReader != null)
{
this.colorFrameReader.Dispose();
this.colorFrameReader = null;
}
if (this.kinectSensor != null)
{
this.kinectSensor.Close();
this.kinectSensor = null;
}
}
private void Reader_BodyFrameArrived(object sender, BodyFrameArrivedEventArgs e)
{
using (var bodyFrame = e.FrameReference.AcquireFrame())
{
if (bodyFrame != null)
{
bodyFrame.GetAndRefreshBodyData(this.bodies);
skeletonCanvas.Children.Clear(); // Nettoyer le canvas avant de dessiner
foreach (var body in this.bodies)
{
if (body.IsTracked)
{
// Dessiner le squelette
DrawSkeleton(body);
}
}
}
}
}
private void DrawSkeleton(Body body)
{
// Tête et cou
DrawBone(body, JointType.Head, JointType.Neck);
DrawBone(body, JointType.Neck, JointType.SpineShoulder);
// Torse
DrawBone(body, JointType.SpineShoulder, JointType.SpineMid);
DrawBone(body, JointType.SpineMid, JointType.SpineBase);
DrawBone(body, JointType.SpineShoulder, JointType.ShoulderRight);
DrawBone(body, JointType.SpineShoulder, JointType.ShoulderLeft);
DrawBone(body, JointType.SpineBase, JointType.HipRight);
DrawBone(body, JointType.SpineBase, JointType.HipLeft);
// Bras droit
DrawBone(body, JointType.ShoulderRight, JointType.ElbowRight);
DrawBone(body, JointType.ElbowRight, JointType.WristRight);
DrawBone(body, JointType.WristRight, JointType.HandRight);
DrawBone(body, JointType.HandRight, JointType.HandTipRight);
DrawBone(body, JointType.WristRight, JointType.ThumbRight);
// Bras gauche
DrawBone(body, JointType.ShoulderLeft, JointType.ElbowLeft);
DrawBone(body, JointType.ElbowLeft, JointType.WristLeft);
DrawBone(body, JointType.WristLeft, JointType.HandLeft);
DrawBone(body, JointType.HandLeft, JointType.HandTipLeft);
DrawBone(body, JointType.WristLeft, JointType.ThumbLeft);
// Jambe droite
DrawBone(body, JointType.HipRight, JointType.KneeRight);
DrawBone(body, JointType.KneeRight, JointType.AnkleRight);
DrawBone(body, JointType.AnkleRight, JointType.FootRight);
// Jambe gauche
DrawBone(body, JointType.HipLeft, JointType.KneeLeft);
DrawBone(body, JointType.KneeLeft, JointType.AnkleLeft);
DrawBone(body, JointType.AnkleLeft, JointType.FootLeft);
// Dessinez les joints
foreach (JointType jointType in body.Joints.Keys)
{
Joint joint = body.Joints[jointType];
if (joint.TrackingState == TrackingState.Tracked)
{
DrawJoint(MapJointToScreen(joint));
}
}
}
private void DrawJoint(Point point)
{
Ellipse ellipse = new Ellipse
{
Width = 10,
Height = 10,
Fill = new SolidColorBrush(Colors.Red)
};
Canvas.SetLeft(ellipse, point.X - ellipse.Width / 2);
Canvas.SetTop(ellipse, point.Y - ellipse.Height / 2);
skeletonCanvas.Children.Add(ellipse);
}
private void DrawBone(Body body, JointType jointType0, JointType jointType1)
{
Joint joint0 = body.Joints[jointType0];
Joint joint1 = body.Joints[jointType1];
// Ne dessinez que si les deux joints sont suivis
if (joint0.TrackingState == TrackingState.Tracked && joint1.TrackingState == TrackingState.Tracked)
{
Line bone = new Line
{
Stroke = new SolidColorBrush(Colors.LightBlue),
StrokeThickness = 4,
X1 = MapJointToScreen(joint0).X,
Y1 = MapJointToScreen(joint0).Y,
X2 = MapJointToScreen(joint1).X,
Y2 = MapJointToScreen(joint1).Y
};
skeletonCanvas.Children.Add(bone);
}
}
private Point MapJointToScreen(Joint joint)
{
ColorSpacePoint colorPoint = this.kinectSensor.CoordinateMapper.MapCameraPointToColorSpace(joint.Position);
// Gestion des coordonnées infinies
float x = float.IsInfinity(colorPoint.X) ? 0 : colorPoint.X;
float y = float.IsInfinity(colorPoint.Y) ? 0 : colorPoint.Y;
return new Point(x, y);
}
private void Reader_DepthFrameArrived(object sender, DepthFrameArrivedEventArgs e)
{
using (DepthFrame depthFrame = e.FrameReference.AcquireFrame())
{
if (depthFrame != null)
{
FrameDescription depthFrameDescription = depthFrame.FrameDescription;
// Créez un tableau pour stocker les données de profondeur
ushort[] depthData = new ushort[depthFrameDescription.LengthInPixels];
depthFrame.CopyFrameDataToArray(depthData);
// Traitez les données de profondeur
ProcessDepthFrameData(depthData, depthFrameDescription.LengthInPixels, depthFrame.DepthMinReliableDistance, depthFrame.DepthMaxReliableDistance);
// Mettez à jour le bitmap de profondeur
this.depthBitmap.WritePixels(
new Int32Rect(0, 0, depthFrameDescription.Width, depthFrameDescription.Height),
this.depthPixels,
depthFrameDescription.Width,
0);
}
}
}
private void ProcessDepthFrameData(ushort[] depthData, uint depthFrameDataSize, ushort minDepth, ushort maxDepth)
{
// Convertir les données de profondeur en niveaux de gris
for (int i = 0; i < depthFrameDataSize; ++i)
{
ushort depth = depthData[i];
this.depthPixels[i] = (byte)(depth >= minDepth && depth <= maxDepth ? (depth % 256) : 0);
}
}
private void ProcessInfraredFrameData(ushort[] frameData, uint frameDataSize)
{
// Convertir les données infrarouges en niveaux de gris
for (int i = 0; i < frameDataSize; ++i)
{
// Convertir la valeur infrarouge en une intensité lumineuse
byte intensity = (byte)(frameData[i] >> 8);
this.infraredPixels[i] = intensity;
}
}
private void Reader_InfraredFrameArrived(object sender, InfraredFrameArrivedEventArgs e)
{
using (InfraredFrame infraredFrame = e.FrameReference.AcquireFrame())
{
if (infraredFrame != null)
{
FrameDescription infraredFrameDescription = infraredFrame.FrameDescription;
// Créez un tableau pour stocker les données infrarouges
ushort[] infraredData = new ushort[infraredFrameDescription.LengthInPixels];
infraredFrame.CopyFrameDataToArray(infraredData);
// Traitez les données infrarouges
ProcessInfraredFrameData(infraredData, infraredFrameDescription.LengthInPixels);
// Mettez à jour le bitmap infrarouge
this.infraredBitmap.WritePixels(
new Int32Rect(0, 0, infraredFrameDescription.Width, infraredFrameDescription.Height),
this.infraredPixels,
infraredFrameDescription.Width,
0);
}
}
}
}
}