Beispiel #1
0
 public BoponotoClassifier(int n, double size, SketchPoint point, Dictionary <string, Sketch> templates)
 {
     this.N         = n;
     this.Size      = size;
     this.Origin    = point;
     this.Templates = templates;
 }
Beispiel #2
0
        public bool Contains(SketchPoint point)
        {
            double x = point.X;
            double y = point.Y;

            return(x < MaxX && x > MinX && y < MaxX && y > MinY);
        }
Beispiel #3
0
        private static bool IsLine(SketchStroke stroke, int i1, int i2)
        {
            SketchPoint p1 = stroke.Points[i1];
            SketchPoint p2 = stroke.Points[i2];

            return(MathHelpers.EuclideanDistance(p1, p2) / SketchStrokeFeatureExtraction.PathLength(stroke, i1, i2) > LineValidationThreshold);
        }
Beispiel #4
0
        public static SketchPoint Intersection(SketchStroke sketchStroke1, SketchStroke sketchStroke2)
        {
            double minDistance  = double.MaxValue;
            int    minDisIndex1 = 0;
            int    minDisIndex2 = 0;

            List <SketchPoint> points1 = sketchStroke1.Points;
            List <SketchPoint> points2 = sketchStroke2.Points;

            for (int i = 0; i < points1.Count; i++)
            {
                SketchPoint point1 = points1[i];

                for (int j = 0; j < points2.Count; j++)
                {
                    SketchPoint point2 = points2[j];

                    double distance = MathHelpers.EuclideanDistance(point1, point2);

                    if (distance < minDistance)
                    {
                        minDistance  = distance;
                        minDisIndex1 = i;
                        minDisIndex2 = j;
                    }
                }
            }

            if (minDistance > 30)
            {
                return(null);
            }

            return(new SketchPoint((points1[minDisIndex1].X + points2[minDisIndex2].X) / 2.0, (points1[minDisIndex1].Y + points2[minDisIndex2].Y) / 2.0));
        }
        public static List <SketchStroke> ScaleToFrame(Sketch sketch, double frameLength)
        {
            List <SketchStroke> result = new List <SketchStroke>();

            double templateFrameWidth  = sketch.FrameMaxX - sketch.FrameMinX;
            double templateFrameHeight = sketch.FrameMaxY - sketch.FrameMinY;

            foreach (SketchStroke origStroke in sketch.Strokes)
            {
                List <SketchPoint> origPoints   = origStroke.Points;
                List <SketchPoint> scaledPoints = new List <SketchPoint>();

                foreach (SketchPoint origPoint in origPoints)
                {
                    double      scaledX     = origPoint.X / templateFrameWidth * frameLength;
                    double      scaledY     = origPoint.Y / templateFrameHeight * frameLength;
                    SketchPoint scaledPoint = new SketchPoint(scaledX, scaledY);
                    scaledPoints.Add(scaledPoint);
                }

                SketchStroke scaledStroke = new SketchStroke(scaledPoints, origStroke.TimeStamp);
                result.Add(scaledStroke);
            }

            return(result);
        }
