Exemplo n.º 1
0
        // Originally overloaded operator ()
        public void ProcessFrame(
            Vector pt,
            int frame_no,
            List <ContinuousResult> results
            )
        {
            if (lastFrameNo == -1)
            {
                last_pt = pt;
            }

            // Update Circular Buffer
            while (lastFrameNo < frame_no)
            {
                buffer.Insert(pt);
                lastFrameNo++;
            }

            Vector vec            = pt - last_pt;
            double segment_length = vec.L2Norm();

            if (device_type == DeviceType.MOUSE && segment_length < 10.0)
            {
                return;
            }

            last_pt = pt;

            if (segment_length <= double.Epsilon)
            {
                return;
            }

            vec /= segment_length;

            for (int ii = 0; ii < templates.Count; ii++)
            {
                templates[ii].Update(
                    buffer,
                    pt,
                    vec,
                    frame_no,
                    segment_length
                    );

                results.Add(templates[ii].result);
            }
        }
Exemplo n.º 2
0
        private static void DouglasPeuckerRDensity(
            List <Vector> points,
            List <Tuple <int, double> > splits,
            int start,
            int end,
            double threshold
            )
        {
            // base case
            if (start + 1 > end)
            {
                return;
            }

            Vector AB    = points[end] - points[start];
            double denom = AB.Dot(AB);

            double largest  = Double.NegativeInfinity;
            int    selected = -1;

            for (int ii = start + 1;
                 ii < end;
                 ii++)
            {
                Vector AC    = points[ii] - points[start];
                double numer = AC.Dot(AB);
                double d2    = AC.Dot(AC) - numer * numer / denom;

                if (denom == 0.0)
                {
                    d2 = AC.L2Norm();
                }

                Vector v1 = points[ii] - points[start];
                Vector v2 = points[end] - points[ii];

                double l1 = v1.L2Norm();
                double l2 = v2.L2Norm();

                double dot = v1.Dot(v2);
                // Protect against zero length vector
                dot /= (l1 * l2 > 0) ? (l1 * l2) : 1.0;
                dot  = Math.Max(-1.0, Math.Min(1.0, dot));
                double angle = Math.Acos(dot);
                d2 *= angle / Math.PI;

                if (d2 > largest)
                {
                    largest  = d2;
                    selected = ii;
                }
            }

            if (selected == -1)
            {
                //Debug.Log("DouglasPeuckerR: nothing selected");
                //Debug.Log(String.Format("start {0}, end {1}", start, end));
                // something went wrong: FIXME how do I exit?
            }

            largest = Math.Max(0.0, largest);
            largest = Math.Sqrt(largest);

            if (largest < threshold)
            {
                return;
            }

            DouglasPeuckerRDensity(
                points,
                splits,
                start,
                selected,
                threshold
                );

            DouglasPeuckerRDensity(
                points,
                splits,
                selected,
                end,
                threshold
                );

            splits[selected].Second = largest;
        }
Exemplo n.º 3
0
        public void Prepare(DeviceType deviceType,
                            List <Vector> resampled,
                            bool filtered = true)
        {
            List <Vector> rotated;
            List <Vector> dpPoints;

            this.device_id = deviceType;

            if (filtered == true)
            {
                rotated = sample.FilteredTrajectory;
            }
            else
            {
                rotated = sample.Trajectory;
            }

            // Remove duplicate points
            resampled.Add(rotated[0]);

            for (int ii = 1; ii < rotated.Count; ii++)
            {
                int    count  = resampled.Count - 1;
                double length = resampled[count].L2Norm(rotated[ii]);

                if (length <= Double.Epsilon)
                {
                    continue;
                }

                resampled.Add(rotated[ii]);
            }

            /*
             * Determine Threshold
             */
            sampleCount = resampled.Count;

            Mathematics.BoundingBox(resampled, out Vector minimum, out Vector maximum);

            double diag = maximum.L2Norm(minimum);

            /*
             * Resample the input using DP
             */
            Mathematics.DouglasPeuckerDensity(resampled, out dpPoints, diag * 0.010f);

            /*
             * Heuristically dehook the trajectory
             */
            if (deviceType == DeviceType.MOUSE)
            {
                int    ptCnt = dpPoints.Count;
                Vector v1    = dpPoints[1] - dpPoints[0];
                Vector v2    = dpPoints[2] - dpPoints[1];
                double ratio = v1.L2Norm() / v2.L2Norm();

                if (ratio < .2)
                {
                    dpPoints.RemoveAt(0);
                    ptCnt--;
                }

                v1 = dpPoints[ptCnt - 2] - dpPoints[ptCnt - 3];
                v2 = dpPoints[ptCnt - 1] - dpPoints[ptCnt - 2];

                ratio = v2.L2Norm() / v1.L2Norm();

                if (ratio < .2)
                {
                    dpPoints.RemoveAt(dpPoints.Count - 1);
                    ptCnt--;
                }
            }

            points = dpPoints;

            // Convert DP resampled points into vectors
            Mathematics.Vectorize(points, out vectors, true);

            // Determine correction factor information
            f2l_Vector = points[points.Count - 1] - points[0];
            double f2l_length = f2l_Vector.L2Norm();

            closedness  = f2l_length;
            closedness /= Mathematics.PathLength(resampled);
            f2l_Vector.Normalize();

            weightClosedness = (1.0f - f2l_length / diag);
            weightF2l        = Math.Min(1.0f, 2.0f * f2l_length / diag);
        }
