From 249f2edbfe7bd711fb154f989b6aefcf87ef8bfb Mon Sep 17 00:00:00 2001 From: Jonathan Trottier Date: Wed, 3 May 2023 10:08:00 -0400 Subject: [PATCH 1/3] squelette.Entrainement --- .../JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj | 4 +- .../View/wEntrainement.xaml.cs | 104 +++++++++++++++++- 2 files changed, 102 insertions(+), 6 deletions(-) diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj b/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj index 400938d..1254054 100644 --- a/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj @@ -282,8 +282,6 @@ Designer - - - + \ No newline at end of file diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml.cs b/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml.cs index a147dcf..ab4ab88 100644 --- a/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml.cs +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml.cs @@ -19,11 +19,22 @@ namespace JeuHoy_WPF.View /// public partial class wEntrainement : Window { - + private Dictionary _dicImgFigure = new Dictionary(); private JouerSon _son = new JouerSon(); private int _positionEnCours = 1; - + + + private KinectSensor _sensor; + private MultiSourceFrameReader _multiSourceFrameReader; + private BodyFrameReader _bodyFrameReader; + private WriteableBitmap _bitmap; + //private DisplayFrameType _displayFrameType = DisplayFrameType.Color; + + private byte[] _picPixels = null; + + + /// /// Constructeur @@ -32,6 +43,27 @@ namespace JeuHoy_WPF.View { InitializeComponent(); + + _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; + + + } + + for (int i = 1; i <= CstApplication.NBFIGURE; i++) { Uri uriSource = new Uri(AppDomain.CurrentDomain.BaseDirectory + @"./HoyContent/fig" + i + ".png", UriKind.Absolute); @@ -43,6 +75,71 @@ namespace JeuHoy_WPF.View _son.JouerSonAsync(@"./HoyContent/hoy.wav"); } + + 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(); + picKinect.Source = _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é. /// @@ -54,6 +151,7 @@ namespace JeuHoy_WPF.View { if (body != null) { + pDessinSquelette.Children.Clear(); Joint[] joints = body.Joints.Values.ToArray(); for (int i = 0; i < joints.Count(); i++) DrawJoint(sensor, joints[i], CstApplication.BODY_ELLIPSE_SIZE, pDessinSquelette); @@ -82,7 +180,7 @@ namespace JeuHoy_WPF.View // Créer un cercle à la position du joint Ellipse ellipse = new Ellipse(); - ellipse.Fill = new SolidColorBrush(Colors.Green); + ellipse.Fill = new SolidColorBrush(Colors.Yellow); ellipse.Width = size; ellipse.Height = size; From 2c70d3a645e3eaba660e90dd5c45ea9cc38e7d00 Mon Sep 17 00:00:00 2001 From: Jonathan Trottier Date: Wed, 3 May 2023 10:36:07 -0400 Subject: [PATCH 2/3] =?UTF-8?q?cam=C3=A9ra.Entrainement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JeuHoy_WPF_Natif/View/wEntrainement.xaml | 2 +- .../JeuHoy_WPF_Natif/View/wEntrainement.xaml.cs | 14 +------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml b/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml index a8e4669..53fb40a 100644 --- a/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml @@ -22,7 +22,7 @@ - + diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml.cs b/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml.cs index ab4ab88..ba871e4 100644 --- a/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml.cs +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/View/wEntrainement.xaml.cs @@ -51,7 +51,7 @@ namespace JeuHoy_WPF.View //Lecture des images _multiSourceFrameReader = _sensor.OpenMultiSourceFrameReader(FrameSourceTypes.Color); - //_multiSourceFrameReader.MultiSourceFrameArrived += MultiSourceFrameReader_MultiSourceFrameArrived; + _multiSourceFrameReader.MultiSourceFrameArrived += MultiSourceFrameReader_MultiSourceFrameArrived; FrameDescription frameDescription = _sensor.ColorFrameSource.FrameDescription; _picPixels = new byte[frameDescription.Width * frameDescription.Height * 4]; @@ -106,9 +106,6 @@ namespace JeuHoy_WPF.View } } - - - } @@ -126,16 +123,7 @@ namespace JeuHoy_WPF.View if (body != null) { DessinerSquelette(body, _sensor); - - } - - - - - - - } } From d79d1123d1f23a8493aee09aafce4080f570831e Mon Sep 17 00:00:00 2001 From: MarcEricMartel Date: Wed, 3 May 2023 10:51:31 -0400 Subject: [PATCH 3/3] PERCEPTRONIC --- .../JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj | 3 + .../JeuHoy_WPF_Natif/Model/CstApplication.cs | 2 +- .../Model/GestionPerceptrons.cs | 82 +++++++++++++++++ .../JeuHoy_WPF_Natif/Model/Perceptron.cs | 90 +++++++++++++++++++ .../JeuHoy_WPF_Natif/Model/Squelette.cs | 62 +++++++++++++ 5 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/GestionPerceptrons.cs create mode 100644 JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Perceptron.cs create mode 100644 JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Squelette.cs diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj b/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj index 400938d..c4aa736 100644 --- a/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/JeuHoy_WPF_Natif.csproj @@ -60,6 +60,9 @@ + + + diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/CstApplication.cs b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/CstApplication.cs index c523657..2b5d651 100644 --- a/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/CstApplication.cs +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/CstApplication.cs @@ -11,7 +11,7 @@ namespace JeuHoy_WPF //Nombre de figure de danse dans l'application. public const int NBFIGURE = 10; //Constante pour la Kinect - public const int SKELETONCOUNT = 6; + public const int SKELETONCOUNT = 10; public const int KINECT_DISPLAY_WIDTH = 320; public const int KINECT_DISPLAY_HEIGHT = 240; diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/GestionPerceptrons.cs b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/GestionPerceptrons.cs new file mode 100644 index 0000000..1e8440e --- /dev/null +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/GestionPerceptrons.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JeuHoy_WPF_Natif.Model { + public class GestionPerceptrons { + private Dictionary _lstPerceptrons = new Dictionary(); + private IGestionFichiers _gestionSortie = new GestionFichiersSorties(); + private List _lstData = new List(); + + /// + /// Constructeur + /// + public GestionPerceptrons() { + for (char x = '0'; x <= '9'; ++x) + _lstPerceptrons.Add(x.ToString(), new Perceptron(x.ToString())); + } + + /// + /// Charge les échantillons d'apprentissage sauvegardé sur le disque. + /// + /// Le nom du fichier + public void ChargerCoordonnees(string fichier) { _lstData = _gestionSortie.ChargerCoordonnees(fichier); } + + /// + /// Sauvegarde les échantillons d'apprentissage sauvegardé sur le disque. + /// + /// Le nom du fichier + /// En cas d'erreur retourne le code d'erreur + public int SauvegarderCoordonnees(string fichier) => _gestionSortie.SauvegarderCoordonnees(fichier, _lstData); + + /// + /// Entraine les perceptrons avec un nouveau caractère + /// + /// Les nouvelles coordonnées + /// La réponse associé(caractère) aux coordonnées + /// Le résultat de la console + public string Entrainement(Squelette coordo, string reponse) { + StringWriter sw = new StringWriter(); + + if (reponse != "") { + coordo.Reponse = reponse; + _lstData.Add(coordo); + } + + if (_lstData is null) + return ""; + + foreach (Perceptron perc in _lstPerceptrons.Values) + sw.WriteLine(perc.Entrainement(_lstData)); + return sw.ToString(); + } + + /// + /// Test le perceptron avec de nouvelles coordonnées. + /// + /// Les nouvelles coordonnées + /// Retourne la liste des valeurs possibles du perceptron + public string Tester(Squelette coord) { + string resultat = ""; + + foreach (Perceptron perc in _lstPerceptrons.Values) + if (perc.TesterNeurone(coord)) + resultat += perc.Reponse; + + if (resultat == "") + resultat = "?"; + + return resultat; + } + + /// + /// Obtient une liste des coordonées. + /// + /// Une liste des coordonées. + public IList ObtenirCoordonnees() => _lstData; + + } +} diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Perceptron.cs b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Perceptron.cs new file mode 100644 index 0000000..666a575 --- /dev/null +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Perceptron.cs @@ -0,0 +1,90 @@ +using JeuHoy_WPF; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace JeuHoy_WPF_Natif.Model { + public class Perceptron { + private double _cstApprentissage; + private double[] _poidsSyn; + private string _reponse = "?"; + public string Reponse { get => _reponse; } + + /// + /// Constructeur de la classe. Crée un perceptron pour une réponse(caractère) qu'on veut identifier le pattern(modèle) + /// + /// La classe que défini le perceptron + public Perceptron(string reponse) { + Random _rand = new Random(); + _reponse = reponse; + _cstApprentissage = CstApplication.CONSTANTEAPPRENTISSAGE; + + _poidsSyn = new double[CstApplication.SKELETONCOUNT * 2]; + for (int x = 0; x < CstApplication.SKELETONCOUNT - 1; ++x) + _poidsSyn[x] = _rand.NextDouble(); + } + + /// + /// Faire l'apprentissage sur un ensemble de coordonnées. Ces coordonnées sont les coordonnées de tous les caractères analysés. + /// + /// La liste de coordonnées pour les caractères à analysés. + /// Les paramètres de la console + public string Entrainement(List lstCoord) { + int iNbItérations = 0, + iNbErreurs = 0; + double dSum = 0, + dPourSucc = 0; + + do { + iNbErreurs = 0; + foreach (Squelette coord in lstCoord) { + dSum = _poidsSyn[0]; + + for (int j = 1; j < _poidsSyn.Length; ++j) + dSum += _poidsSyn[j] * coord.Points[j - 1]; + + int iRes = (dSum >= 0) ? 1 : 0; + int iErr = (_reponse == coord.Reponse ? 1 : 0) - iRes; + + if (iErr != 0) { + _poidsSyn[0] = _cstApprentissage; + for (int j = 1; j < _poidsSyn.Length; ++j) + _poidsSyn[j] += _cstApprentissage * iErr * coord.Points[j - 1]; + ++iNbErreurs; + } + } + dPourSucc = (double)(lstCoord.Count - iNbErreurs) / (double)lstCoord.Count * 100.0; + ++iNbItérations; + } + while (dPourSucc < CstApplication.POURCENTCONVERGENCE && iNbItérations < CstApplication.MAXITERATION); + + return $"Perceptron: {_reponse}; Itérations: {iNbItérations} Taux Réussite: {dPourSucc.ToString("0.00")} %"; ; + } + + /// + /// Calcul la valeur(vrai ou faux) pour un les coordonnées d'un caractère. Permet au perceptron d'évaluer la valeur de vérité. + /// + /// Les poids synaptiques du perceptron + /// Le vecteur de bit correspondant aux couleurs du caractère + /// Vrai ou faux + public int ValeurEstime(double[] vecteurSyn, double[] entree) { + double dSum = vecteurSyn[0]; + + for (int j = 1; j < vecteurSyn.Length; ++j) + dSum += vecteurSyn[j] * entree[j - 1]; + + return (dSum >= 0) ? CstApplication.VRAI : CstApplication.FAUX; + } + + /// + /// Interroge la neuronnes pour un ensembles des coordonnées(d'un caractère). + /// + /// + /// + public bool TesterNeurone(Squelette squel) => ValeurEstime(_poidsSyn, squel.Points) == CstApplication.VRAI ? true : false; + } +} diff --git a/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Squelette.cs b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Squelette.cs new file mode 100644 index 0000000..f78cfea --- /dev/null +++ b/JeuHoyEtudiants/JeuHoy_WPF_Natif/Model/Squelette.cs @@ -0,0 +1,62 @@ +using JeuHoy_WPF; +using Microsoft.Kinect; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace JeuHoy_WPF_Natif.Model { + public class Squelette { + static private JointType[] _joints = new JointType[CstApplication.SKELETONCOUNT] { + JointType.HandLeft, + JointType.HandRight, + JointType.ElbowLeft, + JointType.ElbowRight, + JointType.FootLeft, + JointType.FootRight, + JointType.KneeRight, + JointType.KneeLeft, + JointType.SpineBase, + JointType.Neck + }; + + private double[] _sque = new double[CstApplication.SKELETONCOUNT * 2]; + private string _rep = "?"; + + public string Reponse { get => _rep; set => _rep = value; } + + 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; + } + + _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); + } + + + } +}