Beispiel #6
0
        public static SketchStroke ResampleStroke(SketchStroke stroke, int n)
        {
            SketchStroke resampledStroke = new SketchStroke();

            List <SketchPoint> points    = new List <SketchPoint>();
            List <long>        timeStamp = new List <long>();

            // Copies the points and timeStamps list of the initial stroke
            foreach (SketchPoint p in stroke.Points)
            {
                points.Add(p);
            }
            foreach (long t in stroke.TimeStamp)
            {
                timeStamp.Add(t);
            }

            double totalLength = SketchStrokeFeatureExtraction.PathLength(stroke);
            double increment   = totalLength / (n - 1);
            double dist        = 0;

            resampledStroke.AppendPoint(points[0]);

            for (int i = 1; i < points.Count; i++)
            {
                SketchPoint cur = points[i];
                SketchPoint pre = points[i - 1];

                double d = MathHelpers.EuclideanDistance(cur, pre);

                if (dist + d >= increment)
                {
                    double qx = pre.X + ((increment - dist) / d) * (cur.X - pre.X);
                    double qy = pre.Y + ((increment - dist) / d) * (cur.Y - pre.Y);

                    SketchPoint q = new SketchPoint(qx, qy);

                    resampledStroke.AppendPoint(q);
                    points.Insert(i, q);

                    dist = 0.0;
                }
                else
                {
                    dist = dist + d;
                }
            }

            int oldTimeCount = timeStamp.Count;
            int newTimeCount = resampledStroke.Points.Count;

            for (int j = 0; j < newTimeCount; ++j)
            {
                int index = (int)((double)j / newTimeCount * oldTimeCount);
                resampledStroke.AppendTime(timeStamp[index]);
            }

            return(resampledStroke);
        }
Beispiel #7
0
        private void StrokeIntersectionPlayButton_Click(object sender, RoutedEventArgs e)
        {
            if (!this.techAssessor.IsCorrectStrokeCount)
            {
                return;
            }

            this.AnimationCanvas.Children.Clear();

            int[] correspondance = this.techAssessor.StrokeToStrokeCorrespondenceSameCount;
            string[,] sampleIntersections   = this.techAssessor.SampleIntersectionMatrix;
            string[,] templateIntersections = this.techAssessor.TemplateIntersectionMatrix;

            for (int i = 0; i < sampleIntersections.GetLength(0); i++)
            {
                for (int j = 0; j < sampleIntersections.GetLength(0); j++)
                {
                    if (i == j)
                    {
                        continue;
                    }

                    if (sampleIntersections[i, j] != templateIntersections[i, j])
                    {
                        int realI = 0;
                        int realJ = 0;

                        for (int index = 0; index < correspondance.GetLength(0); index++)
                        {
                            if (correspondance[index] == i)
                            {
                                realI = index;
                            }
                            if (correspondance[index] == j)
                            {
                                realJ = index;
                            }
                        }

                        SketchPoint intersection = SketchStrokeFeatureExtraction.Intersection(this.sketchStrokes[realI], this.sketchStrokes[realJ]);
                        if (intersection != null)
                        {
                            InteractionTools.HighlightWrongIntersection(this.AnimationCanvas, intersection);
                        }
                        else
                        {
                            InteractionTools.HighlightStrokes(this.AnimationCanvas, this.WritingInkCanvas, realI, realJ);
                        }
                    }
                }
            }
        }
Beispiel #8
0
        public static double TrioDistance(SketchStroke strokeA, SketchStroke strokeB)
        {
            SketchPoint startA = strokeA.StartPoint;
            SketchPoint startB = strokeB.StartPoint;
            SketchPoint midA   = strokeA.MidPoint;
            SketchPoint midB   = strokeB.MidPoint;
            SketchPoint endA   = strokeA.EndPoint;
            SketchPoint endB   = strokeB.EndPoint;

            return(MathHelpers.EuclideanDistance(startA, startB) +
                   MathHelpers.EuclideanDistance(midA, midB) +
                   MathHelpers.EuclideanDistance(endA, endB));
        }
        public static void HighlightWrongIntersection(Canvas animationCanvas, SketchPoint intersection)
        {
            Ellipse circle = new Ellipse()
            {
                Height          = 50,
                Width           = 50,
                Stroke          = new SolidColorBrush(Colors.Red),
                StrokeThickness = 10,
            };

            Canvas.SetLeft(circle, intersection.X - circle.Width / 2);
            Canvas.SetTop(circle, intersection.Y - circle.Height / 2);

            animationCanvas.Children.Add(circle);
        }
        public static List <SketchStroke> Translate(List <SketchStroke> strokes, SketchPoint origin, SketchPoint centroid)
        {
            List <SketchStroke> newStrokes = new List <SketchStroke>();

            foreach (SketchStroke stroke in strokes)
            {
                List <SketchPoint> newPoints = new List <SketchPoint>();
                foreach (SketchPoint point in stroke.Points)
                {
                    newPoints.Add(new SketchPoint(point.X + origin.X - centroid.X, point.Y + origin.Y - centroid.Y));
                }
                SketchStroke newStroke = new SketchStroke(newPoints, stroke.TimeStamp);
                newStrokes.Add(newStroke);
            }

            return(newStrokes);
        }
