diff -r 10d5199d9874 -r 4b78f179e7ce middleware/src/Tracking/Search/Segmenter.cs --- a/middleware/src/Tracking/Search/Segmenter.cs Fri Mar 30 11:14:14 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,284 +0,0 @@ -/* -* This file is part of the TraKERS\Middleware package. -* -* (c) IRI -* -* For the full copyright and license information, please view the LICENSE_MIDDLEWARE -* file that was distributed with this source code. -*/ - -/* - * Projet : TraKERS - * Module : MIDDLEWARE - * Sous-Module : Search - * Classe : Segmenter - * - * Auteur : alexandre.bastien@iri.centrepompidou.fr - * - * Fonctionnalités : Permet d'extraire à la volée les segments du tracé en cours. - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Media.Media3D; - -namespace Trakers.Tracking.Search -{ - public class Segmenter - { - //Accès à la classe de détection principale pour les paramètres. - private KinectMain kinectMain; - //Stocke les positions d'une main au cours du temps. - private List handPointerHistory; - //Point précédent. - private Point3D prevPt; - //Ratio : on prend 1/ratio points. - private int ratio; - //Indique le numéro du point actuellement enregistré (pour le ratio). - private int currentPointNumber; - //Extremums enregistrés parmi les 3 axes pour détecter les changements de sens. - private double Xmax, Ymax, Zmax; - private double Xmin, Ymin, Zmin; - //On établit une distance en nombre de points entre le point actuel l'extremum - //local détecté dans les 3 axes (pour copier le segment : points de 0 à id de l'extremum). - private int distToXmax, distToYmax, distToZmax; - private int distToXmin, distToYmin, distToZmin; - //Points critiques. - private Point3D minPt, maxPt; - //Tendance actuelle du tracé. - private bool XtowardRight, YtowardUp, ZtowardFront; - //Limites de différences à partir desquelles . - private int directionChangeTresholdXY; - private float directionChangeTresholdZ; - - /* - * Initialisation du segmenter. - * Coupe une courbe en deux dès qu'il repère un changement important de trajectoire. - */ - public Segmenter(int _ratio, KinectMain _kinectMain) - { - kinectMain = _kinectMain; - directionChangeTresholdXY = kinectMain.getDirectionChangeTresholdXY(); - directionChangeTresholdZ = kinectMain.getDirectionChangeTresholdZ(); - handPointerHistory = new List(); - ratio = _ratio; - currentPointNumber = 1; - prevPt = new Point3D(0, 0, 0); - - Xmax = Ymax = Zmax = Xmin = Ymin = Zmin = -1; - distToXmax = distToYmax = distToZmax = distToXmin = distToYmin = distToZmin = -1; - } - - /* - * Getters et setters. - */ - public void SetRatio(int _ratio) - { - ratio = _ratio; - } - public void SetDirectionChangeTresholdXY(int _directionChangeTresholdXY) - { - directionChangeTresholdXY = _directionChangeTresholdXY; - } - public void SetDirectionChangeTresholdZ(float _directionChangeTresholdZ) - { - directionChangeTresholdZ = _directionChangeTresholdZ; - } - - public int GetRatio() - { - return ratio; - } - public int SetDirectionChangeTresholdXY() - { - return directionChangeTresholdXY; - } - public float SetDirectionChangeTresholdZ() - { - return directionChangeTresholdZ; - } - - /* - * On charge tous les paramètres d'un coup. - */ - public void setParams(int _ratio, int _directionChangeTresholdXY, float _directionChangeTresholdZ) - { - ratio = _ratio; - directionChangeTresholdXY = _directionChangeTresholdXY; - directionChangeTresholdZ = _directionChangeTresholdZ; - } - - /* - * Enregistre le point passé en paramètre d'après le ratio. - */ - public void RecordPoint(Point3D pt) - { - //Indique l'ID du point à couper. - int whereToCut; - //Si le ratio est excédé, on peut enregistrer. - if (currentPointNumber > ratio) - currentPointNumber = 1; - - //Si le point précédent est à une position différente du point actuel. - if(prevPt.X != pt.X || prevPt.Y != pt.Y || prevPt.Z != pt.Z) - { - //Si le numéro est 1 (début ou ratio atteint), on enregistre. - if(currentPointNumber == 1) - handPointerHistory.Add(pt); - - //Si le point précédent a été initialisé avec un vrai point. - if (prevPt.X > 0 && prevPt.Y > 0 && prevPt.Z > 0) - { - //Appel aux detecteurs d'extremums. - if ((whereToCut = DetectDirectionChangeAtXAxis(pt)) > 0) - Segment(whereToCut); - else if((whereToCut = DetectDirectionChangeAtYAxis(pt)) > 0) - Segment(whereToCut); - else if ((whereToCut = DetectDirectionChangeAtZAxis(pt)) > 0) - Segment(whereToCut); - } - //On met à jour le point précédent. - prevPt = pt; - //On passe au numéro suivant (jusqu'à atteindre le ration plus tard). - currentPointNumber++; - } - } - - /* - * Détecte un changement de sens (extremum) dans l'axe X. - */ - public int DetectDirectionChangeAtXAxis(Point3D pt) - { - //ID où couper en cas d'extremum. - int whereToCut = -1; - - //Mise à jour des extremums. - if (Xmax == -1 || Xmax < pt.X) - { - //Si le point est plus grand en X que Xmax, alors il est remplacé et on réinitialise la - //distance au dernier maximum en X. - Xmax = pt.X; - maxPt = pt; - distToXmax = 0; - } - else - distToXmax++; - if (Xmin == -1 || Xmin > pt.X) - { - //Si le point est plus petit en X que Xmin, alors il est remplacé et on réinitialise la - //distance au dernier minimum en X. - Xmin = pt.X; - minPt = pt; - distToXmin = 0; - } - else - distToXmin++; - - //Si X max est plus grand que la position actuelle additionnée du seuil - //et que l'extremum n'est pas le premier point sauvegardé. - if (Xmax > pt.X + directionChangeTresholdXY && maxPt != handPointerHistory.First()) - whereToCut = currentPointNumber - distToXmax; - //Si X min est plus petit que la position actuelle à laquelle on a retiré le seuil - //et que l'extremum n'est pas le premier point sauvegardé. - if (Xmin < pt.X - directionChangeTresholdXY && minPt != handPointerHistory.First()) - whereToCut = currentPointNumber - distToXmin; - - return whereToCut; - } - - /* - * Détecte un changement de sens (extremum) dans l'axe Y. - */ - public int DetectDirectionChangeAtYAxis(Point3D pt) - { - //ID où couper en cas d'extremum. - int whereToCut = -1; - - //Mise à jour des extremums. - if (Ymax == -1 || Ymax < pt.Y) - { - //Si le point est plus grand en Y que Ymax, alors il est remplacé et on réinitialise la - //distance au dernier maximum en Y. - Ymax = pt.Y; - maxPt = pt; - distToYmax = 0; - } - else - distToYmax++; - if (Ymin == -1 || Ymin > pt.Y) - { - //Si le point est plus petit en Y que Ymin, alors il est remplacé et on réinitialise la - //distance au dernier minimum en Y. - Ymin = pt.Y; - minPt = pt; - distToYmin = 0; - } - else - distToYmin++; - - //Si Y max est plus grand que la position actuelle additionnée du seuil - //et que l'extremum n'est pas le premier point sauvegardé. - if (Ymax > pt.Y + directionChangeTresholdXY && maxPt != handPointerHistory.First()) - whereToCut = currentPointNumber - distToYmax; - //Si Y min est plus petit que la position actuelle à laquelle on a retiré le seuil - //et que l'extremum n'est pas le premier point sauvegardé. - if (Ymin < pt.Y - directionChangeTresholdXY && minPt != handPointerHistory.First()) - whereToCut = currentPointNumber - distToYmin; - - return whereToCut; - } - - /* - * Détecte un changement de sens (extremum) dans l'axe Z. - */ - public int DetectDirectionChangeAtZAxis(Point3D pt) - { - //ID où couper en cas d'extremum. - int whereToCut = -1; - - //Mise à jour des extremums. - if (Zmax == -1 || Zmax < pt.Z) - { - //Si le point est plus grand en Z que Ymax, alors il est remplacé et on réinitialise la - //distance au dernier maximum en Z. - Zmax = pt.Z; - maxPt = pt; - distToZmax = 0; - } - else - distToZmax++; - if (Zmin == -1 || Zmin > pt.Z) - { - //Si le point est plus petit en Z que Zmin, alors il est remplacé et on réinitialise la - //distance au dernier minimum en Z. - Zmin = pt.Z; - minPt = pt; - distToZmin = 0; - } - else - distToZmin++; - - //Si Z max est plus grand que la position actuelle additionnée du seuil - //et que l'extremum n'est pas le premier point sauvegardé. - if (Zmax > pt.Z + directionChangeTresholdXY && maxPt != handPointerHistory.First()) - whereToCut = currentPointNumber - distToZmax; - //Si Z min est plus petit que la position actuelle à laquelle on a retiré le seuil - //et que l'extremum n'est pas le premier point sauvegardé. - if (Zmin < pt.Z - directionChangeTresholdXY && minPt != handPointerHistory.First()) - whereToCut = currentPointNumber - distToZmin; - - return whereToCut; - } - - /* - * Découpe le tracé en cours en segment allant du premier point au premier extremum trouvé. - */ - public void Segment(int whereToCut) - { - handPointerHistory.RemoveRange(0, whereToCut); - currentPointNumber -= whereToCut; - } - } -}