From 241d2a6ffbded75d98a3a520de2d7251532f8927 Mon Sep 17 00:00:00 2001 From: MarcEricMartel Date: Wed, 3 May 2023 11:57:03 -0400 Subject: [PATCH] PUSH --- .../JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj | 2 +- .../JeuHoy_WPF_Natif/Model/GestionKinect.cs | 187 ++++++++++++++++++ .../JeuHoy_WPF_Natif/Model/Squelette.cs | 33 +--- 3 files changed, 190 insertions(+), 32 deletions(-) create mode 100644 JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/GestionKinect.cs diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj b/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj index 9dbe294..62de708 100644 --- a/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj @@ -61,10 +61,10 @@ + - diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/GestionKinect.cs b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/GestionKinect.cs new file mode 100644 index 0000000..676ae8b --- /dev/null +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/GestionKinect.cs @@ -0,0 +1,187 @@ +using JeuHoy_WPF; +using Microsoft.Kinect; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows.Media.Imaging; +using System.Windows.Media; +using System.Windows.Shapes; +using System.Windows; + +namespace JeuHoy_WPF_Natif.Model { + public class GestionKinect { + public Image Image { get; set; } + public string Console { get; set; } + public Canvas Canvas { get; set; } + public double[] Body { get; set; } + + private KinectSensor _sensor; + private MultiSourceFrameReader _multiSourceFrameReader; + private BodyFrameReader _bodyFrameReader; + private WriteableBitmap _bitmap; + + private byte[] _picPixels = null; + public GestionKinect() { + _sensor = KinectSensor.GetDefault(); + if (_sensor != null) { + _sensor.Open(); + + //Lecture des images + _multiSourceFrameReader = _sensor.OpenMultiSourceFrameReader(FrameSourceTypes.Color); + _multiSourceFrameReader.MultiSourceFrameArrived += MultiSourceFrameReader_MultiSourceFrameArrived; + + FrameDescription frameDescription = _sensor.ColorFrameSource.FrameDescription; + _picPixels = new byte[frameDescription.Width * frameDescription.Height * 4]; + + //Lecture des squelettes détectés + _bodyFrameReader = _sensor.BodyFrameSource.OpenReader(); + _bodyFrameReader.FrameArrived += BodyFrameReader_FrameArrived; + } + } + + private void MultiSourceFrameReader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e) { + MultiSourceFrame multiSource = e.FrameReference.AcquireFrame(); + + if (multiSource == null) + return; + + + + using (ColorFrame colorFrame = multiSource.ColorFrameReference.AcquireFrame()) { + if (colorFrame != null) { + FrameDescription frameDescription = colorFrame.FrameDescription; + if (_bitmap == null) + _bitmap = new WriteableBitmap(frameDescription.Width, + frameDescription.Height, + 96.0, + 96.0, + PixelFormats.Bgra32, + null); + colorFrame.CopyConvertedFrameDataToArray(_picPixels, ColorImageFormat.Bgra); + _bitmap.Lock(); + Marshal.Copy(_picPixels, 0, _bitmap.BackBuffer, _picPixels.Length); + _bitmap.AddDirtyRect(new Int32Rect(0, 0, _bitmap.PixelWidth, _bitmap.PixelHeight)); + _bitmap.Unlock(); + Image.Source = _bitmap; + } + } + } + + public WriteableBitmap GetImage() => _bitmap; + + + private void BodyFrameReader_FrameArrived(object sender, BodyFrameArrivedEventArgs e) { + using (BodyFrame bodyFrame = e.FrameReference.AcquireFrame()) { + if (bodyFrame == null) + return; + Body[] bodies = new Body[bodyFrame.BodyCount]; + bodyFrame.GetAndRefreshBodyData(bodies); + Body body = bodies.FirstOrDefault(b => b.IsTracked); + + if (body != null) { + DessinerSquelette(body, _sensor); + } + } + + } + + + /// + /// Dessine un ellipse pour chacune des jointure du squelette détecté. + /// + /// Le joueur détecté + /// Le sensor Kinect + private void DessinerSquelette(Body body, KinectSensor sensor) { + try { + if (body != null) { + Canvas.Children.Clear(); + Joint[] joints = body.Joints.Values.ToArray(); + for (int i = 0; i < joints.Count(); i++) + DrawJoint(sensor, joints[i], CstApplication.BODY_ELLIPSE_SIZE, Canvas); + } + } catch (Exception ex) { + Console = ex.Message; + } + + if (Body is null) + Body = new double[CstApplication.SKELETONCOUNT * 2]; + + Vector trans = (Vector)GetPoint(sensor, body.Joints[JointType.Head].Position, new Vector(0, 0)); + for (int i = 0; i < CstApplication.SKELETONCOUNT; ++i) { + Point po = GetPoint(sensor, body.Joints[Squelette.Joints[i]].Position, trans); + Body[i * 2] = po.X; + Body[i * 2 + 1] = po.Y; + } + } + + /// + /// Dessine le joint d'un squellete d'un senseur Kinect sur le canvas passé en paramètre + /// + /// + /// + /// + /// + private void DrawJoint(KinectSensor sensor, Joint joint, int size, Canvas canvas) { + if (joint.Position.X != 0 && joint.Position.Y != 0 && joint.Position.Z != 0) { + // Convertir la position du joint en coordonnées d'écran + System.Windows.Point point = GetPoint(sensor, joint.Position, canvas.Height, canvas.Width); + + // Créer un cercle à la position du joint + Ellipse ellipse = new Ellipse(); + ellipse.Fill = new SolidColorBrush(Colors.Yellow); + ellipse.Width = size; + ellipse.Height = size; + + // Positionner le cercle sur l'élément de dessin Canvas + Canvas.SetLeft(ellipse, point.X - size / 2); + Canvas.SetTop(ellipse, point.Y - size / 2); + + // Ajouter le cercle à l'élément de dessin Canvas + canvas.Children.Add(ellipse); + } + } + + /// + /// Retourne le point x,y d'un joint par rapport à la taille d'un canvas. + /// J'ai permis de dépasser le canvas car je trouvais ça drole :-) + /// + /// + /// + /// + /// + /// + public System.Windows.Point GetPoint(KinectSensor sensor, CameraSpacePoint position, double iCanvasHeight, double iCanvasWidth) { + System.Windows.Point point = new System.Windows.Point(); + + DepthSpacePoint depthPoint = sensor.CoordinateMapper.MapCameraPointToDepthSpace(position); + point.X = float.IsInfinity(depthPoint.X) ? 0.0 : depthPoint.X; + point.Y = float.IsInfinity(depthPoint.Y) ? 0.0 : depthPoint.Y; + + // La Kinect pour Xbox One utilise également le SDK 2 de Microsoft, et sa résolution de profondeur est de 512x424 pixels. + //// Ainsi, la résolution de la carte de profondeur pour la Kinect pour Xbox One est également de 512x424 pixels. + point.X = point.X / 512 * iCanvasHeight; + point.Y = point.Y / 424 * iCanvasWidth; + + return point; + } + + private Point GetPoint(KinectSensor sensor, CameraSpacePoint position, Vector trans) { + Point point = new System.Windows.Point(); + + DepthSpacePoint depthPoint = sensor.CoordinateMapper.MapCameraPointToDepthSpace(position); + point.X = float.IsInfinity(depthPoint.X) ? 0.0 : depthPoint.X; + point.Y = float.IsInfinity(depthPoint.Y) ? 0.0 : depthPoint.Y; + + // La Kinect pour Xbox One utilise également le SDK 2 de Microsoft, et sa résolution de profondeur est de 512x424 pixels. + //// Ainsi, la résolution de la carte de profondeur pour la Kinect pour Xbox One est également de 512x424 pixels. + point.X = point.X / 512; + point.Y = point.Y / 424; + + return Point.Subtract(point, trans); + } + } +} diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Squelette.cs b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Squelette.cs index bf80195..94d45e8 100644 --- a/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Squelette.cs +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Squelette.cs @@ -9,7 +9,7 @@ using System.Windows; namespace JeuHoy_WPF_Natif.Model { public class Squelette { - static private JointType[] _joints = new JointType[CstApplication.SKELETONCOUNT] { + static public readonly JointType[] Joints = new JointType[CstApplication.SKELETONCOUNT] { JointType.HandLeft, JointType.HandRight, JointType.ElbowLeft, @@ -29,38 +29,9 @@ namespace JeuHoy_WPF_Natif.Model { public double[] Points => _sque; - public Squelette(KinectSensor kin, Body body, string reponse) { - Vector trans = (Vector)GetPoint(kin, body.Joints[JointType.Head].Position, new Vector(0,0)); - - for (int i = 0; i < CstApplication.SKELETONCOUNT; ++i) { - Point po = GetPoint(kin, body.Joints[_joints[i]].Position, trans); - - _sque[i * 2] = po.X; - _sque[i * 2 + 1] = po.Y; - } - - if (reponse.Length == 1) - _rep = reponse; - } - public Squelette(double[] body, string reponse) { _sque = body; _rep = reponse; - } - - private Point GetPoint(KinectSensor sensor, CameraSpacePoint position, Vector trans) { - Point point = new System.Windows.Point(); - - DepthSpacePoint depthPoint = sensor.CoordinateMapper.MapCameraPointToDepthSpace(position); - point.X = float.IsInfinity(depthPoint.X) ? 0.0 : depthPoint.X; - point.Y = float.IsInfinity(depthPoint.Y) ? 0.0 : depthPoint.Y; - - // La Kinect pour Xbox One utilise également le SDK 2 de Microsoft, et sa résolution de profondeur est de 512x424 pixels. - //// Ainsi, la résolution de la carte de profondeur pour la Kinect pour Xbox One est également de 512x424 pixels. - point.X = point.X / 512; - point.Y = point.Y / 424; - - return Point.Subtract(point, trans); - } + } } }