Esempio n. 1
0
        public float DistanceTo(DGInstance otherInstance, bool useDTW)
        {
            float dist = useDTW ? GetDTWDistance(otherInstance) : GetLerpedDistance(otherInstance);

            // Factor in path length (with weight 1/5):
            int   newFeatureCount = 0;
            float additionalDist  = 0;

            if (IncludesLeftHand)
            {
                additionalDist += Math.Abs(otherInstance.LeftHandPathLength - MeanLeftHandPathLength) / StdDevLeftHandPathLength;
                newFeatureCount++;
            }
            if (IncludesRightHand)
            {
                additionalDist += Math.Abs(otherInstance.RightHandPathLength - MeanRightHandPathLength) / StdDevRightHandPathLength;
                newFeatureCount++;
            }
            additionalDist /= (float)newFeatureCount;

            float additionalDistWeight = 0;            // 0.1f;

            dist = ((1 - additionalDistWeight) * dist) + (additionalDistWeight * additionalDist);

            return(dist);
        }
Esempio n. 2
0
 public DGInstanceWrapper(DGInstance instance)
 {
     Instance     = instance;
     Id           = -1;
     ClassId      = -1;
     InstanceName = "new instance";
 }
        public void SaveNewDynamicGestureInstance(int classId, DGInstance instance)         // Whenever this is called it will be a new instance.
        {
            string serializedInstance = JsonConvert.SerializeObject(instance);
            string sql = String.Format("INSERT INTO DynamicGestureInstances (class_id, json) VALUES ('{0}', '{1}')", classId, serializedInstance);

            executeNonQuery(sql);
        }
        public DGInstance GetDtwMappedInstance(DGInstance target)
        {
            DGInstance mappedInstance;

            GetDtwDistance(target, out mappedInstance);
            return(mappedInstance);
        }
 public Dictionary <DGClassWrapper, float> GetDistancesFromAllClasses(DGInstance gestureInstance)
 {
     lock (_dynamicGestureClasses)
     {
         var gestureDistances = new Dictionary <DGClassWrapper, float>();
         foreach (var gestureClass in _dynamicGestureClasses)
         {
             gestureDistances.Add(gestureClass, gestureClass.Gesture.DistanceTo(gestureInstance, UseDTW));
         }
         return(gestureDistances);
     }
 }
Esempio n. 6
0
        // Lerps instance to make its sample collection same size as this class.
        public float GetLerpedDistance(DGInstance otherInstance)
        {
            float distance        = 0;
            var   instanceSamples = otherInstance.GetResizedSampleList(LerpedSamples.Count);

            for (int i = 0; i < LerpedSamples.Count; i++)
            {
                var temp = LerpedSamples[i].DistanceTo(instanceSamples[i]);
                distance += temp;
            }

            distance = distance / (float)LerpedSamples.Count;

            return(distance);
        }
Esempio n. 7
0
        // Finds the average number of samples for all dg instances.
        // Lerps all DG instances to be this length, and creates a class for each index.
        public List <DGClassSample> GetLerpedSamples(List <DGInstance> dgInstances)
        {
            var samples = new List <DGClassSample>();

            int classSampleSize   = getAverageSampleSize(dgInstances);
            var lerpedDGInstances = new List <DGInstance>();            // lerps the static gesture instances contained within

            foreach (var instance in dgInstances)
            {
                var resizedInstance = new DGInstance(instance.GetResizedSampleList(classSampleSize));
                lerpedDGInstances.Add(resizedInstance);
            }

            // At this point, lerpedDGInstances() are all the same length.
            for (int i = 0; i < classSampleSize; i++)
            {
                samples.Add(new DGClassSample(lerpedDGInstances.Select(dgi => dgi.Samples[i]).ToList()));
            }

            return(samples);
        }
