Inheritance: ICloneable
 public TriggeredProcessingUnit(bool autofilter)
     : base(autofilter)
 {
     this.learning = false;
     this.analyzing = false;
     this.current = new Gesture();
     this.trainsequence = new List<Gesture>();
 }
Exemple #2
0
 /**
  * Make a deep copy of another Gesture object.
  *
  * @param original Another Gesture object
  */
 public Gesture(Gesture original)
 {
     this.data = new List<AccelerationVector>();
     var origin = original.getData();
     for (int i = 0; i < origin.Count; i++)
     {
         this.add((AccelerationVector)origin[i]);
     }
 }
        private Gesture Circle()
        {
            var gesture = new Gesture();

            var steps = Enumerable.Range(1, 100)
                .Select(i => 2 * Math.PI * i / 100.0)
                .Select(i => new AccelerationVector(-Math.Sin(i), -Math.Cos(i), -Math.Sin(i)));

            foreach (var s in steps)
            {
                gesture.add(s);
            }

            return gesture;
        }
Exemple #4
0
        /**
         * This method recognize a specific gesture, given to the procedure.
         * For classification a bayes classification algorithm is used.
         *
         * @param g	gesture to classify
         */
        public GestureModel classifyGesture(Gesture g)
        {
            // Calculate the denominator, Bayesian
            double sum = 0;
            foreach (var model in gesturemodel)
            {
                sum += model.DefaultProbability *
                        model.GetMatchProbability(g);
            }

            GestureModel recognized = null; // which gesture has been recognized
            double recogprob = Int32.MinValue; // probability of this gesture
            double probgesture = 0; // temporal value for bayes algorithm
            double probmodel = 0; // temporal value for bayes algorithm
            foreach (var model in gesturemodel)
            {
                double tmpgesture = model.GetMatchProbability(g);
                double tmpmodel = model.DefaultProbability;

                if (((tmpmodel * tmpgesture) / sum) > recogprob)
                {
                    probgesture = tmpgesture;
                    probmodel = tmpmodel;
                    recogprob = ((tmpmodel * tmpgesture) / sum);
                    recognized = model;
                }
            }

            // a gesture could be recognized
            if (recogprob > 0 && probmodel > 0 && probgesture > 0 && sum > 0)
            {
                this.lastprob = recogprob;
                return recognized;
            }
            else
            {
                // no gesture could be recognized
                return null;
            }
        }
        public void StopTraining()
        {
            if (this.learning)
            {
                if (this.current.getCountOfData() > 0)
                {
                    Gesture gesture = new Gesture(this.current);
                    this.trainsequence.Add(gesture);
                    this.current = new Gesture();
                }

                this.learning = false;
            }
        }
        public void StopRecognition()
        {
            if (this.analyzing)
            {
                if (this.current.getCountOfData() > 0)
                {
                    Gesture gesture = new Gesture(this.current);

                    var recognized = this.classifier.classifyGesture(gesture);
                    if (recognized != null)
                    {
                        double recogprob = this.classifier.getLastProbability();
                        this.OnGestureRecognized(recognized, recogprob);
                    }
                    else
                    {
                        this.OnGestureRecognized(null, 0.0);
                        // No gesture recognized
                    }

                    this.current = new Gesture();
                }

                this.analyzing = false;
            }
        }
Exemple #7
0
        /**
         * With this method you can transform a gesture to a discrete symbol
         * sequence with values between 0 and granularity (number of observations).
         *
         * @param gesture
         *            Gesture to get the observationsequence to.
         */
        public int[] getObservationSequence(Gesture gesture)
        {
            int[,] groups = this.deriveGroups(gesture);
            List<int> sequence = new List<int>();

            for (int j = 0; j < groups.GetLength(1); j++)
            { // spalten
                for (int i = 0; i < groups.GetLength(0); i++)
                { // zeilen
                    if (groups[i,j] == 1)
                    {
                        sequence.Add(i);
                        break;
                    }
                }
            }

            // this is very dirty! it have to be here because if not
            // too short sequences would cause an error. i've to think about a
            // better resolution than copying the old value a few time.
            while (sequence.Count < this.numStates)
            {
                sequence.Add(sequence[sequence.Count - 1]);
            }

            int[] output = new int[sequence.Count];
            for (int i = 0; i < sequence.Count; i++)
            {
                output[i] = sequence[i];
            }

            return output;
        }