Beispiel #11
0
        public static string IntersectionRelationship(SketchStroke sketchStroke1, SketchStroke sketchStroke2)
        {
            SketchPoint closestPoint = Intersection(sketchStroke1, sketchStroke2);

            if (closestPoint == null)
            {
                return("none");
            }
            if (MathHelpers.EuclideanDistance(closestPoint, sketchStroke1.StartPoint) < 40)
            {
                return("touch head");
            }
            if (MathHelpers.EuclideanDistance(closestPoint, sketchStroke1.EndPoint) < 40)
            {
                return("touch tail");
            }
            return("cross");
        }
Beispiel #12
0
        public static double Distance(List <SketchPoint> alphaPoints, List <SketchPoint> betaPoints)
        {
            double distances = 0.0;

            var pairs = new List <Tuple <SketchPoint, SketchPoint> >();

            double minDistance, weight, distance;
            int    index;

            SketchPoint minPoint = betaPoints[0];

            foreach (SketchPoint alphaPoint in alphaPoints)
            {
                minDistance = Double.MaxValue;

                // iterate through each beta point to find the min beta point to the alpha point
                index = 1;

                foreach (SketchPoint betaPoint in betaPoints)
                {
                    distance = MathHelpers.EuclideanDistance(alphaPoint, betaPoint);

                    // update the min distance and min point
                    if (minDistance > distance)
                    {
                        minDistance = distance;
                        minPoint    = betaPoint;
                    }
                }

                // update distance between alpha and beta point lists
                weight     = 1 - ((index - 1) / alphaPoints.Count);
                distances += minDistance * weight;

                // pair the alpha point to the min beta point and remove min beta point from list of beta points
                pairs.Add(new Tuple <SketchPoint, SketchPoint>(alphaPoint, minPoint));
                betaPoints.Remove(minPoint);
            }

            return(distances);
        }
Beispiel #13
0
        public static double StartToEndSlope(SketchStroke stroke)
        {
            SketchPoint start = stroke.StartPoint;
            SketchPoint end   = stroke.EndPoint;

            if (start.X == end.X)
            {
                if (end.Y >= start.Y)
                {
                    return(double.PositiveInfinity);
                }
                else
                {
                    return(double.NegativeInfinity);
                }
            }
            else
            {
                return((end.Y - start.Y) / (end.X - start.X));
            }
        }
Beispiel #14
0
        public static async Task <Sketch> XMLToSketch(StorageFile file)
        {
            string text = await FileIO.ReadTextAsync(file);

            XDocument document = XDocument.Parse(text);

            int    minX  = Int32.Parse(document.Root.Attribute("frameMinX").Value);
            int    maxX  = Int32.Parse(document.Root.Attribute("frameMaxX").Value);
            int    minY  = Int32.Parse(document.Root.Attribute("frameMinY").Value);
            int    maxY  = Int32.Parse(document.Root.Attribute("frameMaxY").Value);
            string label = document.Root.Attribute("label").Value;
            List <SketchStroke> strokes = new List <SketchStroke>();

            // Itereates through each stroke element
            foreach (XElement element in document.Root.Elements())
            {
                // Initializes the stroke
                SketchStroke stroke = new SketchStroke();

                // Iterates through each point element
                double x, y;
                long   t;

                foreach (XElement pointElement in element.Elements())
                {
                    x = Double.Parse(pointElement.Attribute("x").Value);
                    y = Double.Parse(pointElement.Attribute("y").Value);
                    t = Int64.Parse(pointElement.Attribute("time").Value);

                    SketchPoint point = new SketchPoint(x, y);

                    stroke.AppendPoint(point);
                    stroke.AppendTime(t);
                }

                strokes.Add(stroke);
            }

            return(new Sketch(minX, maxX, minY, maxY, label, strokes));
        }
 public static double EuclideanDistance(SketchPoint p1, SketchPoint p2)
 {
     return(Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2)));
 }
 public static List <SketchStroke> TranslateCentroid(List <SketchStroke> strokes, SketchPoint origin)
 {
     return(Translate(strokes, origin, SketchFeatureExtraction.Centroid(strokes)));
 }
