/// <summary> /// Get the IntersectionPair objects associated with a pair of substrokes /// </summary> /// <param name="s1"></param> /// <param name="s2"></param> /// <returns></returns> private Future <IntersectionPair> getPair(Substroke s1, Substroke s2) { return(new Future <IntersectionPair>(delegate() { if (!m_Boxes.ContainsKey(s1)) { throw new Exception("IntersectionSketch.m_Boxes does not contain key s1"); } if (!m_Boxes.ContainsKey(s2)) { throw new Exception("IntersectionSketch.m_Boxes does not contain key s2"); } if (!m_Lines.ContainsKey(s1)) { throw new Exception("IntersectionSketch.m_Lines does not contain key s1"); } if (!m_Lines.ContainsKey(s2)) { throw new Exception("IntersectionSketch.m_Lines does not contain key s2"); } return new IntersectionPair(s1, s2, m_Boxes[s1], m_Boxes[s2], m_Lines[s1], m_Lines[s2]); })); }
private double computeClassificationQuality() { int totalStrokes = 0; int totalCorrect = 0; foreach (Substroke correctStroke in _original.Substrokes) { if (IGNORE_CLASSIFICATIONS.Contains(correctStroke.Classification.ToLower())) { continue; } string originalClass = correctStroke.Classification; totalStrokes++; Substroke resultStroke = _toCompare.SubstrokesL.Find(delegate(Substroke s) { return(s.GeometricEquals(correctStroke)); }); string resultClass = resultStroke.Classification; if (resultClass == originalClass) { totalCorrect++; } } return((double)totalCorrect / totalStrokes); }
public ResampleCmd(ref Sketch.Sketch sketch, ref LabelerPanel lp, ref Substroke original, int numPts) { _sketch = sketch; _lp = lp; _ss = original; _pts = numPts; }
/// <summary> /// Deletes an Ink Stroke and updates the Sketch. /// </summary> /// <param name="strokeId">The ID of the Ink Stroke to delete</param> public void DeleteInkStroke(int strokeId) { if (!ink2sketchStr.ContainsKey(strokeId)) { System.Console.WriteLine("___No Stroke to delete___"); return; //throw new Exception("No stroke to erase"); } if (!substrokeIdMap.ContainsKey(ink2sketchStr[strokeId])) { return; } Substroke sStroke = substrokeIdMap[ink2sketchStr[strokeId]]; Sketch.RemoveSubstroke(sStroke); // Update mapping ink2sketchStr.Remove(strokeId); sketchStr2ink.Remove(sStroke.XmlAttrs.Id); substrokeIdMap.Remove(sStroke.XmlAttrs.Id); if (StrokeRemoved != null) { StrokeRemoved(sStroke); } }
public SubstrokeOverlap(Substroke strokeA, Substroke strokeB) { m_StrokeA = strokeA; m_StrokeB = strokeB; ComputeAll(); }
private static List <System.Drawing.Point> GetResampledPoints(Substroke stroke, double I) { List <System.Drawing.Point> points = new List <System.Drawing.Point>(stroke.PointsAsSysPoints); List <System.Drawing.Point> newPoints = new List <System.Drawing.Point>(); double D = 0.0; double d = 0.0; newPoints.Add(points[0]); for (int i = 1; i < points.Count; i++) { d = Utilities.Compute.EuclideanDistance(points[i - 1], points[i]); if (D + d >= I) { int X = (int)(points[i - 1].X + ((I - D) / d * (points[i].X - points[i - 1].X))); int Y = (int)(points[i - 1].Y + ((I - D) / d * (points[i].Y - points[i - 1].Y))); System.Drawing.Point q = new System.Drawing.Point(X, Y); newPoints.Add(q); points.Insert(i, q); D = 0.0; } else { D = D + d; } } return(newPoints); }
public List <List <Substroke> > connectedComponents() { List <List <Substroke> > res = new List <List <Substroke> >(); Substroke[] temp = new Substroke[map.Keys.Count]; map.Keys.CopyTo(temp, 0); List <Substroke> keys = new List <Substroke>(temp); while (keys.Count > 0) { List <Substroke> cur = new List <Substroke>(); Queue <Substroke> bfs = new Queue <Substroke>(); bfs.Enqueue(keys[0]); while (bfs.Count > 0) { Substroke s = bfs.Dequeue(); cur.Add(s); keys.Remove(s); foreach (Neighbor n in map[s]) { if (!cur.Contains(n.neighbor)) { bfs.Enqueue(n.neighbor); cur.Add(n.neighbor); } } } res.Add(cur); } return(res); }
private static SortedList <double, Substroke> GetClosestStrokes(Shape shape, Dictionary <Substroke, List <SubstrokeDistance> > distances) { SortedList <double, Substroke> closest = new SortedList <double, Substroke>(); foreach (Substroke s in shape.Substrokes) { if (!distances.ContainsKey(s)) { continue; } List <SubstrokeDistance> dist = distances[s]; SortedList <double, Substroke> current = new SortedList <double, Substroke>(); foreach (SubstrokeDistance d in dist) { double min = d.Min; while (current.ContainsKey(min)) { min += double.MinValue; } if (d.StrokeA == s && !current.ContainsValue(d.StrokeB)) { current.Add(min, d.StrokeB); } else if (d.StrokeB == s && !current.ContainsValue(d.StrokeA)) { current.Add(min, d.StrokeA); } } foreach (KeyValuePair <double, Substroke> kv in current) { double min = kv.Key; Substroke stroke = kv.Value; while (closest.ContainsKey(min)) { min += double.MinValue; } if (closest.ContainsValue(stroke)) { int index = closest.IndexOfValue(stroke); List <double> keys = new List <double>(closest.Keys); double key = keys[index]; if (min < key) { closest.RemoveAt(index); closest.Add(min, stroke); } } else { closest.Add(min, stroke); } } } return(closest); }
public SubstrokeDistance(Substroke strokeA, Substroke strokeB) { m_StrokeA = strokeA; m_StrokeB = strokeB; ComputeAll(); }
/// <summary> /// Adds stroke to the pairwise feature sketch /// </summary> /// <param name="stroke"></param> public void AddStroke(Substroke stroke) { if (m_Strokes.Contains(stroke)) { return; } if (m_Stroke2Pairs.ContainsKey(stroke)) { return; } m_Stroke2Pairs.Add(stroke, new List <Future <FeatureStrokePair> >()); foreach (Substroke s in m_Strokes) { StrokePair strokePair = new StrokePair(s, stroke); Future <FeatureStrokePair> pair = createFeatureStrokePair(strokePair); m_Stroke2Pairs[stroke].Add(pair); m_Pair2FeaturePair.Add(strokePair, pair); m_AllFeaturePairs.Add(pair); m_Stroke2Pairs[s].Add(pair); } m_Strokes.Add(stroke); }
/// <summary> /// Add "strokes" connecting the middle of substrokes adjacent in the graph. /// </summary> /// <param name="sketch">sketch to modify</param> /// <param name="graph">neighborhood graph</param> private static void AddDebuggingCycles(ref Sketch.Sketch sketch, NeighborhoodMap graph) { Dictionary <Substroke, Sketch.Point> midpoints = new Dictionary <Substroke, Sketch.Point>(); foreach (Substroke s in sketch.Substrokes) { midpoints.Add(s, s.PointsL[s.PointsL.Count / 2]); } foreach (Substroke s in graph.Substrokes) { foreach (Neighbor n in graph[s]) { if (!graph.Edge(n.neighbor, s)) { continue; } Substroke sub = new Substroke(new Sketch.Point[] { midpoints[s], midpoints[n.neighbor] }, new XmlStructs.XmlShapeAttrs(true)); sub.XmlAttrs.Time = 0; sub.XmlAttrs.Name = "substroke"; sub.XmlAttrs.Type = "substroke"; Stroke str = new Stroke(sub); str.XmlAttrs.Time = 0; str.XmlAttrs.Name = "stroke"; str.XmlAttrs.Type = "stroke"; Shape xor = new Shape(new List <Substroke>(new Substroke[] { sub }), new XmlStructs.XmlShapeAttrs(true)); xor.XmlAttrs.Type = "BUBBLE"; xor.XmlAttrs.Name = "Shape"; xor.XmlAttrs.Time = 0; sketch.AddStroke(str); sketch.AddShape(xor); } } }
/// <summary> /// Constructor /// </summary> public EndPoint(Sketch.EndPoint endpoint, bool isEnd) { m_Stroke = endpoint.ParentSub; m_End = isEnd; m_Pt = endpoint; m_AttachedEndpoints = new List <EndPoint>(); }
public override void run(Sketch.Sketch sketch, string filename) { FeatureSketch fsketch = FeatureSketch.MakeFeatureSketch(new Sketch.Project(sketch)); Dictionary <Substroke, string> classifications = new Dictionary <Substroke, string>(); foreach (Substroke substroke in sketch.Substrokes) { classifications.Add(substroke, substroke.Classification); } Dictionary <string, Dictionary <FeatureStrokePair, double[]> > pair2values; pair2values = fsketch.GetValuesPairwise(classifications); foreach (KeyValuePair <string, Dictionary <FeatureStrokePair, double[]> > pair in pair2values) { string classification = pair.Key; Dictionary <FeatureStrokePair, double[]> features = pair.Value; Console.WriteLine(classification + ":"); foreach (KeyValuePair <FeatureStrokePair, double[]> pair2 in features) { Substroke stroke1 = pair2.Key.Item1; Substroke stroke2 = pair2.Key.Item2; double[] featureValues = pair2.Value; _resultsPairs.addResult(featureValues); } } }
private void FindIntersections(List <Substroke> strokes, int indexOfStroke) { if (indexOfStroke >= strokes.Count) { return; } Substroke stroke = strokes[indexOfStroke]; int size = Math.Max(1, indexOfStroke - 1); Dictionary <Substroke, Future <IntersectionPair> > pairs = new Dictionary <Substroke, Future <IntersectionPair> >(size); for (int i = 0; i < indexOfStroke; i++) { Substroke s = strokes[i]; Future <IntersectionPair> pair = getPair(stroke, s); pairs.Add(s, pair); lock (m_Stroke2Intersections) { if (m_Stroke2Intersections.ContainsKey(s)) { m_Stroke2Intersections[s].Add(stroke, pair); } } } if (!m_Strokes.Contains(stroke)) { m_Strokes.Add(stroke); } if (!m_Stroke2Intersections.ContainsKey(stroke)) { m_Stroke2Intersections.Add(stroke, pairs); } }
/// <summary> /// Unhighlights the corresponding strokes to the input /// </summary> /// <param name="name"></param> private void truthTableWindow_UnHighlightLabel(string name) { // If it is not in the dictionary - return ListSet <string> strokeSet = new ListSet <string>(); if (inputMapping.ContainsKey(name)) { strokeSet = inputMapping[name]; } else if (outputMapping.ContainsKey(name)) { strokeSet = outputMapping[name]; } else { return; } foreach (string s in strokeSet) { System.Windows.Ink.Stroke stroke = sketchPanel.InkSketch.GetInkStrokeById(s); Substroke sub = sketchPanel.InkSketch.GetSketchSubstrokeByInk(stroke); stroke.DrawingAttributes.Color = sub.Type.Color; } }
private double computeSubstrokeRecognitionQuality() { int totalStrokes = 0; int totalCorrect = 0; foreach (Substroke correctStroke in _original.Substrokes) { if (IGNORE_CLASSIFICATIONS.Contains(correctStroke.Classification.ToLower())) { continue; } ShapeType originalType = correctStroke.ParentShape.Type; totalStrokes++; Substroke resultStroke = _toCompare.SubstrokesL.Find(delegate(Substroke s) { return(s.GeometricEquals(correctStroke)); }); ShapeType resultType = resultStroke.ParentShape.Type; if (originalType == resultType) { totalCorrect++; } } return((double)totalCorrect / totalStrokes); }
/// <summary> /// Returns the average curvature of the substroke /// </summary> public double getAvgCurvature(Substroke sub) { this.arclength = new ArcLength(sub.Points); this.slope = new Slope(sub.Points); this.curve = new Curvature(sub.Points, arclength.Profile, slope.TanProfile); return(curve.AverageCurvature); }
/// <summary> /// Returns whether or not the strokes that make up a shape were /// drawn consecutively /// </summary> /// <param name="sketch">The sketch that contains the shape</param> /// <param name="shape">The shape to be checked</param> /// <returns>Whether or not the shape was drawn consecutively</returns> public bool isConsecutive(Sketch.Sketch sketch, Sketch.Shape shape) { Substroke[] strokes = shape.Substrokes; Substroke sub1 = strokes[0]; bool inShape = false; int shapeIndex = 0; for (int i = 0; i < sketch.Substrokes.Length; i++) { Substroke str = sketch.Substrokes[i]; if (!inShape && str.Equals(sub1)) { inShape = true; } if (shapeIndex == strokes.Length) { break; } if (inShape) { sub1 = strokes[shapeIndex]; if (!sub1.Equals(str)) { return(false); } shapeIndex++; } } return(true); }
/// <summary> /// Removes the given stroke from the pairwise feature sketch /// </summary> /// <param name="stroke"></param> public void RemoveStroke(Substroke stroke) { if (m_Strokes.Contains(stroke)) { m_Strokes.Remove(stroke); } if (m_Stroke2Pairs.ContainsKey(stroke)) { foreach (Future <FeatureStrokePair> pair in m_Stroke2Pairs[stroke]) { m_AllFeaturePairs.Remove(pair); } m_Stroke2Pairs.Remove(stroke); } List <StrokePair> toRemove = new List <StrokePair>(); foreach (KeyValuePair <StrokePair, Future <FeatureStrokePair> > pair in m_Pair2FeaturePair) { if (pair.Key.Includes(stroke)) { toRemove.Add(pair.Key); } } foreach (StrokePair pair in toRemove) { if (m_Pair2FeaturePair.ContainsKey(pair)) { m_Pair2FeaturePair.Remove(pair); } } }
private static Shape MakeShape(Substroke stroke) { List <Substroke> strokes = new List <Substroke>(new Substroke[1] { stroke }); return(MakeShape(strokes)); }
/// <summary> /// Returns the stroke corresponding to the given /// Sketch substroke. Returns null if no corresponding /// Ink stroke exists. /// </summary> /// <param name="substr">The Substroke to look up</param> /// <returns>The corresponding Ink stroke</returns> public System.Windows.Ink.Stroke GetInkStrokeBySubstroke(Substroke substroke) { Guid? substrId = substroke.XmlAttrs.Id; String index; sketchStr2ink.TryGetValue(substrId, out index); return(GetInkStrokeById(index)); }
// This function should return something or write to a file public void consecutiveStats(string statistics) { StreamWriter sw = File.CreateText(statistics); // Put the key at the top of the file sw.WriteLine("SketchID UserID ShapeName IsConsecutive"); foreach (Sketch.Sketch s in sketches) { // For each shape calculate if it is consecutive (i.e., are there any strokes interrupting it) foreach (Shape sh in s.Shapes) { // get the strokes in the shape // In theory these substrokes are time ordered... Substroke[] strokes = sh.Substrokes; if (strokes.Length == 0) { Console.WriteLine("Something's wrong. Shape " + sh + " has no substrokes"); } Substroke s1 = strokes[0]; // find the strokes in the sketch and make sure they are not interrupted by strokes not in the shape bool in_shape = false; int sh_index = 0; bool okSoFar = true; for (int i = 0; i < s.Substrokes.Length; i++) { Substroke str = s.Substrokes[i]; if (!in_shape && str.Equals(s1)) { in_shape = true; } if (sh_index == strokes.Length) { break; } if (in_shape) { s1 = strokes[sh_index]; if (!s1.Equals(str)) { okSoFar = false; sw.WriteLine("{0} {1} {2} False", s.XmlAttrs.Id, userIds[s.XmlAttrs.Id], sh.XmlAttrs.Name); break; } sh_index++; } } if (okSoFar) { sw.WriteLine("{0} {1} {2} True", s.XmlAttrs.Id, userIds[s.XmlAttrs.Id], sh.XmlAttrs.Name); } } } sw.Close(); }
/// <summary> /// Determine whether a substroke is part of a 'label' by way of its xml.type /// </summary> /// <param name="s">Substroke</param> /// <returns>whether it is a gate</returns> private bool IsLabel(Substroke s) { List <string> labelShapes = new List <string>(); labelShapes.Add("Label"); labelShapes.Add("Text"); return(labelShapes.Contains(s.FirstLabel)); }
public LinkedPoint(Substroke par, int index) { Point p = par.PointsL[index]; this.x = p.X; this.y = p.Y; this.parent = par; this.index = index; }
/// <summary> /// Initialize a new stroke steal operation. /// </summary> /// <param name="sketch">the relevant sketch</param> /// <param name="thief">the shape stealing a stroke</param> /// <param name="gem">the stroke it is stealing</param> public StrokeStealOperation( Sketch sketch, Shape thief, Substroke gem) : base(sketch) { _thief = thief; _gem = gem; }
/// <summary> /// Constructor for a specific intersection /// </summary> /// <param name="SSa">First Substroke</param> /// <param name="SSb">Second Substroke</param> /// <param name="aIntPt">Point along first stroke that the intersection occurs</param> /// <param name="bIntPt">Point along second stroke that the intersection occurs</param> /// <param name="aIsEndLine"></param> /// <param name="bIsEndLine"></param> public Intersection(Substroke SSa, Substroke SSb, float aIntPt, float bIntPt, bool aIsEndLine, bool bIsEndLine) { m_Id = Guid.NewGuid(); m_SubstrokeA = SSa; m_SubstrokeB = SSb; m_aIntPt = aIntPt; m_bIntPt = bIntPt; m_IsEndLineA = aIsEndLine; m_IsEndLineB = bIsEndLine; }
/// <summary> /// Classifies using WEKA. /// </summary> public override string classify(Substroke substroke, FeatureSketch featureSketch) { // Get the features for this substroke double[] featureValues = featureSketch.GetValuesSingle(substroke); // classify using Weka string classification = _wekaWrapper.Value.classify(featureValues); return(classification); }
/// <summary> /// Creates a new shape with a nonempty list of substrokes. /// </summary> /// <returns></returns> public static Shape newValidShape() { Substroke s1 = Shapes.newValidSubstroke(); Substroke s2 = Shapes.newValidSubstroke(); Substroke s3 = Shapes.newValidSubstroke(); Shape shape = new Shape(new Substroke[] { s1, s2, s3 }); shape.Name = "shape_" + (++time); return(shape); }
/// <summary> /// Constructor which creates an intersection pair between 2 strokes /// and then populates the list of intersections between the strokes /// </summary> /// <param name="ssA">First Substroke</param> /// <param name="ssB">Second Substroke</param> /// <param name="boxA"></param> /// <param name="boxB"></param> /// <param name="linesA"></param> /// <param name="linesB"></param> public IntersectionPair(Substroke ssA, Substroke ssB, RectangleF boxA, RectangleF boxB, List <Line> linesA, List <Line> linesB) { m_Id = Guid.NewGuid(); m_SubstrokeA = ssA; m_BoxA = boxA; m_LinesA = linesA; m_SubstrokeB = ssB; m_BoxB = boxB; m_LinesB = linesB; m_Intersections = Compute.Intersect(m_SubstrokeA, m_SubstrokeB, m_LinesA, m_LinesB, m_BoxA, m_BoxB, 0.0f); }
/// <summary> /// Construct a new SSA object to match against a single substroke /// </summary> /// <param name="ss">The substroke to match against</param> /// <param name="s">The shape containing the important substroke</param> /// <param name="fs">A list of features to align on the basis of. Each feature gets one "vote"</param> public SingleStrokeAlign(Substroke ss, Shape s, List <AlignFeature> fs) { _template = ss; _shape = s; _tf = new Dictionary <AlignFeature, double>(); foreach (AlignFeature f in fs) { _tf.Add(f, double.NaN); } calculateParam(s); }