고다경

Rule-Based 각도판단 코드

1 +using UnityEngine;
2 +using UnityEngine.UI;
3 +using System.Collections;
4 +using System.Collections.Generic;
5 +using Kinect = Windows.Kinect;
6 +using System.IO;
7 +using System;
8 +
9 +
10 +public class BodySourceView : MonoBehaviour
11 +{
12 + public Material BoneMaterial;
13 + public Material xbot;
14 + public GameObject BodySourceManager;
15 +
16 + private Dictionary<ulong, GameObject> _Bodies = new Dictionary<ulong, GameObject>();
17 + private BodySourceManager _BodyManager;
18 +
19 + public Text IfSpineIsStraight;
20 + public Text HipBalance;
21 + public Text AngleLeftKnee;
22 + public Text AngleRightKnee;
23 + public Text KneeToeLeft;
24 + public Text KneeToeRight;
25 + public Text LeftLegUp;
26 + public Text RightLegUp;
27 +
28 + string hipbal, leftkneewarning, rightkneewarning, leftsidehighkick, rightsidehighkick;
29 +
30 + private Dictionary<Kinect.JointType, Kinect.JointType> _BoneMap = new Dictionary<Kinect.JointType, Kinect.JointType>()
31 + {
32 + { Kinect.JointType.FootLeft, Kinect.JointType.AnkleLeft },
33 + { Kinect.JointType.AnkleLeft, Kinect.JointType.KneeLeft },
34 + { Kinect.JointType.KneeLeft, Kinect.JointType.HipLeft },
35 + { Kinect.JointType.HipLeft, Kinect.JointType.SpineBase },
36 +
37 + { Kinect.JointType.FootRight, Kinect.JointType.AnkleRight },
38 + { Kinect.JointType.AnkleRight, Kinect.JointType.KneeRight },
39 + { Kinect.JointType.KneeRight, Kinect.JointType.HipRight },
40 + { Kinect.JointType.HipRight, Kinect.JointType.SpineBase },
41 +
42 + { Kinect.JointType.HandTipLeft, Kinect.JointType.HandLeft },
43 + { Kinect.JointType.ThumbLeft, Kinect.JointType.HandLeft },
44 + { Kinect.JointType.HandLeft, Kinect.JointType.WristLeft },
45 + { Kinect.JointType.WristLeft, Kinect.JointType.ElbowLeft },
46 + { Kinect.JointType.ElbowLeft, Kinect.JointType.ShoulderLeft },
47 + { Kinect.JointType.ShoulderLeft, Kinect.JointType.SpineShoulder },
48 +
49 + { Kinect.JointType.HandTipRight, Kinect.JointType.HandRight },
50 + { Kinect.JointType.ThumbRight, Kinect.JointType.HandRight },
51 + { Kinect.JointType.HandRight, Kinect.JointType.WristRight },
52 + { Kinect.JointType.WristRight, Kinect.JointType.ElbowRight },
53 + { Kinect.JointType.ElbowRight, Kinect.JointType.ShoulderRight },
54 + { Kinect.JointType.ShoulderRight, Kinect.JointType.SpineShoulder },
55 +
56 + { Kinect.JointType.SpineBase, Kinect.JointType.SpineMid },
57 + { Kinect.JointType.SpineMid, Kinect.JointType.SpineShoulder },
58 + { Kinect.JointType.SpineShoulder, Kinect.JointType.Neck },
59 + { Kinect.JointType.Neck, Kinect.JointType.Head },
60 + };
61 +
62 +
63 + void Update()
64 + {
65 +
66 + IfSpineIsStraight.text = "허리를 곧게: Tracking";
67 + HipBalance.text = "양쪽 힙 균형: Calculating";
68 + AngleLeftKnee.text = "왼쪽 무릎 각도: Tracking";
69 + AngleRightKnee.text = "오른쪽 무릎 각도: Tracking";
70 + KneeToeLeft.text = "왼쪽 무릎과 발끝: Tracking";
71 + KneeToeRight.text = "오른쪽 무릎과 발끝: Tracking";
72 + LeftLegUp.text = "왼쪽 다리 들어올린 각도: Tracking";
73 + RightLegUp.text = "오른쪽 다리 들어올린 각도: Tracking";
74 +
75 +
76 + if (BodySourceManager == null)
77 + {
78 + return;
79 + }
80 +
81 + _BodyManager = BodySourceManager.GetComponent<BodySourceManager>();
82 + if (_BodyManager == null)
83 + {
84 + return;
85 + }
86 +
87 + Kinect.Body[] data = _BodyManager.GetData();
88 + if (data == null)
89 + {
90 + return;
91 + }
92 +
93 + List<ulong> trackedIds = new List<ulong>();
94 + foreach (var body in data)
95 + {
96 + if (body == null)
97 + {
98 + continue;
99 + }
100 +
101 + if (body.IsTracked)
102 + {
103 + trackedIds.Add(body.TrackingId);
104 + }
105 + }
106 +
107 + List<ulong> knownIds = new List<ulong>(_Bodies.Keys);
108 +
109 + // First delete untracked bodies
110 + foreach (ulong trackingId in knownIds)
111 + {
112 + if (!trackedIds.Contains(trackingId))
113 + {
114 + Destroy(_Bodies[trackingId]);
115 + _Bodies.Remove(trackingId);
116 + }
117 + }
118 +
119 + foreach (var body in data)
120 + {
121 + if (body == null)
122 + {
123 + continue;
124 + }
125 +
126 + if (body.IsTracked)
127 + {
128 + if (!_Bodies.ContainsKey(body.TrackingId))
129 + {
130 + _Bodies[body.TrackingId] = CreateBodyObject(body.TrackingId);
131 + }
132 +
133 + RefreshBodyObject(body, _Bodies[body.TrackingId]);
134 + }
135 + }
136 +
137 + }
138 +
139 + private GameObject CreateBodyObject(ulong id)
140 + {
141 + GameObject body = new GameObject("Body:" + id);
142 +
143 + for (Kinect.JointType jt = Kinect.JointType.SpineBase; jt <= Kinect.JointType.ThumbRight; jt++)
144 + {
145 + GameObject jointObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
146 +
147 + LineRenderer lr = jointObj.AddComponent<LineRenderer>();
148 + lr.SetVertexCount(2);
149 + lr.material = BoneMaterial;
150 + //////////////////
151 + //lr.material = xbot;
152 +
153 + /////////////////
154 + lr.SetWidth(0.05f, 0.05f);
155 +
156 +
157 + jointObj.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
158 + jointObj.name = jt.ToString();
159 + jointObj.transform.parent = body.transform;
160 + }
161 +
162 + return body;
163 + }
164 +
165 + int num = 0;
166 + string str = "";
167 +
168 + private void RefreshBodyObject(Kinect.Body body, GameObject bodyObject)
169 + {
170 +
171 + //StreamWriter sw = new StreamWriter(new FileStream("a.txt", FileMode.Create));
172 + // sw.WriteLine("Hello");
173 + //sw.Close();
174 + // Debug.Log("바디트래킹됨=================" + num++);
175 + //NewBehaviourScript.test();
176 + // str += "바디트래킹됨=================" + num++ + "\n";
177 +
178 +
179 +
180 + for (Kinect.JointType jt = Kinect.JointType.SpineBase; jt <= Kinect.JointType.ThumbRight; jt++)
181 + {
182 +
183 + Kinect.Joint sourceJoint = body.Joints[jt];
184 + Kinect.Joint? targetJoint = null;
185 +
186 + ///////////////////////////
187 + Angles MyAngles = new Angles();
188 + byte[] ReadAngles = MyAngles.GetVector(body);
189 + // ReadAngles[0].ToString();
190 + //Debug.Log("HipLeft " + ReadAngles[1].ToString());
191 + //Debug.Log("HipRight " + ReadAngles[2].ToString());
192 + //Debug.Log("KneeLeft " + ReadAngles[3].ToString());
193 + //Debug.Log("KneeRight " + ReadAngles[4].ToString());
194 +
195 +
196 + if (ReadAngles[1] - ReadAngles[2] <= 5)
197 + {
198 + hipbal = "양쪽 균형이 잡혀있습니다.";
199 + }
200 + else {
201 + hipbal = "양쪽 힘이 동일하지 않습니다. 균형을 잡으세요";
202 + }
203 +
204 + if (ReadAngles[5] > 90)
205 + {
206 + leftkneewarning = "왼쪽 무릎이 발끝을 넘어갔습니다.";
207 + }
208 + else {
209 + leftkneewarning = "";
210 + }
211 + if (ReadAngles[6] > 90)
212 + {
213 + rightkneewarning = "오른쪽 무릎이 발끝을 넘어갔습니다.";
214 + }
215 + else
216 + {
217 + rightkneewarning = "";
218 + }
219 +
220 + if (ReadAngles[7] < 45)
221 + {
222 + leftsidehighkick = "왼쪽 다리를 좀 더 높이 들어올리세요";
223 + }
224 + else {
225 + leftsidehighkick = "";
226 + }
227 +
228 + if (ReadAngles[8] < 45)
229 + {
230 + rightsidehighkick = "오른쪽 다리를 좀 더 높이 들어올리세요";
231 + }
232 + else
233 + {
234 + rightsidehighkick = "";
235 + }
236 +
237 +
238 + IfSpineIsStraight.text = "허리를 곧게: " + ReadAngles[0].ToString();
239 + HipBalance.text = "양쪽 힙 균형: " + hipbal;
240 + AngleLeftKnee.text = "왼쪽 무릎 각도: " + ReadAngles[3].ToString();
241 + AngleRightKnee.text = "오른쪽 무릎 각도: " + ReadAngles[4].ToString();
242 + KneeToeLeft.text = "올바르지 않은 자세: " + leftkneewarning;
243 + KneeToeRight.text = "올바르지 않은 자세: " + rightkneewarning;
244 + LeftLegUp.text = "왼쪽 다리 운동중: " + leftsidehighkick;
245 + RightLegUp.text = "오른쪽 다리 운동중: " + rightsidehighkick;
246 +
247 + ///////////////////////////
248 +
249 + Debug.Log(body.Joints[Kinect.JointType.SpineBase].Position.X);
250 + if (body.Joints[jt].JointType.ToString() == "SpineBase")
251 + {
252 + Debug.Log(sourceJoint.Position.X);
253 +
254 + //str += sourceJoint.Position.X;
255 + //str += "\n";
256 + Debug.Log(sourceJoint.Position.Y);
257 +
258 + //str += sourceJoint.Position.Y;
259 + //str += "\n";
260 + Debug.Log(sourceJoint.Position.Z);
261 + }
262 + //str += body.Joints[jt].JointType;
263 + //str += "\n";
264 +
265 +
266 + //str += sourceJoint.Position.Z;
267 + //str += "\n";
268 + //Debug.Log("<<<<<<<<<<<<<<<<<");
269 +
270 + // str += "<<<<<<<<<<<<<<<<<<<\n";
271 +
272 +
273 + if (_BoneMap.ContainsKey(jt))
274 + {
275 + targetJoint = body.Joints[_BoneMap[jt]];
276 + }
277 +
278 + Transform jointObj = bodyObject.transform.Find(jt.ToString());
279 + jointObj.localPosition = GetVector3FromJoint(sourceJoint);
280 +
281 + LineRenderer lr = jointObj.GetComponent<LineRenderer>();
282 + if (targetJoint.HasValue)
283 + {
284 + lr.SetPosition(0, jointObj.localPosition);
285 + lr.SetPosition(1, GetVector3FromJoint(targetJoint.Value));
286 + lr.SetColors(GetColorForState(sourceJoint.TrackingState), GetColorForState(targetJoint.Value.TrackingState));
287 + }
288 + else
289 + {
290 + lr.enabled = false;
291 + }
292 + }
293 + }
294 +
295 + private static Color GetColorForState(Kinect.TrackingState state)
296 + {
297 + switch (state)
298 + {
299 + case Kinect.TrackingState.Tracked:
300 + return Color.green;
301 +
302 + case Kinect.TrackingState.Inferred:
303 + return Color.red;
304 +
305 + default:
306 + return Color.black;
307 + }
308 + }
309 +
310 + private static Vector3 GetVector3FromJoint(Kinect.Joint joint)
311 + {
312 + return new Vector3(joint.Position.X * 10, joint.Position.Y * 10, joint.Position.Z * 10);
313 + }
314 +
315 +
316 + public class Angles
317 + {
318 + public double AngleBetweenTwoVectors(Vector3 Va, Vector3 Vb)
319 + {
320 + double dotProduct;
321 +
322 + Va.Normalize();
323 + Vb.Normalize();
324 + dotProduct = Vector3.Dot(Va, Vb);
325 +
326 + return (double)Math.Acos(dotProduct) * (180/ Math.PI);
327 +
328 + }
329 +
330 + public byte[] GetVector(Kinect.Body body)
331 + {
332 + Vector3 SpineShoulder = new Vector3(body.Joints[Kinect.JointType.SpineShoulder].Position.X, body.Joints[Kinect.JointType.SpineShoulder].Position.Y, body.Joints[Kinect.JointType.SpineShoulder].Position.Z);
333 + Vector3 RightShoulder = new Vector3(body.Joints[Kinect.JointType.ShoulderRight].Position.X, body.Joints[Kinect.JointType.ShoulderRight].Position.Y, body.Joints[Kinect.JointType.ShoulderRight].Position.Z);
334 + Vector3 LeftShoulder = new Vector3(body.Joints[Kinect.JointType.ShoulderLeft].Position.X, body.Joints[Kinect.JointType.ShoulderLeft].Position.Y, body.Joints[Kinect.JointType.ShoulderLeft].Position.Z);
335 + Vector3 RightElbow = new Vector3(body.Joints[Kinect.JointType.ElbowRight].Position.X, body.Joints[Kinect.JointType.ElbowRight].Position.Y, body.Joints[Kinect.JointType.ElbowRight].Position.Z);
336 + Vector3 LeftElbow = new Vector3(body.Joints[Kinect.JointType.ElbowLeft].Position.X, body.Joints[Kinect.JointType.ElbowLeft].Position.Y, body.Joints[Kinect.JointType.ElbowLeft].Position.Z);
337 + Vector3 RightWrist = new Vector3(body.Joints[Kinect.JointType.WristRight].Position.X, body.Joints[Kinect.JointType.WristRight].Position.Y, body.Joints[Kinect.JointType.WristRight].Position.Z);
338 + Vector3 LeftWrist = new Vector3(body.Joints[Kinect.JointType.WristLeft].Position.X, body.Joints[Kinect.JointType.WristLeft].Position.Y, body.Joints[Kinect.JointType.WristLeft].Position.Z);
339 + Vector3 UpVector = new Vector3((float)0.0, (float)1.0, (float)0.0);
340 + //////////////////////////////////////
341 + Vector3 SpineMid = new Vector3(body.Joints[Kinect.JointType.SpineMid].Position.X, body.Joints[Kinect.JointType.SpineMid].Position.Y, body.Joints[Kinect.JointType.SpineMid].Position.Z);
342 + Vector3 SpineBase = new Vector3(body.Joints[Kinect.JointType.SpineBase].Position.X, body.Joints[Kinect.JointType.SpineBase].Position.Y, body.Joints[Kinect.JointType.SpineBase].Position.Z);
343 + Vector3 HipLeft = new Vector3(body.Joints[Kinect.JointType.HipLeft].Position.X, body.Joints[Kinect.JointType.HipLeft].Position.Y, body.Joints[Kinect.JointType.HipLeft].Position.Z);
344 + Vector3 KneeLeft = new Vector3(body.Joints[Kinect.JointType.KneeLeft].Position.X, body.Joints[Kinect.JointType.KneeLeft].Position.Y, body.Joints[Kinect.JointType.KneeLeft].Position.Z);
345 + Vector3 AnkleLeft = new Vector3(body.Joints[Kinect.JointType.AnkleLeft].Position.X, body.Joints[Kinect.JointType.AnkleLeft].Position.Y, body.Joints[Kinect.JointType.AnkleLeft].Position.Z);
346 + Vector3 HipRight = new Vector3(body.Joints[Kinect.JointType.HipRight].Position.X, body.Joints[Kinect.JointType.HipRight].Position.Y, body.Joints[Kinect.JointType.HipRight].Position.Z);
347 + Vector3 KneeRight = new Vector3(body.Joints[Kinect.JointType.KneeRight].Position.X, body.Joints[Kinect.JointType.KneeRight].Position.Y, body.Joints[Kinect.JointType.KneeRight].Position.Z);
348 + Vector3 AnkleRight = new Vector3(body.Joints[Kinect.JointType.AnkleRight].Position.X, body.Joints[Kinect.JointType.AnkleRight].Position.Y, body.Joints[Kinect.JointType.AnkleRight].Position.Z);
349 + Vector3 FootRight = new Vector3(body.Joints[Kinect.JointType.FootRight].Position.X, body.Joints[Kinect.JointType.FootRight].Position.Y, body.Joints[Kinect.JointType.FootRight].Position.Z);
350 + Vector3 FootLeft = new Vector3(body.Joints[Kinect.JointType.FootLeft].Position.X, body.Joints[Kinect.JointType.FootLeft].Position.Y, body.Joints[Kinect.JointType.FootLeft].Position.Z);
351 +
352 + /*
353 + double AngleRightElbow = AngleBetweenTwoVectors(RightElbow - RightShoulder, RightElbow - RightWrist);
354 + double AngleRightShoulder = AngleBetweenTwoVectors(UpVector, RightShoulder - RightElbow);
355 + double AngleLeftElbow = AngleBetweenTwoVectors(LeftElbow - LeftShoulder, LeftElbow - LeftWrist);
356 + double AngleLeftShoulder = AngleBetweenTwoVectors(UpVector, LeftShoulder - LeftElbow);
357 + */
358 +
359 + double StraightSpine = AngleBetweenTwoVectors(SpineShoulder - SpineMid, SpineBase - SpineMid); //스쿼트, 런지 - Joint 3개로도 가능
360 +
361 + double AngleLeftHip = AngleBetweenTwoVectors(SpineBase - SpineShoulder, HipLeft - KneeLeft); //스쿼트, 런지
362 + double AngleRightHip = AngleBetweenTwoVectors(SpineBase - SpineShoulder, HipRight - KneeRight); //스쿼트, 런지
363 + double AngleLeftKnee = AngleBetweenTwoVectors(KneeLeft - HipLeft, KneeLeft - AnkleLeft); //스쿼트, 런지, 사이드하이킥 - Joint 3개로도 가능
364 + double AngleRightKnee = AngleBetweenTwoVectors(KneeRight - HipRight, KneeRight - AnkleRight); //스쿼트, 런지, 사이드하이킥 - Joint 3개로도 가능
365 +
366 + double KneeToeLeft = AngleBetweenTwoVectors(AnkleLeft - FootLeft, KneeLeft - FootLeft); //스쿼트 - Joint 3개로도 가능
367 + double KneeToeRight = AngleBetweenTwoVectors(AnkleRight - FootRight, KneeRight - FootRight); //스쿼트 - Joint 3개로도 가능
368 + double LeftLegUp = AngleBetweenTwoVectors(SpineMid - SpineShoulder, KneeLeft - HipLeft); //사이드 하이킥
369 + double RightLegUp = AngleBetweenTwoVectors(SpineMid - SpineShoulder, KneeRight - HipRight); //사이드 하이킥
370 +
371 +
372 + byte[] Angles = { Convert.ToByte(StraightSpine),
373 + Convert.ToByte(AngleLeftHip), Convert.ToByte(AngleRightHip),
374 + Convert.ToByte(AngleLeftKnee), Convert.ToByte(AngleRightKnee),
375 + Convert.ToByte(KneeToeLeft), Convert.ToByte(KneeToeRight),
376 + Convert.ToByte(LeftLegUp), Convert.ToByte(RightLegUp)};
377 +
378 + return Angles;
379 + }
380 + }
381 +
382 +
383 +}