Beispiel #17
0
 private static bool IsInsideBoard(SketchPoint point, int length)
 {
     return(IsInsideBoard((int)point.X, (int)point.Y, length));
 }
 public void AppendPoint(SketchPoint p) { this.points.Add(p); }
        public static List <SketchStroke> Normalize(List <SketchStroke> strokes, int n, double size, SketchPoint origin)
        {
            List <SketchStroke> sampleCopy = new List <SketchStroke>();

            foreach (SketchStroke orig in strokes)
            {
                sampleCopy.Add(SketchStroke.Copy(orig));
            }

            List <SketchStroke> resampled  = Resample(sampleCopy, n);
            List <SketchStroke> scaled     = ScaleSquare(resampled, size);
            List <SketchStroke> translated = TranslateCentroid(scaled, origin);

            return(translated);
        }
Beispiel #20
0
        public static async void SketchToXml(StorageFile file, string label, string userName, string userMotherLanguage, string userFluency, double frameMinX, double frameMinY, double frameMaxX, double frameMaxY, List <SketchStroke> strokes)
        {
            // create the string writer as the streaming source of the XML data
            string output = "";

            using (StringWriter stringWriter = new StringWriter())
            {
                // set the string writer as the streaming source for the XML writer
                using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter))
                {
                    // <xml>
                    xmlWriter.WriteStartDocument();

                    // <sketch>
                    xmlWriter.WriteStartElement("sketch");
                    xmlWriter.WriteAttributeString("label", label);
                    xmlWriter.WriteAttributeString("name", userName);
                    xmlWriter.WriteAttributeString("motherlanguage", userMotherLanguage);
                    xmlWriter.WriteAttributeString("fluency", userFluency);
                    xmlWriter.WriteAttributeString("frameMinX", "" + frameMinX);
                    xmlWriter.WriteAttributeString("frameMinY", "" + frameMinY);
                    xmlWriter.WriteAttributeString("frameMaxX", "" + frameMaxX);
                    xmlWriter.WriteAttributeString("frameMaxY", "" + frameMaxY);

                    // iterate through each stroke
                    for (int i = 0; i < strokes.Count; i++)
                    {
                        // <stroke>
                        xmlWriter.WriteStartElement("stroke");

                        // get the current stroke's points and times
                        List <SketchPoint> points = strokes[i].Points;
                        List <long>        times  = strokes[i].TimeStamp;

                        //
                        for (int j = 0; j < points.Count; ++j)
                        {
                            SketchPoint point = points[j];
                            long        time  = times[j]; // TODO: FIX!

                            // <point>
                            xmlWriter.WriteStartElement("point");

                            xmlWriter.WriteAttributeString("x", "" + point.X);
                            xmlWriter.WriteAttributeString("y", "" + point.Y);
                            xmlWriter.WriteAttributeString("time", "" + times[j]);

                            // </point>
                            xmlWriter.WriteEndElement();
                        }

                        // </stroke>
                        xmlWriter.WriteEndElement();
                    }

                    // </sketch>
                    xmlWriter.WriteEndElement();

                    // </xml>
                    xmlWriter.WriteEndDocument();
                }

                output = stringWriter.ToString();
            }

            await FileIO.WriteTextAsync(file, output);
        }
