コード例 #1
0
        /// <summary>
        /// Classifies the specified input data.
        /// </summary>
        /// <param name="inputData">The input data.</param>
        /// <returns>a classification result containing name and parameter of the recognized gesture if
        /// recognition succeeds, null otherwise.</returns>
        public IClassificationResult Classify(TrackedGesture inputData)
        {
            IClassificationResult result = null;

            //RecognizePinchGesture(inputData);
            if (inputData.Count == 0)
            {
                return(result);
            }
            //if (result == null)
            //{
            //    result = RecognizeSemiPinchGesture(inputData);
            //}
            if (result == null)
            {
                result = RecognizeBlurryPinchGesture(inputData);
            }
            if (result == null)
            {
                result = RecognizeBlurryLineGesture(inputData);
            }
            if (result == null)
            {
                result = RecognizeBlurryCircleGesture(inputData);
            }
            if (result == null)
            {
                result = RecognizeXFingerDragging(inputData.FrameList, 3);
            }
            System.Diagnostics.Debug.WriteLine("recognized: " + (result == null ? "nothing" :
                                                                 result.ToString()));
            return(result);
        }
コード例 #2
0
        private IClassificationResult RecognizeBlurryCircleGesture(TrackedGesture inputData)
        {
            String resultString = null;

            if (!CheckTokenCriterion(inputData.FrameList, 1))
            {
                return(null);
            }
            int startPointIndex = FindFirstFrameIndexWithCorrectCount(inputData.FrameList, 1, true);
            int endPointIndex   = FindFirstFrameIndexWithCorrectCount(inputData.FrameList, 1, false);

            if (startPointIndex == -1 || endPointIndex == -1)
            {
                return(null);
            }

            Vertex startPoint = new Vertex(inputData.FrameList[startPointIndex][0].x, inputData.FrameList[startPointIndex][0].y);
            Vertex endPoint   = new Vertex(inputData.FrameList[endPointIndex][0].x, inputData.FrameList[endPointIndex][0].y);

            //search endpoint es point with max distance from start point
            Size dim;
            var  centre = GetCentre(inputData.FrameList, out dim); //centre of all blobs

            if (MetricDistances.EuclideanDistance(centre, startPoint)
                > MetricDistances.EuclideanDistance(startPoint, endPoint))
            {
                int endPointBlobIndex = GetBlobMaxDistantFromPointIndex(inputData.FrameList, startPoint, out endPointIndex);
            }

            if (CheckCircleFormKriterion(inputData.FrameList))
            {
                if (CheckForFullCircle(inputData.FrameList, startPoint, endPoint))
                {
                    resultString = "circle";
                }
                else
                {
                    resultString = "semi circle";
                }
            }
            else
            {
                return(null);
            }

            return(new ClassificationResult(
                       resultString,
                       100.0,
                       new Sample[] { new Sample(DateTime.Now, startPoint) },
                       new KeyValuePair <String, double>("direction", GetCircleDirection(inputData.FrameList) ? 1.0 : -1.0),
                       new KeyValuePair <String, Size>("dimensions", dim)
                       ));
        }
コード例 #3
0
        public virtual IClassificationResult FinishEvaluation(bool clear)
        {
            IClassificationResult classificationResult = null;

            if (blobTracker != null)
            {
                TrackedGesture trackedGesture = blobTracker.TrackedBlobs;
                RecognitionMode = false;
                if (blobTracker.Trajectories.Count > 0)
                {
                    Console.WriteLine("Gesture trajectories to evaluate:" + blobTracker.Trajectories.Count);
                    List <IClassificationResult> oldResults = new List <IClassificationResult>();
                    // foreach (IClassify classifier in classifiers){
                    for (int i = 0; i < classifiers.Count; i++)
                    {
                        IClassify classifier = classifiers[i];
                        if (classifier != null)
                        {
                            classificationResult = classifier.Classify(blobTracker.FrameList, blobTracker.Trajectories);
                            if (classificationResult != null)
                            {
                                if (classificationResult.Probability > ProbabilityThreshold)
                                {
                                    break;
                                }
                                else
                                {
                                    oldResults.Add(classificationResult);
                                }
                            }
                        }
                    }

                    // no result was taken directly, so find the first one with the highest probability
                    if (oldResults != null && oldResults.Count > 0)
                    {
                        foreach (var result in oldResults)
                        {
                            if (classificationResult == null || result.Probability > classificationResult.Probability)
                            {
                                classificationResult = result;
                            }
                        }
                    }
                }
                if (clear)
                {
                    blobTracker.InitiateTracking();
                }
            }
            return(classificationResult);
        }