Exemple #8
0
        /**
         * This methods looks up a Gesture to a group matrix, used by the
         * k-mean-algorithm (traincenteroid method) above.
         *
         * @param gesture
         *            the gesture
         */
        private int[,] deriveGroups(Gesture gesture)
        {
            List<AccelerationVector> data = gesture.getData();
            int[,] groups = new int[this.map.Length, data.Count];

            // Calculate cartesian distance
            double[,] d = new double[this.map.Length, data.Count];
            double[] curr = new double[3];
            double[] vector = new double[3];

            for (int i = 0; i < this.map.Length; i++)
            { // lines
                var line = this.map[i];
                for (var j = 0; j < data.Count; j++)
                { // split
                    var accel = data[j];

                    curr[0] = accel.X;
                    curr[1] = accel.Y;
                    curr[2] = accel.Z;

                    vector[0] = line[0] - curr[0];
                    vector[1] = line[1] - curr[1];
                    vector[2] = line[2] - curr[2];
                    d[i,j] = Math.Sqrt((vector[0] * vector[0])
                            + (vector[1] * vector[1]) + (vector[2] * vector[2]));
                }
            }

            // look, to which group a value belongs
            for (int j = 0; j < data.Count; j++)
            {
                double smallest = Double.MaxValue;
                int row = 0;
                for (int i = 0; i < this.map.GetLength(0); i++)
                {
                    if (d[i, j] < smallest)
                    {
                        smallest = d[i, j];
                        row = i;
                    }
                    groups[i, j] = 0;
                }
                groups[row, j] = 1; // group set
            }

            return groups;
        }
