From 893170e54fec74f7b9004a44ba48a60accbacac5 Mon Sep 17 00:00:00 2001 From: Alexis Iakovenko <alexis.iakovenko@gmail.com> Date: Wed, 10 Jan 2018 17:30:09 +0100 Subject: [PATCH] Compute mean for replay --- Assets/Gesture/Gesture.cs | 104 +++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 12 deletions(-) diff --git a/Assets/Gesture/Gesture.cs b/Assets/Gesture/Gesture.cs index a439190..8332081 100644 --- a/Assets/Gesture/Gesture.cs +++ b/Assets/Gesture/Gesture.cs @@ -18,10 +18,9 @@ public class Gesture public Gesture (string name, GestureType type = GestureType.Normal) { + states = new List<GestureState> (); this.name = name; - if (type == GestureType.Normal) - Load (); - else if (type == GestureType.Mean) + if (type == GestureType.Mean) ComputeMean (); else if (type == GestureType.Variance) ComputeVariance (); @@ -29,34 +28,115 @@ public class Gesture void ComputeMean () { + //Debug.Log ("[Gesture:ComputeMean] Start computing mean "); + //find and load gestures to compare for the mean List<Gesture> gesturesToMean = new List<Gesture> (); string path = "Assets/Record/Recorded/" + name + "/"; - foreach (string gesturePath in Directory.GetDirectories (path)) + //Debug.Log ("[Gesture:ComputeMean] path " + path); + foreach (string gesturePath in Directory.GetFiles (path)) { - if (!gesturePath.Equals (path + "mean.txt") && !gesturePath.Equals (path + "variance.txt")) + //Debug.Log ("[Gesture:ComputeMean] gesturePath " + gesturePath); + if (gesturePath.Substring(gesturePath.Length - 4).Equals(".txt") && + !gesturePath.Equals (path + "mean.txt") && !gesturePath.Equals (path + "variance.txt")) { - Gesture gesture = new Gesture(gesturePath); - gesture.Load (); + Gesture gesture = new Gesture(name); + gesture.Load (gesturePath); gesturesToMean.Add(gesture); } } - //compute the mean + if (gesturesToMean.Count == 0) + return; + + + //find mean time and normalize towards it + int meanTime = 0; + foreach (Gesture gesture in gesturesToMean) + meanTime += gesture.states.Count; + meanTime /= gesturesToMean.Count; + foreach (Gesture gesture in gesturesToMean) + gesture.NormalizeTime (meanTime); + + //for each frame, compute position and rotation mean + for (int i = 0; i < meanTime; i++) + { + Vector3 positionMean = new Vector3 (0, 0, 0); + Vector4 rotationMean = new Vector4 (0, 0, 0, 0); + float timestampMean = 0.0f; + + foreach (Gesture gesture in gesturesToMean) + { + timestampMean += gesture.states [i].timestamp; + positionMean += gesture.states [i].position; + rotationMean += gesture.states [i].rotation; + } + + timestampMean /= gesturesToMean.Count; + positionMean /= gesturesToMean.Count; + rotationMean /= gesturesToMean.Count; + + GestureState stateMean = new GestureState (); + stateMean.position = positionMean; + stateMean.rotation = rotationMean; + stateMean.timestamp = timestampMean; + states.Add (stateMean); + } + + Debug.Log ("[Gesture:ComputeMean] Finished computing mean " + meanTime); } void ComputeVariance () { } - public void Load () + public void NormalizeTime(int pointNumber) { - states = GestureLoader.Load (FullPath ()); + if (pointNumber == states.Count) + return; + + float timeNormalizationFactor = pointNumber * 1.0f / states.Count; + //Debug.Log ("Time normalization, factor: " + timeNormalizationFactor); + List<GestureState> normalizedStates = new List<GestureState>(); + + float timestampStep = (states [states.Count - 1].timestamp - states [0].timestamp) / (states.Count - 1); + float normalizedTimestamp = states [0].timestamp; + for (int i = 0; i < pointNumber; i++) + { + GestureState normalizedState = new GestureState (); + + int stateID = (int)Mathf.Floor(i / timeNormalizationFactor); + GestureState currentState = states [stateID]; + Vector3 normalizedPosition = states [stateID].position; + Vector3 normalizedRotation = states [stateID].rotation; + + if (stateID > 0 && stateID < states.Count - 1) + { + GestureState nextState = states [stateID + 1]; + float smallTimestamp = (normalizedTimestamp - currentState.timestamp); + if (smallTimestamp != 0) { + float smallFactor = (nextState.timestamp - currentState.timestamp) / smallTimestamp; + + Vector3 positionToNextState = nextState.position - currentState.position; + normalizedPosition = currentState.position + positionToNextState * smallFactor; + + Vector4 rotationToNextState = nextState.rotation - currentState.rotation; + normalizedRotation = currentState.rotation + rotationToNextState * smallFactor; + } + } + normalizedState.position = normalizedPosition; + normalizedState.rotation = normalizedRotation; + normalizedState.timestamp = normalizedTimestamp; + normalizedStates.Add (normalizedState); + + normalizedTimestamp += timestampStep; + } + states = normalizedStates; } - private string FullPath () + public void Load (string path) { - return directoryPath + name + ".txt"; + states = GestureLoader.Load (path); } public override string ToString () -- GitLab