A soron következő feladat a gesztusok felismerése. Mi is a gesztus? A gesztus egy, a felhasználó által végrehajtott, előre definiált mozdulatsor, mint az integetés, karunk lendítése, lábemelés, törzshajlítás.
Először a lineáris gesztusokat használom fel. Vegyünk egy példát, legyen ez a jobb kezünkkel való intés fel, le, jobbra és balra. Vizsgáljuk meg jobb kezünk koordinátáit. Ha szemben állunk a szenzorral, akkor a koordináta rendszer pozitív x tengelye a jobb kezünk felé, a pozitív y tengelye pedig a fejünk felé esik. A z koordináta pedig a szenzortól mért távolság.
A balra intés ekkor függ a kezünk x és y koordinátájától: x irányban haladunk, y pedig a kitérés lesz. Tehát meg kell vizsgálnunk, hogy jó felé haladunk-e (negatív x irányba) és hogy nem térünk e ki a megadott sávból (y koordináta +- a tűréshatár).
A feladathoz szükség volt egy újabb átalakításra az eszköztárban. Az eszköztár szerkezete:
+Kinect.Stream.Utilities: Feldolgozó osztályokat tartalmazó projekt |-ColorStream |-->ColorStreamProcessor.cs: Color stream feldolgozó osztály |-DepthStream |-->DepthStreamProcessor.cs: Depth stream feldolgozó osztály |-->Distance.cs: Távolság |-->DistanceProcessor.cs: Távolság feldolgozó osztály |-SkeletonStream |-->SkeletonDrawer.cs: Csontváz kirajzoló osztály |-->SkeletonStreamProcessor.cs: Skeleton Stream feldolgozó osztály +Kinect.Toolbox.Utilities: User control-okat tartalmazó projekt |->DistanceViewer.cs: Távolságokat megjelenítő User Control |->ImageViewer.cs: Képeket megjelenítő User Control +Kinect.Gesture.Utilities: Gesztus feldolgozó osztályokat tartalmazó projekt |-Container |-->Position.cs: Pozíció tároló osztály |-->PositionStore.cs: Pozíció feldolgozó osztály |-Recognizer |-->GestureEventArgs.cs: Gesztus esemény |-->LinearGestureRecognizer.cs: LinearRecognizerből származó feldolgozó |-->LinearRecognizer.cs: Lineáris gesztusokat feldolgozó ősosztály
A SkeletalStreamProcessorból kivettem a Player osztályt és helyette csak két Skeletont tárol – így könnyebb használni a gesztusokhoz – valamint kézzel kell meghívni a SkeletonDrawer osztály draw metódusát a MainWindow-ban.
Pár szóban az új osztályokról:
- Postition: Ebben az osztályban három koordinátát és a felvétel idejét tárolom.
- PositionStore: Egyetlen adattagja a MaxPositions, egy int, amelyben csak a maximális pozíciószámot tárolom. Metódusa a CapturePositions, amely rögzíti a megfelelő típusú Joint-ot Position-ként egy Dictionary-ba, ha megtelt, akkor törli az első pozíciót (amely a legrégebbi).
- GestureEventArgs: Az EventArgs leszármazottja. Két string adattagja (egyenlőre) a message és a PlayerID.
- LinearRecognizer: négy adattagja van, a minimális hossz (két pozíció között), amplitúdó (mennyire térhet ki a mozdulat), a minimális és a maximális idő (meddig kell tartania a mozdulatnak). Egy metódusa van, a Recognize, egy kereső függvény, amelynek generikus kifejezések a paraméterei, valamint egy Position lista. A három generikus kifejezésnek (Func<>) majd a leszármazott osztályban adunk értéket. A metódus végig megy a listán és ellenőrzi, hogy a paraméterben kapott Func<>-oknak megfelelőek-e. Ha igen, akkor ellenőrzi, hogy a kezdő és a záró pozíció elég hosszú ideig tartott. Ha igen, akkor igennel tér vissza – azaz volt gesztus a pozíciók között.
- LinearGestureRecognizer:a LinearRecignizer leszármazottja. Egy új adattagja van: egy event. Van továbbá egy delegate is:
public delegate void Gestures(ref List<Position>, ref string id);
és egy Search metódus, amely egy Gestures-t, egy List-et és egy stringet kap paraméterül:
public void Search(Gestures g, List<Position> pList, string id)
A metódus törzse tulajdonképpen:
g(ref pList, ref id);
Ennek a segítségével a MainWindow-ban adhatjuk meg a Recognize Func-ainak deklarációját. (Könnyebben újrahasznosítható.)