Exemplo n.º 4
0
        public void Update(
            CircularBuffer <Vector> buffer,
            Vector pt,
            Vector nvec,
            int frameNo,
            double length
            )
        {
            // Cache current row as prev
            List <MacheteElement> previous = dtw[currentIndex];

            // Update Circular Buffer Index
            currentIndex++;
            currentIndex %= 2;

            // Cache reference to current row
            List <MacheteElement> current = dtw[currentIndex];

            // Update frame number
            current[0].startFrameNo = frameNo;

            for (int col = 1; col <= vectorCount; col++)
            {
                double dot  = nvec.Dot(vectors[col - 1]);
                double cost = 1.0 - Math.Max(-1.0, Math.Min(1.0, dot));
                cost = cost * cost;

                // Pick the lowest cost neightbor to
                // extent it's warping path through
                // this (frame_no, col) element.
                MacheteElement n1 = current[col - 1];
                MacheteElement n2 = previous[col - 1];
                MacheteElement n3 = previous[col];

                MacheteElement extend  = n1;
                double         minimum = n1.GetNormalizedWarpingPathCost();

                if (n2.GetNormalizedWarpingPathCost() < minimum)
                {
                    extend  = n2;
                    minimum = n2.GetNormalizedWarpingPathCost();
                }

                if (n3.GetNormalizedWarpingPathCost() < minimum)
                {
                    extend  = n3;
                    minimum = n3.GetNormalizedWarpingPathCost();
                }

                // Update the miniumum cost warping path
                // Element to include this frame
                current[col].Update(
                    extend,
                    frameNo,
                    cost,
                    length);
            }

            MacheteElement curr = current[vectorCount];

            int    startFrameNo       = curr.startFrameNo;
            int    endFrameNo         = curr.endFrameNo;
            double durationFrameCount = endFrameNo - startFrameNo + 1;
            double cf = 1.0f;

            if (device_id == DeviceType.MOUSE)
            {
                double cf_closedness = 2.0;
                double cf_f2l        = 2.0;

                if (durationFrameCount < buffer.Count() - 1)
                {
                    // Get first to last vector
                    Vector vec         = buffer[-1] - buffer[-(int)durationFrameCount];
                    double total       = current[vectorCount].total;
                    double vlength     = vec.L2Norm();
                    double closedness1 = vlength / total;

                    vec /= vlength;

                    // Closedness
                    cf_closedness  = Math.Max(closedness1, closedness);
                    cf_closedness /= Math.Min(closedness1, closedness);
                    cf_closedness  = 1 + weightClosedness * (cf_closedness - 1.0);
                    cf_closedness  = Math.Min(2.0, cf_closedness);

                    // End direction
                    double f2l_dot = f2l_Vector.Dot(vec);
                    f2l_dot = 1.0 - Math.Max(-1.0, Math.Min(1.0, f2l_dot));
                    cf_f2l  = 1.0 + (f2l_dot / 2.0) * weightF2l;
                    cf_f2l  = Math.Min(2.0, cf_f2l);

                    cf = cf_closedness * cf_f2l;
                }
            }

            double ret = curr.GetNormalizedWarpingPathCost();

            if (durationFrameCount < minimumFrameCount)
            {
                cf *= 1000.0f;
            }

            trigger.Update(
                frameNo,
                ret,
                cf,
                curr.startFrameNo,
                curr.endFrameNo);

            double _t = trigger.GetThreshold();

            result.Update(
                ret * cf,
                _t,
                curr.startFrameNo,
                curr.endFrameNo,
                frameNo);
        }