middleware/src/Tracking/Gestures/JumpDetector.cs
changeset 15 4b78f179e7ce
parent 14 10d5199d9874
child 16 a9ebacd6c089
equal deleted inserted replaced
14:10d5199d9874 15:4b78f179e7ce
     1 /*
       
     2 * This file is part of the TraKERS\Middleware package.
       
     3 *
       
     4 * (c) IRI <http://www.iri.centrepompidou.fr/>
       
     5 *
       
     6 * For the full copyright and license information, please view the LICENSE_MIDDLEWARE
       
     7 * file that was distributed with this source code.
       
     8 */
       
     9 
       
    10 /*
       
    11  * Projet : TraKERS
       
    12  * Module : MIDDLEWARE
       
    13  * Sous-Module : Tracking/Gestures
       
    14  * Classe : JumpDetector
       
    15  * 
       
    16  * Auteur : alexandre.bastien@iri.centrepompidou.fr
       
    17  * 
       
    18  * Fonctionnalités : Permet de détecter si l'utilisateur a sauté, en se basant sur
       
    19  * des règles appliquées à la positions des noeuds dans le temps.
       
    20  * 
       
    21  * P.S : Cette partie est encore en développement.
       
    22  */
       
    23 
       
    24 using System;
       
    25 using System.Collections.Generic;
       
    26 using System.Linq;
       
    27 using System.Text;
       
    28 using Microsoft.Kinect;
       
    29 
       
    30 namespace Trakers.Tracking.Gestures
       
    31 {
       
    32     public class JumpDetector : GestureDetector
       
    33     {
       
    34         Debug.DebugWindow debug;
       
    35         static int n = 0;
       
    36 
       
    37         public JumpDetector(Debug.DebugWindow _d) : base()
       
    38         {
       
    39             debug = _d;
       
    40             gesturePeriod = (float)1;
       
    41             indexesPerSecond = 30;
       
    42             indexesToCheck = (int)(gesturePeriod * indexesPerSecond);
       
    43         }
       
    44 
       
    45         /*
       
    46          * Lit les noeuds de l'historique du squelette afin de détecter un Jump.
       
    47          * Règles :
       
    48          * .
       
    49          */
       
    50         public bool CheckForJump()
       
    51         {
       
    52             //Crée un historique de squelette local, puisque l'historique est mis à jour toutes les ~1/30 s.
       
    53             List<List<Joint>> localHistory = new List<List<Joint>>(history);
       
    54             
       
    55             //Si il n'y a pas assez de positions dans l'historique local pour vérifier le geste.
       
    56             if (localHistory.Count < indexesToCheck)
       
    57                 return false;
       
    58 
       
    59             /* (HeadBelowBaseLine || LeftKneeBelowBaseLine || RightKneeBelowBaseLine ||
       
    60              * LeftAnkleBelowBaseLine || RightAnkleBelowBaseLine || BodyFaceUpwards
       
    61              * 
       
    62              * NOT
       
    63              * 
       
    64              * AND
       
    65              * 
       
    66              * HeadAboveBaseLine && LeftKneeAboveBaseLine && RightKneeAboveBaseLine &&
       
    67              * LegsStraightPreviouslyBent)
       
    68              * 
       
    69              * OR
       
    70              * 
       
    71              * HeadFarAboveBaseLine
       
    72              */
       
    73 
       
    74             //La distance de référence est ici la distance entre le milieu du dos et le milieu des épaules.
       
    75             refDistance = Math.Abs(localHistory[0][(int)JointType.Spine].Position.Y - localHistory[0][(int)JointType.ShoulderCenter].Position.Y);
       
    76             //On commence la position pour les indexesToCheck dernières postures (celle à l'index 0 étant la dernière).
       
    77 
       
    78             int beginIdx = localHistory.Count - indexesToCheck + 1;
       
    79             int middleIdx = localHistory.Count - indexesToCheck / 2;
       
    80 
       
    81             //bool middleOK = true
       
    82             bool topOfJump = false;
       
    83 
       
    84             
       
    85 
       
    86             //De la position p1 à pn, on suit l'algorithme.
       
    87             for (int i = beginIdx ; i < localHistory.Count ; i++)
       
    88             {
       
    89 
       
    90                 if (localHistory[i][(int)JointType.HandRight].Position.Y < localHistory[beginIdx][(int)JointType.HandRight].Position.Y + refDistance &&
       
    91                    localHistory[i - 1][(int)JointType.HandRight].Position.Y < localHistory[i][(int)JointType.HandRight].Position.Y)
       
    92                 {
       
    93                     topOfJump = true;
       
    94                     //Console.Out.WriteLine("TOP");
       
    95                 }
       
    96 
       
    97                 if (localHistory[i - 1][(int)JointType.HandRight].Position.Y > localHistory[i][(int)JointType.HandRight].Position.Y && !topOfJump)
       
    98                     return false;
       
    99 
       
   100                 //Si la position Y de la main est plus haute que la tête
       
   101                 //OU si la position Y de la main est plus basse que la hanche
       
   102                 //OU si la nouvelle position Z de la main est moins profonde que la précédente
       
   103                 //OU si la nouvelle position X de la main est plus éloignée de la distance N par rapport à la première position X
       
   104                 //OU si la nouvelle position Y de la main est plus éloignée de la distance N par rapport à la première position Y
       
   105                 //Alors la main en question ne fait pas de push.
       
   106                 if (localHistory[i - 1][(int)JointType.HandRight].Position.Y > localHistory[i][(int)JointType.HandRight].Position.Y &&
       
   107                     topOfJump || localHistory[i - 1][(int)JointType.HandRight].Position.Y < localHistory[i][(int)JointType.HandRight].Position.Y &&
       
   108                     !topOfJump)
       
   109                     return false;
       
   110             }
       
   111 
       
   112             //Console.Out.WriteLine("OK");
       
   113 
       
   114             //Si la distance en Z du geste a été plus courte que la distance N
       
   115             //Alors on retourne faux.
       
   116             //float dist = (localHistory[localHistory.Count - 1][handRightID].Position.X - localHistory[localHistory.Count - indexesToCheck][handRightID].Position.X);
       
   117 
       
   118             //Console.WriteLine(Math.Abs(localHistory[0][handLeftID].Position.Z - localHistory[localHistory.Count - indexesToCheck][handLeftID].Position.Z) * 100 + " " + refDistance);
       
   119 
       
   120             //Si la dernière position de la main droite/gauche est sur le côté gauche/droit du corps
       
   121             //OU si la première position calculée de la main droite/gauche est sur le côté gauche/droit du corps
       
   122             //Alors on retourne faux.
       
   123             
       
   124             //On supprime l'historique local.
       
   125             
       
   126             debug.ExceptionLbl.Background = System.Windows.Media.Brushes.Yellow;
       
   127             
       
   128             return false;
       
   129         }
       
   130     }
       
   131 }