Beispiel #21
0
        public VisionAssessor(List <SketchStroke> sample, int sampleFrameLength, List <SketchStroke> template, int templateFrameLength)
        {
            bool[,] sampleArray   = VisionFeatureExtraction.SketchToArray(sample, sampleFrameLength);
            bool[,] templateArray = VisionFeatureExtraction.SketchToArray(template, templateFrameLength);

            bool[,] sampleArrayScaled   = VisionFeatureExtraction.Scale(sampleArray, ScaledFrameSize);
            bool[,] templateArrayScaled = VisionFeatureExtraction.Scale(templateArray, ScaledFrameSize);

            SketchPoint sampleCentroid   = VisionFeatureExtraction.Centroid(sampleArrayScaled);
            SketchPoint templateCentroid = VisionFeatureExtraction.Centroid(templateArrayScaled);

            BoundingBox sampleBoundingBox   = VisionFeatureExtraction.BoundingRectangle(sampleArrayScaled);
            BoundingBox templateBoundingBox = VisionFeatureExtraction.BoundingRectangle(templateArrayScaled);

            double sampleHeight   = sampleBoundingBox.Height;
            double templateHeight = templateBoundingBox.Height;
            double sampleWidth    = sampleBoundingBox.Width;
            double templateWidth  = templateBoundingBox.Width;

            int[] sampleProjectionX   = VisionFeatureExtraction.VerticalProjection(sampleArrayScaled);
            int[] sampleProjectionY   = VisionFeatureExtraction.HorizontalProjection(sampleArrayScaled);
            int[] templateProjectionX = VisionFeatureExtraction.VerticalProjection(templateArrayScaled);
            int[] templateProjectionY = VisionFeatureExtraction.HorizontalProjection(templateArrayScaled);

            double fc = Math.Sqrt(Math.Pow(sampleCentroid.X - templateCentroid.X, 2) + Math.Pow(sampleCentroid.Y - templateCentroid.Y, 2)) / (0.5 * sampleArrayScaled.GetLength(1));
            double fa = (sampleWidth * sampleHeight - templateWidth * templateHeight) / (templateWidth * templateHeight);
            double fr = (sampleWidth / sampleHeight - templateWidth / templateHeight);
            double dx = VisionFeatureExtraction.ProjectionDifference(sampleProjectionX, templateProjectionX);
            double dy = VisionFeatureExtraction.ProjectionDifference(sampleProjectionY, templateProjectionY);
            double fs = VisionFeatureExtraction.SymmetryFeature(sampleProjectionX, templateProjectionX);

            double muonNear           = Fuzzy.Gamma(fc, 0.1, 0.9);
            double muonFar            = Fuzzy.Lambda(fc, 0.1, 0.9);
            double muonSmall          = Fuzzy.Gamma(fa, -1, 0);
            double muonProperSize     = Fuzzy.Delta(fa, -0.4, 0, 0.4);
            double muonLarge          = Fuzzy.Lambda(fa, 0, 1);
            double muonTall           = Fuzzy.Gamma(fr, -0.5, 0);
            double muonProperRatio    = Fuzzy.Delta(fr, -0.166667, 0, 0.166667);
            double muonShort          = Fuzzy.Lambda(fr, 0, 0.5);
            double muonLessX          = Fuzzy.Gamma(dx, 0.1, 0.9);
            double muonMuchX          = Fuzzy.Lambda(dx, 0.1, 0.9);
            double muonLessY          = Fuzzy.Gamma(dy, 0.1, 0.9);
            double muonMuchY          = Fuzzy.Lambda(dy, 0.1, 0.9);
            double muonLeft           = Fuzzy.Gamma(fs, -1, 0);
            double muonProperSymmetry = Fuzzy.Delta(fs, -0.4, 0, 0.4);
            double muonRight          = Fuzzy.Lambda(fs, 0, 1);

            double sc = muonNear > muonFar?Fuzzy.CenterOfAreaHigh(0.1, 0.9, muonNear) : Fuzzy.CenterOfAreaLow(0.1, 0.9, muonFar);

            double sa  = muonProperSize > Math.Max(muonSmall, muonLarge) ? Fuzzy.CenterOfAreaHigh(0.6, 0.9, muonProperSize) : Fuzzy.CenterOfAreaLow(0.1, 0.9, Math.Max(muonSmall, muonLarge));
            double sr  = muonProperRatio > Math.Max(muonTall, muonShort) ? Fuzzy.CenterOfAreaHigh(0.8, 0.9, muonProperRatio) : Fuzzy.CenterOfAreaLow(0.5, 0.9, Math.Max(muonTall, muonShort));
            double sdx = muonLessX > muonMuchX?Fuzzy.CenterOfAreaHigh(0.1, 0.9, muonLessX) : Fuzzy.CenterOfAreaLow(0.1, 0.9, muonMuchX);

            double sdy = muonLessY > muonMuchY?Fuzzy.CenterOfAreaHigh(0.1, 0.9, muonMuchY) : Fuzzy.CenterOfAreaLow(0.1, 0.9, muonMuchY);

            double ss = muonProperSymmetry > Math.Max(muonLeft, muonRight) ? Fuzzy.CenterOfAreaHigh(0.6, 0.9, muonProperSymmetry) : Fuzzy.CenterOfAreaLow(0.1, 0.9, Math.Max(muonLeft, muonRight));

            double s1 = sc;
            double s2 = (sa + sr) / 2.0;
            double s3 = (sdx + sdy) / 2.0;

            double muonLocationVeryLow    = Fuzzy.Gamma(s1, 0.3, 0.4);
            double muonLocationLow        = Fuzzy.Delta(s1, 0.3, 0.4, 0.5);
            double muonLocationAverage    = Fuzzy.Delta(s1, 0.4, 0.5, 0.6);
            double muonLocationHigh       = Fuzzy.Delta(s1, 0.5, 0.6, 0.7);
            double muonLocationVeryHigh   = Fuzzy.Lambda(s1, 0.6, 0.7);
            double muonShapeVeryLow       = Fuzzy.Gamma(s2, 0.3, 0.4);
            double muonShapeLow           = Fuzzy.Delta(s2, 0.3, 0.4, 0.5);
            double muonShapeAverage       = Fuzzy.Delta(s2, 0.4, 0.5, 0.6);
            double muonShapeHigh          = Fuzzy.Delta(s2, 0.5, 0.6, 0.7);
            double muonShapeVeryHigh      = Fuzzy.Lambda(s2, 0.6, 0.7);
            double muonProjectionVeryLow  = Fuzzy.Gamma(s2, 0.3, 0.4);
            double muonProjectionLow      = Fuzzy.Delta(s2, 0.3, 0.4, 0.5);
            double muonProjectionAverage  = Fuzzy.Delta(s2, 0.4, 0.5, 0.6);
            double muonProjectionHigh     = Fuzzy.Delta(s2, 0.5, 0.6, 0.7);
            double muonProjectionVeryHigh = Fuzzy.Lambda(s2, 0.6, 0.7);

            LocationFeedback   = getFeedback(muonLocationVeryLow, muonLocationLow, muonLocationAverage, muonLocationHigh, muonLocationVeryHigh);
            ShapeFeedback      = getFeedback(muonShapeVeryLow, muonShapeLow, muonShapeAverage, muonShapeHigh, muonShapeVeryHigh);
            ProjectionFeedback = getFeedback(muonProjectionVeryLow, muonProjectionLow, muonProjectionAverage, muonProjectionHigh, muonProjectionVeryHigh);
        }