Exemple #9
0
        /**
         * Trains this Quantizer with a specific gesture. This means that the
         * positions of the centeroids would adapt to this training gesture. In our
         * case this would happen with a summarized virtual gesture, containing all
         * the other gestures.
         *
         * @param gesture
         *            the summarized virtual gesture
         */
        public void trainCenteroids(Gesture gesture)
        {
            List<AccelerationVector> data = gesture.getData();
            double pi = Math.PI;
            this.radius = (gesture.getMaxAcceleration() + gesture.getMinAcceleration()) / 2;

            // x , z , y
            if (!this.maptrained) {
            this.maptrained = true;
            this.map[0] = new double[] { this.radius, 0.0, 0.0 };
            this.map[1] = new double[] { Math.Cos(pi / 4) * this.radius, 0.0,
                    Math.Sin(pi / 4) * this.radius };
            this.map[2] = new double[] { 0.0, 0.0, this.radius };
            this.map[3] = new double[] { Math.Cos(pi * 3 / 4) * this.radius,
                    0.0, Math.Sin(pi * 3 / 4) * this.radius };
            this.map[4] = new double[] { -this.radius, 0.0, 0.0 };
            this.map[5] = new double[] { Math.Cos(pi * 5 / 4) * this.radius,
                    0.0, Math.Sin(pi * 5 / 4) * this.radius };
            this.map[6] = new double[] { 0.0, 0.0, -this.radius };
            this.map[7] = new double[] { Math.Cos(pi * 7 / 4) * this.radius,
                    0.0, Math.Sin(pi * 7 / 4) * this.radius };

            this.map[8] = new double[] { 0.0, this.radius, 0.0 };
            this.map[9] = new double[] { 0.0, Math.Cos(pi / 4) * this.radius,
                    Math.Sin(pi / 4) * this.radius };
            this.map[10] = new double[] { 0.0,
                    Math.Cos(pi * 3 / 4) * this.radius,
                    Math.Sin(pi * 3 / 4) * this.radius };
            this.map[11] = new double[] { 0.0, -this.radius, 0.0 };
            this.map[12] = new double[] { 0.0,
                    Math.Cos(pi * 5 / 4) * this.radius,
                    Math.Sin(pi * 5 / 4) * this.radius };
            this.map[13] = new double[] { 0.0,
                    Math.Cos(pi * 7 / 4) * this.radius,
                    Math.Sin(pi * 7 / 4) * this.radius };
            }

            int[,] g_alt = new int[this.map.Length, data.Count];
            int[,] g = new int[this.map.Length, data.Count];

            do {
            // Derive new Groups...
            g_alt = this.copyarray(g);
            g = this.deriveGroups(gesture);

            // calculate new centeroids
            for (int i = 0; i < this.map.GetLength(0); i++) {
                double zaehlerX = 0;
                double zaehlerY = 0;
                double zaehlerZ = 0;
                int nenner = 0;
                for (int j = 0; j < data.Count; j++) {
                    if (g[i,j] == 1) {
                        var e = data[j];
                        zaehlerX += e.X;
                        zaehlerY += e.Y;
                        zaehlerZ += e.Z;
                        nenner++;
                    }
                }
                if (nenner > 1) { // nur wenn der nenner>0 oder >1??? ist muss
                                    // was
                    // geaendert werden
                    // Log.write("Setze neuen Centeroid!");
                    this.map[i] = new double[] {(zaehlerX / (double) nenner),
                                                (zaehlerY / (double) nenner),
                                                (zaehlerZ / (double) nenner) };
                    // Log.write("Centeroid: "+i+": "+newcenteroid[0]+":"+newcenteroid[1]);
                }
            } // new centeroids

            } while (!equalarrays(g_alt, g));

            // Debug: Printout groups
            /*
             * for (int i = 0; i < n; i++) { for (int j = 0; j < this.data.Count;
             * j++) { Log.write(g[i][j] + "|"); } Log.write(""); }
             */
        }
Exemple #10
0
        /**
         * Trains the model to a set of motion-sequences, representing
         * different evaluations of a gesture
         *
         * @param trainsequence	a vector of gestures
         */
        public void Train(IEnumerable<Gesture> trainsequence)
        {
            // summarize all vectors from the different gestures in one
            // gesture called sum.
            double maxacc = 0;
            double minacc = 0;
            Gesture sum = new Gesture();

            foreach (var gesture in trainsequence)
            {
                IEnumerable<AccelerationVector> t = gesture.getData();

                // add the max and min acceleration, we later get the average
                maxacc += gesture.getMaxAcceleration();
                minacc += gesture.getMinAcceleration();

                // transfer every single accelerationevent of each gesture to
                // the new gesture sum
                foreach (var accelerationEvent in t)
                {
                    sum.add(accelerationEvent);
                }

            }

            // get the average and set it to the sum gesture
            sum.setMaxAndMinAcceleration(maxacc / trainsequence.Count(), minacc / trainsequence.Count());

            // train the centeroids of the quantizer with this master gesture sum.
            this.quantizer.trainCenteroids(sum);

            // convert gesture vector to a sequence of discrete values
            var seqs = new List<int[]>();
            foreach (var gesture in trainsequence)
            {
                seqs.Add(this.quantizer.getObservationSequence(gesture));
            }

            // train the markov model with this derived discrete sequences
            this.markovmodell.train(seqs);

            // set the default probability for use with the bayes classifier
            this.SetDefaultProbability(trainsequence);
        }
Exemple #11
0
 /**
  * Returns the probability that a gesture matches to this
  * gesture model.
  *
  * @param gesture a gesture to test.
  * @return probability that the gesture belongs to this gesture
  * model.
  */
 public double GetMatchProbability(Gesture gesture)
 {
     int[] sequence = quantizer.getObservationSequence(gesture);
     return this.markovmodell.getProbability(sequence);
 }