コード例 #4
0
        /// <summary>
        /// Checks for tap gestures.
        /// </summary>
        /// <param className="clusteredSamples">The clustered samples.</param>
        /// <returns>Number of Taps detected, -1 if no tap gesture could be recognized.</returns>
        private int CheckForTapGestures(TrackedGesture inputData, ref Vertex tapedPos)
        {
            tapedPos[0] = -1;
            if (inputData == null || inputData.Count == 0)
            {
                return(-1);
            }
            var frameList       = inputData.FrameList;
            int framesWithBlobs = 0;
            int taps            = 1;
            int frameCounter    = 0;

            foreach (var frame in frameList)
            {
                if (frame.Count > 1)
                {
                    return(-1);
                }
                if (frame.Count == 1)
                {
                    framesWithBlobs++;
                    if (!(frame[0].cx < MAXTAPDISTANCE && frame[0].cy < MAXTAPDISTANCE)) //to big blobs
                    {
                        return(-1);
                    }
                    if (tapedPos[0] != -1.0 &&
                        MetricDistances.EuclideanDistance(tapedPos,
                                                          new Vertex(frame[0].x, frame[0].y)) > MAXTAPDISTANCE) //to much moving while tapping
                    {
                        return(-1);
                    }
                    if (tapedPos[0] < 0.0)
                    {
                        tapedPos = new Vertex(frame[0].x, frame[0].y); //first tap contact is tap position
                    }
                }
                else //frame without blobs -> touch left surface
                {
                    if (frameCounter != 0 && frameCounter != frameList.Length - 1)
                    {
                        taps++;
                    }
                }
                ++frameCounter;
            }
            return(taps);
        }
コード例 #5
0
        private IClassificationResult RecognizeBlurryLineGesture(TrackedGesture inputData)
        {
            if (!CheckTokenCriterion(inputData.FrameList, 1))
            {
                return(null);
            }

            Vertex startPoint, endPoint;
            int    startPointIndex = FindFirstFrameIndexWithCorrectCount(inputData.FrameList, 1, true);
            int    endPointIndex   = FindFirstFrameIndexWithCorrectCount(inputData.FrameList, 1, false);

            Touch t = inputData.FrameList[startPointIndex][0];

            startPoint = new Vertex(t.x, t.y);

            int maxDistantBlobFrameIndex;
            //search endpoint es point with max distance from start point
            //accounts for misleading data and offers robust identification of lines with disadvantage of
            //more wrong positive classifications
            int maxDistantBlobIndex = GetBlobMaxDistantFromPointIndex(inputData.FrameList, startPoint, out maxDistantBlobFrameIndex);

            if (startPointIndex == -1 || endPointIndex == -1 ||
                startPointIndex == endPointIndex || maxDistantBlobFrameIndex == -1)
            {
                return(null);
            }


            t        = inputData.FrameList[endPointIndex][0];
            endPoint = new Vertex(t.x, t.y);


            IClassificationResult result = null;

            if (CheckMaxDistanceFromLineKriterion(inputData.FrameList, startPoint, endPoint, MAXDISTFROMLINE) &&
                MetricDistances.EuclideanDistance(startPoint, endPoint) > MINLINELENGTH)
            {
                //return RecognizeDirectionalLine(startPoint, endPoint);
                result = new ClassificationResult("line", 100.0, new Sample[] { new Sample(DateTime.Now, startPoint), new Sample(DateTime.Now, endPoint) },
                                                  new KeyValuePair <String, double>("angle", GetAngle(startPoint, endPoint)));
            }
            return(result);
        }
