middleware/src/Tracking/Gestures/GestureDetector.cs
author bastiena
Tue, 20 Mar 2012 18:00:55 +0100
changeset 7 8a21bec5d45f
parent 5 d40f84d77db4
child 8 e4e7db2435f8
permissions -rw-r--r--
Middleware : No proximity bugs anymore. The skeleton disappear if a tracked person is too close or not tracked anymore. Processing : There are no laggs anymore when an user stay too long moving his hands and drawing tons of ellipses. (TUIO Cursors are not taken by their vectors, only the last position of the cursors are caught to be drawn).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     1
/*
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     2
 * Projet : TraKERS
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     3
 * Module : MIDDLEWARE
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     4
 * Sous-Module : Tracking/Gestures
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     5
 * Classe : GestureDetector
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     6
 * 
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     7
 * Auteur : alexandre.bastien@iri.centrepompidou.fr
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     8
 * 
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
     9
 * Fonctionnalités : Reçoit les positions des noeuds envoyés par la classe de manipulation de la Kinect
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    10
 * et les stocke dans un historique.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    11
 * Contient également des variables propres à toute gesture : distance de référence, point de départ,
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    12
 * durée de la gesture, FPS et nombre de frames à traiter.
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    13
 */
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    14
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    15
using System;
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    16
using System.Collections.Generic;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    17
using System.Linq;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    18
using System.Text;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    19
using Microsoft.Kinect;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    20
using System.Drawing;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    21
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    22
namespace Trakers.Tracking.Gestures
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    23
{
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    24
    public class GestureDetector
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    25
    {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    26
        //Historique des positions du squelette.
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    27
        protected static List<List<Joint>> history = new List<List<Joint>>();
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    28
        //protected JointCollection previousSkeleton;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    29
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
    30
        //Voici les ID des noeuds d'un squelette : variables magiques en attente de factorisation.
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
    31
        /*protected int hipCenterID = 0, spineID = 1, shoulderCenterID = 2, headID = 3;
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    32
        protected int shoulderLeftID = 4, elbowLeftID = 5, wristLeftID = 6, handLeftID = 7;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    33
        protected int shoulderRightID = 8, elbowRightID = 9, wristRightID = 10, handRightID = 11;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    34
        protected int hipLeftID = 12, kneeLeftID = 13, ankleLeftID = 14, footLeftID = 15;
5
d40f84d77db4 Documentations (readme)
bastiena
parents: 3
diff changeset
    35
        protected int hipRightID = 16, kneeRightID = 17, ankleRightID = 18, footRightID = 19;*/
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    36
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    37
        //Elements nécessaires à la reconnaissance du geste :
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    38
        //Distance du parcours du geste (va dépendre de la distance de l'utilisateur).
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    39
        protected float refDistance;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    40
        //Position de départ pour le geste.
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    41
        protected SkeletonPoint startPoint;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    42
        //Estimation du temps que prend la gesture (en s).
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    43
        protected float gesturePeriod = 1;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    44
        //Estimation du nombre d'indexes par seconde (framerate).
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    45
        protected int indexesPerSecond = 30;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    46
        //Estimation du nombre de positions du squelette à vérifier dans l'historique.
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    47
        protected int indexesToCheck;// = gesturePeriod * indexesPerSecond;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    48
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    49
        public GestureDetector()
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    50
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    51
            
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    52
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    53
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    54
        //Setters.
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    55
        public void setRefDistance(float _refDistance)
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    56
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    57
            refDistance = _refDistance;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    58
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    59
        public void setStartPoint(SkeletonPoint _startPoint)
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    60
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    61
            startPoint = _startPoint;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    62
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    63
        public void setGesturePeriod(float _gesturePeriod)
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    64
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    65
            gesturePeriod = _gesturePeriod;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    66
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    67
        public void setIndexesPerSecond(int _indexesPerSecond)
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    68
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    69
            indexesPerSecond = _indexesPerSecond;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    70
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    71
        public void setIndexesToCheck(int _indexesToCheck)
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    72
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    73
            indexesToCheck = _indexesToCheck;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    74
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    75
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    76
        //Getters.
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    77
        public float getRefDistance()
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    78
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    79
            return refDistance;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    80
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    81
        public SkeletonPoint getStartPoint()
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    82
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    83
            return startPoint;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    84
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    85
        public float getGesturePeriod()
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    86
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    87
            return gesturePeriod;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    88
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    89
        public int getIndexesPerSecond()
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    90
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    91
            return indexesPerSecond;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    92
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    93
        public int getIndexesToCheck()
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    94
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    95
            return indexesToCheck;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    96
        } 
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    97
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    98
        //Stocke les gestes du skelette pour ~3 seconds (si on prend en compte que le framerate de la Kinect
6fefd4afe506 First Import
bastiena
parents:
diff changeset
    99
        //est de ~30 fps.
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   100
        public static void UpdateSkeletonHistory(List<Joint> latestSkeleton)
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   101
        {
3
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   102
            history.Add(latestSkeleton);
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   103
                
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   104
            if (history.Count > 90)
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   105
            {
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   106
                history.RemoveAt(0);
92f19af39024 Middleware :
bastiena
parents: 0
diff changeset
   107
            }
0
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   108
        }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   109
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   110
        /*public bool CheckForHandWave()
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   111
        {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   112
            //Crée un historique de squelette local, puisque l'historique est mis à jour toutes les ~1/30 s.
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   113
            List<Skeleton> history = new List<Skeleton>(history);
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   114
            //Si il n'y a pas assez de positions dans l'historique local pour vérifier le geste.
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   115
            if (history.Count < indexesToCheck)
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   116
                return false;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   117
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   118
            float refDistance = Math.Abs(history[0].Joints.ElementAt(spineID).Position.Y - history[0].Joints.ElementAt(hipCenterID).Position.Y);
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   119
            float startPos = history[history.Count - indexesToCheck].Joints.ElementAt(handRightID).Position.X;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   120
            bool movedRight = false;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   121
            for (int i = history.Count - indexesToCheck + 1; i < history.Count; i++)
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   122
            {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   123
                // Throughout the gesture period, right hand should be above theelbow, below the head and hand should be higher than the wrist
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   124
                if (!(history[i].Joints[JointID.HandRight].Position.Y > history[i].Joints[JointID.ElbowRight].Position.Y + refDistance &&
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   125
                history[i].Joints[JointID.HandRight].Position.Y < history[i].Joints[JointID.Head].Position.Y &&
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   126
                history[i].Joints[JointID.HandRight].Position.Y > history[i].Joints[JointID.WristRight].Position.Y + refDistance / 4))
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   127
                {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   128
                    return false;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   129
                }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   130
                // If the previous condition was met, check if the hand has moved to the right
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   131
                if (history[i].Joints[JointID.HandRight].Position.X >= startPos + refDistance / 2 && !movedRight)
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   132
                {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   133
                    movedRight = true;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   134
                }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   135
                // If the hand did move to the right, check if it returned near the original position
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   136
                if (movedRight && history[i].Joints[JointID.HandRight].Position.X <= startPos + refDistance / 5)
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   137
                {
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   138
                    skeletonHistory.Clear();
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   139
                    return true;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   140
                }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   141
            }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   142
                return false;
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   143
        }*/
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   144
    }
6fefd4afe506 First Import
bastiena
parents:
diff changeset
   145
}