Middleware :
Began to create a curve segmenter based on cutting on local extremums.
Remove joint arguments on hand quit events to notify Processing when skeleton is not detected anymore.
--- a/middleware/src/App.config Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/App.config Thu Mar 29 14:39:21 2012 +0200
@@ -10,5 +10,8 @@
<add key="connexionPort" value="80"/>
<add key="timerElapsing" value="1000"/>
<add key="imagesToShow" value="25"/>
+ <add key="takenPoints" value="10"/>
+ <add key="directionChangeTresholdXY" value="10"/>
+ <add key="directionChangeTresholdZ" value="0,01"/>
</appSettings>
</configuration>
\ No newline at end of file
--- a/middleware/src/Debug/DebugParameters.xaml Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Debug/DebugParameters.xaml Thu Mar 29 14:39:21 2012 +0200
@@ -99,6 +99,30 @@
</Grid>
</StackPanel>
</TabItem>
+ <TabItem Header="Recherche">
+ <StackPanel>
+ <Label Content="Courbes de recherche :" Height="30" HorizontalAlignment="Left" VerticalAlignment="Top" Width="300" />
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="30" />
+ <RowDefinition Height="30" />
+ <RowDefinition Height="30" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="50*" />
+ <ColumnDefinition Width="50*" />
+ </Grid.ColumnDefinitions>
+
+ <!-- Paramètres de la recherche de courbes. -->
+ <Label Grid.Row="0" Grid.Column="0" Content="On prend 1/N pts :" HorizontalAlignment="Left" VerticalAlignment="Top" />
+ <TextBox Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Name="takenPointsTB" VerticalAlignment="Top" Width="120" />
+ <Label Grid.Row="1" Grid.Column="0" Content="Seuil cut XY :" HorizontalAlignment="Left" VerticalAlignment="Top" />
+ <TextBox Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Name="directionChangeTresholdXYTB" VerticalAlignment="Top" Width="120" />
+ <Label Grid.Row="2" Grid.Column="0" Content="Seuil cut Z :" HorizontalAlignment="Left" VerticalAlignment="Top" />
+ <TextBox Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" Name="directionChangeTresholdZTB" VerticalAlignment="Top" Width="120" />
+ </Grid>
+ </StackPanel>
+ </TabItem>
</TabControl>
<Button Content="Modifier" Click="Button_Click" />
--- a/middleware/src/Debug/DebugParameters.xaml.cs Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Debug/DebugParameters.xaml.cs Thu Mar 29 14:39:21 2012 +0200
@@ -71,6 +71,9 @@
connexionPortTB.Text = kinectMain.getConnexionPort().ToString();
timerElapsingTB.Text = kinectMain.getTimerElapsing().ToString();
imagesToShowTB.Text = kinectMain.getImagesToShow().ToString();
+ takenPointsTB.Text = kinectMain.getTakenPoints().ToString();
+ directionChangeTresholdXYTB.Text = kinectMain.getTakenPoints().ToString();
+ directionChangeTresholdZTB.Text = kinectMain.getTakenPoints().ToString();
}
/*
@@ -90,10 +93,14 @@
int connexionPort = int.Parse(connexionPortTB.Text);
int timerElapsing = int.Parse(timerElapsingTB.Text);
int imagesToShow = int.Parse(imagesToShowTB.Text);
+ int takenPoints = int.Parse(takenPointsTB.Text);
+ int directionChangeTresholdXY = int.Parse(directionChangeTresholdXYTB.Text);
+ float directionChangeTresholdZ = float.Parse(directionChangeTresholdZTB.Text);
if (maxDistHands <= 0f || minDistHands <= 0f || maxDistHands > maxDist || minDistHands > maxDist ||
minDistHands >= maxDistHands || zeroPoint < maxDistHands || minDistHands < minDist ||
- zeroPoint >= maxDist || connexionPort < 0 || timerElapsing < 0 || imagesToShow < 1)
+ zeroPoint >= maxDist || connexionPort < 0 || timerElapsing < 0 || imagesToShow < 1 ||
+ takenPoints <= 0 || directionChangeTresholdXY < 0 || directionChangeTresholdZ < 0)
{
ExceptionInParametersLbl.Content = rm.GetString("loadParametersIncorrect");
}
@@ -108,6 +115,9 @@
kinectMain.setConnexionPort(connexionPort);
kinectMain.setTimerElapsing(timerElapsing);
kinectMain.setImagesToShow(imagesToShow);
+ kinectMain.setTakenPoints(takenPoints);
+ kinectMain.setDirectionChangeTresholdXY(directionChangeTresholdXY);
+ kinectMain.setDirectionChangeTresholdZ(directionChangeTresholdZ);
kinectMain.updateParameters();
ExceptionInParametersLbl.Content = null;
--- a/middleware/src/Debug/DebugWindow.xaml.cs Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Debug/DebugWindow.xaml.cs Thu Mar 29 14:39:21 2012 +0200
@@ -509,8 +509,6 @@
R8.Fill = System.Windows.Media.Brushes.DarkGray;
R9.Fill = System.Windows.Media.Brushes.DarkGray;
R10.Fill = System.Windows.Media.Brushes.DarkGray;
- LeftHand.Background = System.Windows.Media.Brushes.DarkGray;
- RightHand.Background = System.Windows.Media.Brushes.DarkGray;
}
/*
--- a/middleware/src/Tracking/Events/LeftHandQuitEventArgs.cs Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Tracking/Events/LeftHandQuitEventArgs.cs Thu Mar 29 14:39:21 2012 +0200
@@ -30,18 +30,14 @@
{
public class LeftHandQuitEventArgs : EventArgs
{
- public readonly Joint handJoint;
- public readonly float position;
public readonly Debug.DebugWindow debug;
public readonly Server server;
/*
- * Constructeur : Il prend le noeud de la main, sa position, l'affichage de debug et le serveur TUIO.
+ * Constructeur : Il prend l'affichage de debug et le serveur TUIO.
*/
- public LeftHandQuitEventArgs(Joint joint, float pos, Debug.DebugWindow _debug, Server _server)
+ public LeftHandQuitEventArgs(Debug.DebugWindow _debug, Server _server)
{
- handJoint = joint;
- position = pos;
debug = _debug;
server = _server;
}
--- a/middleware/src/Tracking/Events/LeftHandQuitListener.cs Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Tracking/Events/LeftHandQuitListener.cs Thu Mar 29 14:39:21 2012 +0200
@@ -36,7 +36,6 @@
*/
public void ShowOnScreen(object o, LeftHandQuitEventArgs e)
{
- Joint handJoint = e.handJoint;
//On l'indique dans le debug.
e.debug.showLeftHandRect(false);
e.debug.showLeftHandCoord("");
--- a/middleware/src/Tracking/Events/RightHandQuitEventArgs.cs Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Tracking/Events/RightHandQuitEventArgs.cs Thu Mar 29 14:39:21 2012 +0200
@@ -30,18 +30,14 @@
{
public class RightHandQuitEventArgs : EventArgs
{
- public readonly Joint handJoint;
- public readonly float position;
public readonly Debug.DebugWindow debug;
public readonly Server server;
/*
- * Constructeur : Il prend le noeud de la main, sa position, l'affichage de debug et le serveur TUIO.
+ * Constructeur : Il prend l'affichage de debug et le serveur TUIO.
*/
- public RightHandQuitEventArgs(Joint joint, float pos, Debug.DebugWindow _debug, Server _server)
+ public RightHandQuitEventArgs(Debug.DebugWindow _debug, Server _server)
{
- handJoint = joint;
- position = pos;
debug = _debug;
server = _server;
}
--- a/middleware/src/Tracking/Events/RightHandQuitListener.cs Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Tracking/Events/RightHandQuitListener.cs Thu Mar 29 14:39:21 2012 +0200
@@ -36,7 +36,6 @@
*/
public void ShowOnScreen(object o, RightHandQuitEventArgs e)
{
- Joint handJoint = e.handJoint;
//On l'indique dans le debug.
e.debug.showRightHandRect(false);
e.debug.showRightHandCoord("");
--- a/middleware/src/Tracking/KinectMain.cs Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Tracking/KinectMain.cs Thu Mar 29 14:39:21 2012 +0200
@@ -20,6 +20,7 @@
* noeuds de son squelette. Lance des événements lorsque la main gauche/droite entre dans/quitte le champ.
* Envoie des données au sous-module de debug de manière a afficher un retour visuel sur la position de l'utilisateur,
* son squelette, la détection de ses mains.
+ * Découpe l'interaction avec le middleware en différents modes.
*/
using System;
@@ -67,8 +68,6 @@
public delegate void JumpHandler(object o, JumpEventArgs e);
//Il s'agit de la fonction permettant d'appeler les fonctions des événements de proximité.
public delegate void UserPositionHandler(object o, UserPositionEventArgs e);
- //Il s'agit de la fonctoin permettant de notifier le serveur en cas de changement de mode.
- public delegate void ModChangeHandler(object o, ModChangeEventArgs e);
public class KinectMain
{
@@ -97,6 +96,9 @@
private float maxDist;
private float zeroPoint;
private int imagesToShow;
+ private int takenPoints;
+ private int directionChangeTresholdXY;
+ private float directionChangeTresholdZ;
//Temps de rafraichissement pour le timer (Détection de gesture dans le serveur TUIO).
private int timerElapsing;
@@ -104,6 +106,9 @@
//Serveur TUIO pour la connexion du Middleware vers le Front Atelier.
private Server server;
+ //Gestionnaire de modes.
+ private ModeManagement modeManagement;
+
//Les événements des mains pour la recherche.
public static event LeftHandTrackedHandler LeftHandTrackedEvent;
public static event RightHandTrackedHandler RightHandTrackedEvent;
@@ -117,8 +122,6 @@
public static event JumpHandler JumpEvent;
//L'événement l'utilisateur se déplace dans la zone de détection.
public static event UserPositionHandler UserPositionEvent;
- //L'événement on change de mode.
- public static event ModChangeHandler ModChangeEvent;
private string connexionHost;
private int connexionPort;
@@ -148,6 +151,9 @@
connexionPort = 80;
timerElapsing = 1000;
imagesToShow = 25;
+ takenPoints = 10;
+ directionChangeTresholdXY = 10;
+ directionChangeTresholdZ = 0.01f;
}
//On crée la fenêtre de debug.
@@ -245,12 +251,11 @@
UserPositionListener userPositionListener = new UserPositionListener();
UserPositionEvent += new UserPositionHandler(userPositionListener.ShowOnScreen);
- //Fonction appelée lorsqu'on change de mode.
- ModChangeListener modChangeListener = new ModChangeListener();
- ModChangeEvent += new ModChangeHandler(modChangeListener.ShowOnScreen);
-
//On connecte le serveur à l'adresse locale sur le port 80.
server = new Server(connexionHost, connexionPort, timerElapsing, debug);
+
+ //On crée le gestionnaire de modes.
+ modeManagement = new ModeManagement(this, server, debug);
}
/*
@@ -400,7 +405,7 @@
//Si la main gauche quitte le champ, on lance l'événement approprié.
else
{
- LeftHandQuitEventArgs leftHandQuitEvent = new LeftHandQuitEventArgs(handLeft, handLeft.Position.Z, debug, server);
+ LeftHandQuitEventArgs leftHandQuitEvent = new LeftHandQuitEventArgs(debug, server);
OnLeftHandQuitEvent(leftHandQuitEvent);
}
//Si la main droite est dans le champ, on lance l'événement approprié.
@@ -412,7 +417,7 @@
//Si la main droite quitte le champ, on lance l'événement approprié.
else
{
- RightHandQuitEventArgs rightHandQuitEvent = new RightHandQuitEventArgs(handRight, handRight.Position.Z, debug, server);
+ RightHandQuitEventArgs rightHandQuitEvent = new RightHandQuitEventArgs(debug, server);
OnRightHandQuitEvent(rightHandQuitEvent);
}
@@ -459,6 +464,8 @@
float proximity = userPositionDetector.CalcProximity(first.Position.Z);
int numberOfImages = userPositionDetector.ImagesToShow(proximity, imagesToShow);
+ modeManagement.DetectProximityBasedModes(proximity, numberOfImages);
+
if (proximity > 0f)
{
UserPositionEventArgs userPositionEvent = new UserPositionEventArgs(debug, server, proximity, numberOfImages);
@@ -467,6 +474,10 @@
else
{
debug.hideSkeleton();
+ LeftHandQuitEventArgs leftHandQuitEvent = new LeftHandQuitEventArgs(debug, server);
+ OnLeftHandQuitEvent(leftHandQuitEvent);
+ RightHandQuitEventArgs rightHandQuitEvent = new RightHandQuitEventArgs(debug, server);
+ OnRightHandQuitEvent(rightHandQuitEvent);
}
}
@@ -475,7 +486,13 @@
debug.showSkeleton(hipCenter, spine, shoulderCenter, head, shoulderLeft, elbowLeft, wristLeft, handLeft, shoulderRight, elbowRight, wristRight, handRight, hipLeft, kneeLeft, ankleLeft, footLeft, hipRight, kneeRight, ankleRight, footRight);
}
else
+ {
debug.hideSkeleton();
+ LeftHandQuitEventArgs leftHandQuitEvent = new LeftHandQuitEventArgs(debug, server);
+ OnLeftHandQuitEvent(leftHandQuitEvent);
+ RightHandQuitEventArgs rightHandQuitEvent = new RightHandQuitEventArgs(debug, server);
+ OnRightHandQuitEvent(rightHandQuitEvent);
+ }
}
/*
@@ -560,15 +577,6 @@
}
/*
- * Initialise l'événement et fait appel aux fonctions du listener quand on change de mode.
- */
- public static void OnModChangeEvent(ModChangeEventArgs e)
- {
- if (ModChangeEvent != null)
- ModChangeEvent(new object(), e);
- }
-
- /*
* Méthode de chargement des paramètres (position du champ de recherche...).
*/
public bool loadParameters()
@@ -584,6 +592,9 @@
connexionPort = int.Parse(ConfigurationManager.AppSettings["connexionPort"]);
timerElapsing = int.Parse(ConfigurationManager.AppSettings["timerElapsing"]);
imagesToShow = int.Parse(ConfigurationManager.AppSettings["imagesToShow"]);
+ takenPoints = int.Parse(ConfigurationManager.AppSettings["takenPoints"]);
+ directionChangeTresholdXY = int.Parse(ConfigurationManager.AppSettings["directionChangeTresholdXY"]);
+ directionChangeTresholdZ = (float)double.Parse(ConfigurationManager.AppSettings["directionChangeTresholdZ"]);
}
catch (Exception)
{
@@ -592,7 +603,8 @@
if (maxDistHands <= 0f || minDistHands <= 0f || maxDistHands > maxDist || minDistHands > maxDist ||
minDistHands >= maxDistHands || zeroPoint < maxDistHands || minDistHands < minDist ||
- zeroPoint >= maxDist || connexionPort < 0 || timerElapsing < 0 || imagesToShow < 1)
+ zeroPoint >= maxDist || connexionPort < 0 || timerElapsing < 0 || imagesToShow < 1 ||
+ takenPoints <= 0 || directionChangeTresholdXY < 0 || directionChangeTresholdZ < 0)
{
debug.ExceptionLbl.Content = rm.GetString("loadParametersIncorrect");
return false;
@@ -606,6 +618,7 @@
public void updateParameters()
{
userPositionDetector.setParams(minDist, maxDist, minDistHands, maxDistHands, zeroPoint);
+ //segmenter.setParams(takenPoints, directionChangeTresholdXY, directionChangeTresholdZ);
//On récupère la config.
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
@@ -628,6 +641,12 @@
config.AppSettings.Settings.Add("timerElapsing", timerElapsing.ToString());
config.AppSettings.Settings.Remove("imagesToShow");
config.AppSettings.Settings.Add("imagesToShow", imagesToShow.ToString());
+ config.AppSettings.Settings.Remove("takenPoints");
+ config.AppSettings.Settings.Add("takenPoints", takenPoints.ToString());
+ config.AppSettings.Settings.Remove("directionChangeTresholdXY");
+ config.AppSettings.Settings.Add("directionChangeTresholdXY", directionChangeTresholdXY.ToString());
+ config.AppSettings.Settings.Remove("directionChangeTresholdZ");
+ config.AppSettings.Settings.Add("directionChangeTresholdZ", directionChangeTresholdZ.ToString());
//Sauvegarde la configuration.
config.Save(ConfigurationSaveMode.Modified);
@@ -673,6 +692,18 @@
{
imagesToShow = _imagesToShow;
}
+ public void setTakenPoints(int _takenPoints)
+ {
+ takenPoints = _takenPoints;
+ }
+ public void setDirectionChangeTresholdXY(int _directionChangeTresholdXY)
+ {
+ directionChangeTresholdXY = _directionChangeTresholdXY;
+ }
+ public void setDirectionChangeTresholdZ(float _directionChangeTresholdZ)
+ {
+ directionChangeTresholdZ = _directionChangeTresholdZ;
+ }
public float getMinDistHands()
{
@@ -710,5 +741,17 @@
{
return imagesToShow;
}
+ public int getTakenPoints()
+ {
+ return takenPoints;
+ }
+ public int getDirectionChangeTresholdXY()
+ {
+ return directionChangeTresholdXY;
+ }
+ public float getDirectionChangeTresholdZ()
+ {
+ return directionChangeTresholdZ;
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/ModeManagement.cs Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,161 @@
+/*
+* This file is part of the TraKERS\Middleware package.
+*
+* (c) IRI <http://www.iri.centrepompidou.fr/>
+*
+* 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 : Tracking
+ * Classe : ModeManagement
+ *
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ *
+ * Fonctionnalités : Permet de gérer les différents modes qui découpent l'interaction avec le middleware.
+ * Découpe l'interaction avec le middleware en différents modes.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Trakers.Communication;
+using Trakers.Tracking.Events;
+using Trakers.Debug;
+
+namespace Trakers.Tracking
+{
+ public class ModeManagement
+ {
+ //Il s'agit de la fonctoin permettant de notifier le serveur en cas de changement de mode.
+ public delegate void ModChangeHandler(object o, ModChangeEventArgs e);
+ //L'événement on change de mode.
+ public static event ModChangeHandler ModChangeEvent;
+
+ //Accès au module d'interaction principal.
+ private KinectMain kinectMain;
+ //Accès au debug.
+ private DebugWindow debug;
+ //Accès au serveur.
+ private Server server;
+ //La liste des modes.
+ public enum Mode {NO_USER, USER_INCOMING, MOSAIC, FILTER, VIDEO, TIMELINE, SEARCH};
+ //Mode actuel.
+ private Mode currentMode;
+
+ /*
+ * Constructeur qui prend en paramètres le module principal et le serveur.
+ */
+ public ModeManagement(KinectMain _kinectMain, Server _server, DebugWindow _debug)
+ {
+ kinectMain = _kinectMain;
+ server = _server;
+ debug = _debug;
+ currentMode = Mode.NO_USER;
+
+ //Fonction appelée lorsqu'on change de mode.
+ ModChangeListener modChangeListener = new ModChangeListener();
+ ModChangeEvent += new ModChangeHandler(modChangeListener.ShowOnScreen);
+ }
+
+ /*
+ * Détecte tout changement de mode en se basant sur la proximité de l'utilisateur.
+ */
+ public void DetectProximityBasedModes(float proximity, int numberOfImages)
+ {
+ //Si l'utilisateur se déplace dans la zone de détection.
+ //On traite le problème en plusieurs limites, on discrétise la zone.
+ //On considère qu'il n'y a pas d'utilisateur si sa proximité est trop faible.
+ if (proximity < 10f && currentMode != Mode.NO_USER)
+ {
+ currentMode = Mode.NO_USER;
+ ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "NO_USER");
+ OnModChangeEvent(modChangeEvent);
+ }
+ //S'il n'est pas encore au point d'interaction maximale, on considère qu'il est en chemin.
+ else if (proximity >= 10f && proximity < 100f)
+ {
+ currentMode = Mode.USER_INCOMING;
+ ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "USER_INCOMING");
+ OnModChangeEvent(modChangeEvent);
+ }
+ //S'il est arrivé au point, il a la mosaïque complète.
+ else
+ {
+ currentMode = Mode.MOSAIC;
+ ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "MOSAIC");
+ OnModChangeEvent(modChangeEvent);
+ }
+ }
+
+ /*
+ * Détecte si l'utilisateur veut filtrer la mosaïque.
+ */
+ public void DetectFilterMode()
+ {
+ //Ne fonctionne que si on se trouve dans la mosaïque.
+ if (currentMode == Mode.MOSAIC)
+ {
+ currentMode = Mode.FILTER;
+ ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "FILTER");
+ OnModChangeEvent(modChangeEvent);
+ }
+ }
+
+ /*
+ * Détecte si l'utilisateur veut entrer dans une vidéo.
+ */
+ public void DetectVideoMode()
+ {
+ //Si on vient de la mosaïque, d'un filtrage, de la timeline ou d'une recherche, on peut entrer.
+ if (currentMode == Mode.MOSAIC || currentMode == Mode.FILTER ||
+ currentMode == Mode.TIMELINE || currentMode == Mode.SEARCH)
+ {
+ currentMode = Mode.VIDEO;
+ ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "VIDEO");
+ OnModChangeEvent(modChangeEvent);
+ }
+ }
+
+ /*
+ * Détecte si l'utilisateur veut entrer dans la timeline.
+ */
+ public void DetectTimeLineMode()
+ {
+ //Si on est dans une vidéo, on peut entrer.
+ if (currentMode == Mode.VIDEO)
+ {
+ currentMode = Mode.TIMELINE;
+ ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "TIMELINE");
+ OnModChangeEvent(modChangeEvent);
+ }
+ }
+
+ /*
+ * Détecte si l'utilisateur veut effectuer une recherche dans cette vidéo.
+ */
+ public void DetectSearchMode()
+ {
+ //Si on est dans une vidéo, on peut entrer.
+ if (currentMode == Mode.VIDEO)
+ {
+ currentMode = Mode.SEARCH;
+ ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "SEARCH");
+ OnModChangeEvent(modChangeEvent);
+ }
+ }
+
+ /*
+ * Initialise l'événement et fait appel aux fonctions du listener quand on change de mode.
+ */
+ public static void OnModChangeEvent(ModChangeEventArgs e)
+ {
+ if (ModChangeEvent != null)
+ ModChangeEvent(new object(), e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Comparator.cs Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,36 @@
+/*
+* This file is part of the TraKERS\Middleware package.
+*
+* (c) IRI <http://www.iri.centrepompidou.fr/>
+*
+* 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 : Comparator
+ *
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ *
+ * Fonctionnalités : Permet de comparer une courbe tracée avec un dictionnaire.
+ * La comparaison se fait sur les segments de chaque courbe, ce qui permet d'avancer dans l'arbre du
+ * dictionnaire et de présenter des complétions potentielles.
+ * Lors d'une comparaison entre deux structures de courbes, chaque segment est comparé un à un, ensuite,
+ * c'est l'ensemble de la structure qui est comparée à l'autre (afin d'éviter les problèmes de changement
+ * d'échelle partielle).
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Trakers.Tracking.Search
+{
+ public class Comparator
+ {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Constructor.cs Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,38 @@
+/*
+* This file is part of the TraKERS\Middleware package.
+*
+* (c) IRI <http://www.iri.centrepompidou.fr/>
+*
+* 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 : Constructor
+ *
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ *
+ * Fonctionnalités : Construit une structure au fur et à mesure que ses segments sont tracés.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Trakers.Tracking.Search
+{
+ public class Constructor
+ {
+ /*public double Bernstein(int i, int k, double t)
+ {
+ if(i == 0 && k == 0)
+ return 1;
+
+ }*/
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Curve.cs Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,32 @@
+/*
+* This file is part of the TraKERS\Middleware package.
+*
+* (c) IRI <http://www.iri.centrepompidou.fr/>
+*
+* 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 : Curve
+ *
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ *
+ * Fonctionnalités : Définit l'objet de courbe en lui-même, composé d'une ou deux structures et
+ * d'un pictogramme le représentant.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Trakers.Tracking.Search
+{
+ public class Curve
+ {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Dictionnary.cs Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,31 @@
+/*
+* This file is part of the TraKERS\Middleware package.
+*
+* (c) IRI <http://www.iri.centrepompidou.fr/>
+*
+* 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 : Dictionnary
+ *
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ *
+ * Fonctionnalités : Dictionnaire sous forme d'arbre contenant les courbes répertoriées pour la recherche.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Trakers.Tracking.Search
+{
+ public class Dictionnary
+ {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Segment.cs Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,36 @@
+/*
+* This file is part of the TraKERS\Middleware package.
+*
+* (c) IRI <http://www.iri.centrepompidou.fr/>
+*
+* 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 : Segment
+ *
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ *
+ * Fonctionnalités : Définit un composant de structure de courbe.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Media.Media3D;
+
+namespace Trakers.Tracking.Search
+{
+ public class Segment
+ {
+ //Points de la courbe réelle.
+ private List<double> knots;
+ //Points de contrôle.
+ private List<Point3D> P;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Segmenter.cs Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,284 @@
+/*
+* This file is part of the TraKERS\Middleware package.
+*
+* (c) IRI <http://www.iri.centrepompidou.fr/>
+*
+* 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<Point3D> 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<Point3D>();
+ 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;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Structure.cs Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,32 @@
+/*
+* This file is part of the TraKERS\Middleware package.
+*
+* (c) IRI <http://www.iri.centrepompidou.fr/>
+*
+* 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 : Structure
+ *
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ *
+ * Fonctionnalités : Définit la structure d'une courbe d'un point de vue algorithmique.
+ * Ce sont ces structures là qui seront comparées par la suite.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Trakers.Tracking.Search
+{
+ public class Structure
+ {
+ }
+}
--- a/middleware/src/Trakers.csproj Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Trakers.csproj Thu Mar 29 14:39:21 2012 +0200
@@ -130,12 +130,22 @@
<Compile Include="Tracking\Events\RightHandTrackedListener.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Tracking\ModeManagement.cs" />
+ <Compile Include="Tracking\Search\Comparator.cs" />
+ <Compile Include="Tracking\Search\Constructor.cs" />
+ <Compile Include="Tracking\Search\Curve.cs" />
+ <Compile Include="Tracking\Search\Dictionnary.cs" />
+ <Compile Include="Tracking\Search\Segment.cs" />
+ <Compile Include="Tracking\Search\Segmenter.cs" />
+ <Compile Include="Tracking\Search\Structure.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
- <None Include="App.config" />
+ <None Include="App.config">
+ <SubType>Designer</SubType>
+ </None>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -152,6 +162,7 @@
<SubType>Designer</SubType>
</Page>
</ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.