コード例 #6
0
        /// <summary>
        /// Checks for tap gestures.
        /// </summary>
        /// <param className="inputData">The input data .</param>
        /// <returns>Number of Taps detected, -1 if no tap gesture could be recognized.</returns>F:\Material\Gesture_Source\Gesten\Classifiers\DTWClassifier.cs
        private int CheckForTapGestures2(TrackedGesture inputData, ref Vertex tapedPos)
        {
            tapedPos[0] = -1;
            if (inputData == null || inputData.Count == 0)
            {
                return(-1);
            }
            var frameList       = inputData.FrameList;
            int framesWithBlobs = 0;
            int taps            = 1;

            foreach (var frame in frameList)
            {
                if (frame.Count > 1)
                {
                    return(-1);
                }
                if (frame.Count == 1)
                {
                    framesWithBlobs++;
                    if (!(frame[0].DimX < maxTapDistance && frame[0].DimY < maxTapDistance)) //to big blobs
                    {
                        return(-1);
                    }
                    if (tapedPos[0] != -1.0 &&
                        MetricDistances.EuclideanDistance(tapedPos,
                                                          new Vertex(frame[0].X, frame[0].Y)) > maxTapDistance) //to much moving while tapping
                    {
                        return(-1);
                    }
                    if (tapedPos[0] < 0.0)
                    {
                        tapedPos = new Vertex(frame[0].X, frame[0].Y); //first tap contact is tap position
                    }
                }
                else //frame without blobs -> touch left surface
                {
                    taps++;
                }
            }
            return(taps);
        }
コード例 #7
0
        public IClassificationResult FinishEvaluation()
        {
            TrackedGesture        trackedGesture       = blobTracker.TrackedBlobs;
            IClassificationResult classificationResult = null;

            RecognitionMode = false;

            foreach (IClassify classifier in classifiers)
            {
                classificationResult = classifier.Classify(trackedGesture);
                if (classificationResult != null)
                {
                    blobTracker.InitiateTracking();
                    return(classificationResult);
                }
            }

            blobTracker.InitiateTracking();
            return(classificationResult);
        }
コード例 #8
0
        /// <summary>
        /// Classifies the specified gesture.
        /// </summary>
        /// <param name="gesture">The gesture.</param>
        /// <returns></returns>
        public IClassificationResult Classify(TrackedGesture gesture)
        {
            int    result;
            Vertex tappedPos = new Vertex();

            if (gesture.Count == 0)
            {
                return(null);
            }
            //if (gesture.Count == 1)
            { result = CheckForTapGestures(gesture, ref tappedPos); }

            //else { result = CheckForTapGesturesMT(gesture, ref tapedPos); }
            if (result == -1)
            {
                return(null);
            }

            String resultString = "tap";

            return(new ClassificationResult(resultString, 100.0, new Sample[] { new Sample(DateTime.Now, tappedPos) },
                                            new KeyValuePair <String, double>("taps", result)));
        }
