|
1 /* |
|
2 * Projet : KINECT PROJECTS |
|
3 * Module : MIDDLEWARE |
|
4 * Sous-Module : Debug |
|
5 * Classe : DebugWindow |
|
6 * |
|
7 * Auteur : alexandre.bastien@iri.centrepompidou.fr |
|
8 * |
|
9 * Fonctionnalités : Reçoit des notifications des sous-modules Tracking, Communication et Exception. |
|
10 * Intéragit avec la fenêtre XAML de debug de façon à afficher un rendu visuel. |
|
11 */ |
|
12 |
|
13 using System; |
|
14 using System.Collections.Generic; |
|
15 using System.Linq; |
|
16 using System.Text; |
|
17 using System.Windows; |
|
18 using System.Windows.Controls; |
|
19 using System.Windows.Data; |
|
20 using System.Windows.Documents; |
|
21 using System.Windows.Input; |
|
22 using System.Windows.Media; |
|
23 using System.Windows.Media.Imaging; |
|
24 using System.Windows.Navigation; |
|
25 using System.Windows.Shapes; |
|
26 using System.Drawing; |
|
27 using System.Windows.Media.Media3D; |
|
28 using Microsoft.Kinect; |
|
29 |
|
30 using Coding4Fun.Kinect.Wpf; |
|
31 |
|
32 using Trakers.Tracking; |
|
33 using System.Threading; |
|
34 |
|
35 namespace Trakers.Debug |
|
36 { |
|
37 public partial class DebugWindow : Window |
|
38 { |
|
39 //Membre permettant d'atteindre la classe KinectMain du sous-module Tracking. |
|
40 private KinectMain kinectMain; |
|
41 //Tableau contenant une image en couleurs. |
|
42 private byte[] colorPixelData; |
|
43 //Indique si la kinect est allumée/éteinte. |
|
44 private bool on; |
|
45 //Indique si la fenêtre de debug est actuellement en cours de fermeture. |
|
46 private bool closing; |
|
47 |
|
48 /* |
|
49 * Constructeur : Affiche la fenêtre de debug en lui passant en paramètre une instanciation de la |
|
50 * classe KinectMain. |
|
51 * Au départ, la kinect est éteinte. |
|
52 */ |
|
53 public DebugWindow(KinectMain main) |
|
54 { |
|
55 InitializeComponent(); |
|
56 kinectMain = main; |
|
57 on = false; |
|
58 closing = false; |
|
59 } |
|
60 |
|
61 /* |
|
62 * Getter pour le membre indiquant la fermeture de la fenêtre de debug. |
|
63 */ |
|
64 public bool isClosing() |
|
65 { |
|
66 return closing; |
|
67 } |
|
68 |
|
69 /* |
|
70 * Est appelée à la fermeture de la fenêtre. |
|
71 */ |
|
72 private void Window_Closed(object sender, EventArgs e) |
|
73 { |
|
74 closing = true; |
|
75 //On éteint la Kinect (pour éviter qu'elle reste allumée même lorsque le programme est éteint). |
|
76 kinectMain.KinectClose(); |
|
77 } |
|
78 |
|
79 /* |
|
80 * Bouton ON/OFF. |
|
81 */ |
|
82 private void Switch_Click(object sender, RoutedEventArgs e) |
|
83 { |
|
84 //S'il valait faux, il vaut vrai maintenant et inversement. |
|
85 on = !on; |
|
86 //Si la kinect est allumée. |
|
87 if (on) |
|
88 { |
|
89 //Il affiche OFF (pour éteindre la kinect). |
|
90 Switch.Content = "OFF"; |
|
91 //On vide le label des exceptions. |
|
92 ExceptionLbl.Content = ""; |
|
93 //On initialise la Kinect. |
|
94 kinectMain.KinectInitialization(); |
|
95 } |
|
96 else |
|
97 { |
|
98 //Il affiche ON (pour allumer la kinect). |
|
99 Switch.Content = "ON"; |
|
100 //On remet à zéro tous les éléments du retour visuel. |
|
101 R1.Fill = System.Windows.Media.Brushes.DarkGray; |
|
102 R2.Fill = System.Windows.Media.Brushes.DarkGray; |
|
103 R3.Fill = System.Windows.Media.Brushes.DarkGray; |
|
104 R4.Fill = System.Windows.Media.Brushes.DarkGray; |
|
105 DistanceLbl.Content = "Distance :"; |
|
106 LeftHand.Background = System.Windows.Media.Brushes.DarkGray; |
|
107 LeftHand.Content = ""; |
|
108 RightHand.Background = System.Windows.Media.Brushes.DarkGray; |
|
109 RightHand.Content = ""; |
|
110 DebugCanvas.Children.RemoveRange(1, DebugCanvas.Children.Count - 1); |
|
111 //On éteint la Kinect. |
|
112 kinectMain.KinectClose(); |
|
113 } |
|
114 } |
|
115 |
|
116 /* |
|
117 * Récupère le flux video et met à jour le rendu visuel de debug. |
|
118 */ |
|
119 public void RefreshVideo(AllFramesReadyEventArgs e) |
|
120 { |
|
121 bool receivedData = false; |
|
122 ColorImageFrame colorImageFrameData; |
|
123 using (colorImageFrameData = e.OpenColorImageFrame()) |
|
124 { |
|
125 //Si on ne reçoit pas de trames de la kinect. |
|
126 if (colorImageFrameData == null) |
|
127 { |
|
128 //L'image est supprimée. |
|
129 DebugImage.Source = null; |
|
130 } |
|
131 //Si le tableau stockant l'image en cours est nul. |
|
132 if (colorPixelData == null) |
|
133 //On alloue un nouveau tableau. |
|
134 colorPixelData = new byte[colorImageFrameData.PixelDataLength]; |
|
135 else |
|
136 { |
|
137 //Sinon on met à jour le tableau en copiant le contenu de la trame dans le tableau. |
|
138 colorImageFrameData.CopyPixelDataTo(colorPixelData); |
|
139 receivedData = true; |
|
140 } |
|
141 } |
|
142 //Si on a des données dans le tableau et que la kinect est allumée. |
|
143 if (receivedData && on) |
|
144 { |
|
145 //On met à jour l'image de la caméra. |
|
146 DebugImage.Source = BitmapSource.Create(colorImageFrameData.Width, colorImageFrameData.Height, 96, 96, PixelFormats.Bgr32, null, colorPixelData, colorImageFrameData.Width * colorImageFrameData.BytesPerPixel); |
|
147 DebugImage.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; |
|
148 DebugImage.VerticalAlignment = System.Windows.VerticalAlignment.Center; |
|
149 DebugImage.Stretch = Stretch.Fill; |
|
150 } |
|
151 } |
|
152 |
|
153 /* |
|
154 * Affiche la distance de l'utilisateur dans le rendu visuel. |
|
155 * Sous forme de nombre en m et de rectangles changeant de couleur en fonction de la distance. |
|
156 */ |
|
157 public void showDistance(float distance) |
|
158 { |
|
159 DistanceLbl.Content = "Distance : " + distance; |
|
160 |
|
161 if (distance > 0 && distance < 1) |
|
162 { |
|
163 R1.Fill = System.Windows.Media.Brushes.Red; |
|
164 R2.Fill = System.Windows.Media.Brushes.DarkGray; |
|
165 R3.Fill = System.Windows.Media.Brushes.DarkGray; |
|
166 R4.Fill = System.Windows.Media.Brushes.DarkGray; |
|
167 } |
|
168 else if (distance > 1 && distance < 2) |
|
169 { |
|
170 R1.Fill = System.Windows.Media.Brushes.DarkGray; |
|
171 R2.Fill = System.Windows.Media.Brushes.Orange; |
|
172 R3.Fill = System.Windows.Media.Brushes.DarkGray; |
|
173 R4.Fill = System.Windows.Media.Brushes.DarkGray; |
|
174 } |
|
175 else if (distance > 2 && distance < 3) |
|
176 { |
|
177 R1.Fill = System.Windows.Media.Brushes.DarkGray; |
|
178 R2.Fill = System.Windows.Media.Brushes.DarkGray; |
|
179 R3.Fill = System.Windows.Media.Brushes.Yellow; |
|
180 R4.Fill = System.Windows.Media.Brushes.DarkGray; |
|
181 } |
|
182 else if (distance > 3 && distance < 4) |
|
183 { |
|
184 R1.Fill = System.Windows.Media.Brushes.DarkGray; |
|
185 R2.Fill = System.Windows.Media.Brushes.DarkGray; |
|
186 R3.Fill = System.Windows.Media.Brushes.DarkGray; |
|
187 R4.Fill = System.Windows.Media.Brushes.White; |
|
188 } |
|
189 } |
|
190 |
|
191 /* |
|
192 * Affiche la détection de la main droite via un label. |
|
193 */ |
|
194 public void showRightHandRect(bool show) |
|
195 { |
|
196 if (show) |
|
197 RightHand.Background = System.Windows.Media.Brushes.Blue; |
|
198 else |
|
199 RightHand.Background = System.Windows.Media.Brushes.DarkGray; |
|
200 } |
|
201 |
|
202 /* |
|
203 * Affiche la détection de la main gauche via un label. |
|
204 */ |
|
205 public void showLeftHandRect(bool show) |
|
206 { |
|
207 if (show) |
|
208 LeftHand.Background = System.Windows.Media.Brushes.Blue; |
|
209 else |
|
210 LeftHand.Background = System.Windows.Media.Brushes.DarkGray; |
|
211 } |
|
212 |
|
213 /* |
|
214 * Dessine les noeuds du squelette dans le rendu visuel. |
|
215 */ |
|
216 public void drawJoints(JointCollection joints, Skeleton first) |
|
217 { |
|
218 //On enlève tout élément du Canvas à part l'image, de manière à mettre à jour la position du squelette. |
|
219 DebugCanvas.Children.RemoveRange(1, DebugCanvas.Children.Count - 1); |
|
220 |
|
221 //Pour chaque noeud. |
|
222 foreach (Joint joint in first.Joints) |
|
223 { |
|
224 //On crée une ellipse de taille 20 et de largeur 20. |
|
225 Ellipse node = new Ellipse(); |
|
226 node.Height = 20; |
|
227 node.Width = 20; |
|
228 |
|
229 //S'il s'agit d'un noeud de tête, on le colorie en rouge, sinon en bleu. |
|
230 if (joint.JointType == JointType.Head) |
|
231 node.Fill = System.Windows.Media.Brushes.Red; |
|
232 else if(joint.JointType == JointType.ShoulderCenter) |
|
233 node.Fill = System.Windows.Media.Brushes.Green; |
|
234 else if(joint.JointType == JointType.HipCenter) |
|
235 node.Fill = System.Windows.Media.Brushes.Green; |
|
236 else if (joint.JointType == JointType.HandRight) |
|
237 node.Fill = System.Windows.Media.Brushes.Red; |
|
238 else |
|
239 node.Fill = System.Windows.Media.Brushes.Blue; |
|
240 |
|
241 //On met à la bonne échelle les coordonnées des positions des noeuds. |
|
242 Joint scaledJoint = Coding4Fun.Kinect.Wpf.SkeletalExtensions.ScaleTo(joint, 600, 400, 0.75f, 0.75f); |
|
243 |
|
244 //On positionne le noeud dans le Canvas, et on l'ajoute. |
|
245 Canvas.SetLeft(node, scaledJoint.Position.X); |
|
246 Canvas.SetTop(node, scaledJoint.Position.Y); |
|
247 DebugCanvas.Children.Add(node); |
|
248 } |
|
249 } |
|
250 |
|
251 /* |
|
252 * Dessine un os, en ayant en paramètres deux noeuds. |
|
253 */ |
|
254 public void drawBone(Joint j1, Joint j2) |
|
255 { |
|
256 //On crée une nouvelle ligne verte d'épaisseur 8 entre les deux noeuds et on l'ajoute au Canvas. |
|
257 Line line = new Line(); |
|
258 line.Stroke = System.Windows.Media.Brushes.Green; |
|
259 line.X1 = j1.Position.X; |
|
260 line.X2 = j2.Position.X; |
|
261 line.Y1 = j1.Position.Y; |
|
262 line.Y2 = j2.Position.Y; |
|
263 line.StrokeThickness = 8; |
|
264 DebugCanvas.Children.Add(line); |
|
265 } |
|
266 |
|
267 /* |
|
268 * Dessine le squelette (ensemble des os), en ayant en paramètres tous les noeuds. |
|
269 */ |
|
270 public void showSkeleton(Joint hipCenter, Joint spine, Joint shoulderCenter, Joint head, Joint shoulderLeft, Joint elbowLeft, Joint wristLeft, Joint handLeft, Joint shoulderRight, Joint elbowRight, Joint wristRight, Joint handRight, Joint hipLeft, Joint kneeLeft, Joint ankleLeft, Joint footLeft, Joint hipRight, Joint kneeRight, Joint ankleRight, Joint footRight) |
|
271 { |
|
272 //On met les noeuds deux par deux en fonction de leur position dans le squelette. |
|
273 drawBone(head, shoulderCenter); |
|
274 drawBone(shoulderCenter, shoulderLeft); |
|
275 drawBone(shoulderLeft, elbowLeft); |
|
276 drawBone(elbowLeft, wristLeft); |
|
277 drawBone(wristLeft, handLeft); |
|
278 drawBone(shoulderCenter, shoulderRight); |
|
279 drawBone(shoulderRight, elbowRight); |
|
280 drawBone(elbowRight, wristRight); |
|
281 drawBone(wristRight, handRight); |
|
282 drawBone(shoulderCenter, spine); |
|
283 drawBone(spine, hipCenter); |
|
284 drawBone(hipCenter, hipLeft); |
|
285 drawBone(hipLeft, kneeLeft); |
|
286 drawBone(kneeLeft, ankleLeft); |
|
287 drawBone(ankleLeft, footLeft); |
|
288 drawBone(hipCenter, hipRight); |
|
289 drawBone(hipRight, kneeRight); |
|
290 drawBone(kneeRight, ankleRight); |
|
291 drawBone(ankleRight, footRight); |
|
292 } |
|
293 |
|
294 /* |
|
295 * Affiche la position de la main gauche dans le rendu visuel. |
|
296 */ |
|
297 public void showLeftHandCoord(String coord) |
|
298 { |
|
299 LeftHand.Content = coord; |
|
300 } |
|
301 |
|
302 /* |
|
303 * Affiche la position de la main gauche dans le rendu visuel. |
|
304 */ |
|
305 public void showRightHandCoord(String coord) |
|
306 { |
|
307 RightHand.Content = coord; |
|
308 } |
|
309 |
|
310 public void showSwipe() |
|
311 { |
|
312 ExceptionLbl.Background = System.Windows.Media.Brushes.Red; |
|
313 } |
|
314 } |
|
315 } |