Esempio n. 8
0
        public float GetDTWDistance(DGInstance otherInstance, int windowSize = 3)
        {
            if (DtwSamples.Count == 0 || otherInstance.Samples.Count == 0)
            {
                return(float.PositiveInfinity);
            }

            float[,] distances = new float[DtwSamples.Count, otherInstance.Samples.Count];
            for (int i = 0; i < DtwSamples.Count; i++)
            {
                for (int j = 0; j < otherInstance.Samples.Count; j++)
                {
                    distances[i, j] = DtwSamples[i].DistanceTo(otherInstance.Samples[j]);
                }
            }

            int window = Math.Max(windowSize, Math.Abs(DtwSamples.Count - otherInstance.Samples.Count));

            float[,] dtw = new float[DtwSamples.Count, otherInstance.Samples.Count];
            for (int i = 0; i < DtwSamples.Count; i++)
            {
                for (int j = 0; j < otherInstance.Samples.Count; j++)
                {
                    dtw[i, j] = float.PositiveInfinity;
                }
            }
            dtw[0, 0] = 0;

            for (int i = 1; i < DtwSamples.Count; i++)
            {
                //for (int j = 0; j < otherInstance.Samples.Count; j++)
                for (int j = Math.Max(1, i - window); j < Math.Min(otherInstance.Samples.Count, i + window); j++)
                {
                    float cost           = distances[i, j];
                    var   precedingCosts = new List <float>()
                    {
                        dtw[Math.Max(i - 1, 0), j],
                        dtw[i, Math.Max(j - 1, 0)],
                        dtw[Math.Max(i - 1, 0), Math.Max(j - 1, 0)]
                    };
                    dtw[i, j] = cost + precedingCosts.Min();
                }
            }

            // TODO: Backtrack through and find the path (particularly interested in its length)
            var path = new Stack <Tuple <int, int> >();
            int x    = DtwSamples.Count - 1;
            int y    = otherInstance.Samples.Count - 1;

            path.Push(new Tuple <int, int>(x, y));
            while (x > 0 || y > 0)
            {
                if (x == 0)
                {
                    y--;
                }
                else if (y == 0)
                {
                    x--;
                }
                else
                {
                    var neighboringCosts = new List <float>()
                    {
                        dtw[Math.Max(0, x - 1), Math.Max(0, y - 1)],
                        dtw[Math.Max(0, x - 1), y],
                        dtw[x, Math.Max(0, y - 1)]
                    };
                    if (dtw[Math.Max(0, x - 1), y] == neighboringCosts.Min())
                    {
                        x--;
                    }
                    else if (dtw[x, Math.Max(0, y - 1)] == neighboringCosts.Min())
                    {
                        y--;
                    }
                    else
                    {
                        x--; y--;
                    }
                }
                path.Push(new Tuple <int, int>(x, y));
            }

            float distance = dtw[DtwSamples.Count - 1, otherInstance.Samples.Count - 1] / (float)path.Count;

            return(distance);
        }
        public float GetDtwDistance(DGInstance otherInstance, out DGInstance mappedInstance)
        {
            mappedInstance = null;

            if (Samples.Count == 0 || otherInstance.Samples.Count == 0)
            {
                return(float.PositiveInfinity);
            }

            float[,] distances = new float[Samples.Count, otherInstance.Samples.Count];
            for (int i = 0; i < Samples.Count; i++)
            {
                for (int j = 0; j < otherInstance.Samples.Count; j++)
                {
                    distances[i, j] = Samples[i].DistanceTo(otherInstance.Samples[j]);
                }
            }

            float[,] dtw = new float[Samples.Count, otherInstance.Samples.Count];
            for (int i = 0; i < Samples.Count; i++)
            {
                for (int j = 0; j < otherInstance.Samples.Count; j++)
                {
                    float cost           = distances[i, j];
                    var   precedingCosts = new List <float>()
                    {
                        dtw[Math.Max(i - 1, 0), j],
                        dtw[i, Math.Max(j - 1, 0)],
                        dtw[Math.Max(i - 1, 0), Math.Max(j - 1, 0)]
                    };
                    dtw[i, j] = cost + precedingCosts.Min();
                }
            }

            // TODO: Backtrack through and find the path (particularly interested in its length)
            var path = new Stack <Tuple <int, int> >();
            int x    = Samples.Count - 1;
            int y    = otherInstance.Samples.Count - 1;

            path.Push(new Tuple <int, int>(x, y));
            while (x > 0 || y > 0)
            {
                if (x == 0)
                {
                    y--;
                }
                else if (y == 0)
                {
                    x--;
                }
                else
                {
                    var neighboringCosts = new List <float>()
                    {
                        dtw[x - 1, y - 1],
                        dtw[x - 1, y],
                        dtw[x, y - 1]
                    };
                    if (dtw[x - 1, y] == neighboringCosts.Min())
                    {
                        x--;
                    }
                    else if (dtw[x, y - 1] == neighboringCosts.Min())
                    {
                        y--;
                    }
                    else
                    {
                        x--; y--;
                    }
                }
                path.Push(new Tuple <int, int>(x, y));
            }

            // x (Item1) is index of this instance; y (Item2) is index of other instance
            var mappedSamples = new List <DGInstanceSample>();

            while (path.Count > 0)
            {
                int index = path.Pop().Item1;
                mappedSamples.Add(Samples[index]);
            }

            mappedInstance = new DGInstance(mappedSamples);

            float distance = dtw[Samples.Count - 1, otherInstance.Samples.Count - 1] / path.Count;

            return(distance);
        }
Esempio n. 10
0
        public void ProcessFrame(Frame frame)
        {
            if (_lastFrame == null)
            {
                _lastFrame = frame;
                return;
            }

            bool handsStill = handsAreStill(frame);

            if (frame.Hands.Count == 0)
            {
                State = DGRecorderState.WaitingForHands;
            }

            switch (State)
            {
            case DGRecorderState.WaitingForHands:
                if (frame.Hands.Count > 0)
                {
                    _stillGesture = new SGInstance(frame);
                    State         = DGRecorderState.WaitingToStart;
                }
                break;

            case DGRecorderState.WaitingToStart:
                if (handsStill)
                {
                    _startOfGesture = new DGInstanceSample(frame);
                    _gestureSamples = new List <DGInstanceSample>();
                    _gestureSamples.Add(_startOfGesture);

                    State = DGRecorderState.InStartPosition;
                }
                break;

            case DGRecorderState.InStartPosition:
                if (!handsStill)
                {
                    State = DGRecorderState.RecordingGesture;
                }
                break;

            case DGRecorderState.RecordingGesture:
                if (handsStill)
                {
                    // Trim the extra samples in back (from holding hand still for X seconds)
                    int stillFrames = (int)(_frameRate * _stillSeconds);
                    _gestureSamples.RemoveRange(_gestureSamples.Count - stillFrames, stillFrames);

                    MostRecentInstance = new DGInstance(_gestureSamples);
                    if (_inRecordMode)
                    {
                        Instances.Add(MostRecentInstance);
                    }

                    State = DGRecorderState.RecordingJustFinished;                             // Put this first so "InEndPosition" is printed while we process the frames
                }
                else
                {
                    _gestureSamples.Add(new DGInstanceSample(frame));
                }
                break;

            case DGRecorderState.RecordingJustFinished:
                State = DGRecorderState.InEndPosition;
                break;

            case DGRecorderState.InEndPosition:
                if (!handsStill)
                {
                    State = DGRecorderState.WaitingToStart;
                }
                break;
            }
        }