コード例 #9
0
        private IClassificationResult RecognizeBlurryPinchGesture(TrackedGesture inputData)
        {
            double maxTapDistance = 2;
            double startDist = double.MinValue,
                   endDist = double.MinValue;
            Sample startNode1 = new Sample(), startNode2 = new Sample();
            bool   semi1 = true;
            bool   semi2 = true;
            //check for min blob relation
            int equalToX = 0, lessThanX = 0, moreThanX = 0;
            int i = 0;

            while (i < inputData.FrameList.Length)
            {
                if (inputData.FrameList[i].Count == 2)
                {
                    equalToX++;
                    //store the first two blobs occurring together as start blobs for the pinch gesture
                    if (startDist < 0.0)
                    {
                        //if more than 1/3 of the frames belongs to single line movement, than it is no pinch anymore
                        if (i <= inputData.FrameList.Length / 3)
                        {
                            //first fingers start contact for the pinch
                            startNode1 = new Sample(
                                inputData.FrameList[i].TimeStamp,
                                inputData.FrameList[i][0].x,
                                inputData.FrameList[i][0].y);
                            //second fingers start contact for the pinch
                            startNode2 = new Sample(
                                inputData.FrameList[i].TimeStamp,
                                inputData.FrameList[i][1].x,
                                inputData.FrameList[i][1].y);
                            //pinching fingers distance at the beginning
                            startDist =
                                MetricDistances.EuclideanDistance(startNode1, startNode2);
                        }
                    }
                    //check for a steady first finger (blobs stay close to first contact of one finger)
                    semi1 = semi1 &&
                            (
                        (Math.Abs(startNode1[0] - inputData.FrameList[i][0].x) < maxTapDistance
                         &&
                         Math.Abs(startNode1[1] - inputData.FrameList[i][0].y) < maxTapDistance
                        )
                        ||
                        (Math.Abs(startNode1[0] - inputData.FrameList[i][1].x) < maxTapDistance
                         &&
                         Math.Abs(startNode1[1] - inputData.FrameList[i][1].y) < maxTapDistance
                        )
                            );
                    //check for a steady second finger (blobs stay close to first contact of one finger)
                    semi2 = semi2 &&
                            (
                        (Math.Abs(startNode2[0] - inputData.FrameList[i][0].x) < maxTapDistance
                         &&
                         Math.Abs(startNode2[1] - inputData.FrameList[i][0].y) < maxTapDistance
                        )
                        ||
                        (Math.Abs(startNode2[0] - inputData.FrameList[i][1].x) < maxTapDistance
                         &&
                         Math.Abs(startNode2[1] - inputData.FrameList[i][1].y) < maxTapDistance
                        )
                            );
                }
                else
                {
                    //count cases of more or less than two blobs in one frame
                    //can be caused by performing another gesture, flickering or touch unsensitive modules
                    if (inputData.FrameList[i].Count > 2)
                    {
                        moreThanX++;
                    }
                    else
                    {
                        lessThanX++;
                    }
                }
                i++;
            }

            //if there are to many frames with less or more than two blobs, reject pinch gesture assumption
            if ((double)equalToX / (lessThanX + moreThanX) < MINBLOBRELATION)
            {
                return(null);
            }


            //get last frame with two blobs for finding end positions of both fingers
            i = inputData.FrameList.Length - 1;
            while (endDist < 0.0 && i >= 0)
            {
                //check if last frame with two fingers contact is within last third of frame-range
                //if more than 1/3 of the frames belongs to single line movement, than it is no pinch anymore
                if (i >= inputData.FrameList.Length * 2 / 3 && inputData.FrameList[i].Count == 2)
                {
                    IVertex endPoint1 = new Vertex(inputData.FrameList[i][0].x, inputData.FrameList[i][0].y);
                    IVertex endPoint2 = new Vertex(inputData.FrameList[i][1].x, inputData.FrameList[i][1].y);
                    endDist = MetricDistances.EuclideanDistance(endPoint1, endPoint2);

                    if (startDist > endDist)
                    {
                        endPoint1 = startNode1;
                        endPoint2 = startNode2;
                    }

                    //if to much scattering of blobs along a given line between the outmost two fingers contact, reject pinch gesture assumption
                    if (!CheckMaxDistanceFromLineKriterion(inputData.FrameList, endPoint1, endPoint2, MAXDISTFROMLINE))
                    {
                        return(null);
                    }
                }
                i--;
            }
            //get direction out of change of start to end distances between the two fingers contacts
            bool direction = startDist > endDist; //pinch or reverse pinch

//            GestureToken token = ConnectTokens(inputData);
//          if (!CheckMaxDistanceFromLineKriterion(token, 2 * MAXDISTFROMLINE)) { return null; }

            bool pinch = startDist > 0.0 && endDist > 0.0 &&
                         ((direction ? (startDist / endDist) : endDist / startDist) > 0.5);

            return(!pinch ? null :
                   new ClassificationResult(
                       (semi2 || semi1) ? "one finger pinch" : "pinch",
                       1.0, new Sample[] {
                semi1?startNode1: (semi2 ? startNode2 :
                                   new Sample(startNode2.TimeStamp,
                                              (startNode1[0] + startNode2[0]) / 2,
                                              (startNode1[1] + startNode2[1]) / 2))
            },
                       new KeyValuePair <String, double>("expanding",
                                                         (direction) ? -1.0 : 1.0)));
        }