/// <summary> /// Reads the Shape XML attributes /// </summary> /// <param name="reader">XML text reader for the file</param> private void ReadShape(XmlTextReader reader) { // Required MIT XML attributes string type = reader.GetAttribute("type"); string name = reader.GetAttribute("name"); string id = reader.GetAttribute("id"); string time = reader.GetAttribute("time"); XmlStructs.XmlShapeAttrs shapeAttrs = new XmlStructs.XmlShapeAttrs(new Guid(id)); if ((type != null) && (id != null) && (time != null)) { shapeAttrs.Type = type; shapeAttrs.Name = name; shapeAttrs.Time = Convert.ToUInt64(time); } else { string bad = ""; if (type == null) { bad += "Type "; } if (name == null) { bad += "Name "; } if (id == null) { bad += "ID "; } if (time == null) { bad += "Time "; } throw new ApplicationException("Invalid Format: Shapes must contain a Type, Name, Id, and Time. Missing " + bad); } // Get the rest of the attributes, if they are there // We use temporary strings here so that we can check if the attribute is <null> string author = reader.GetAttribute("author"); string color = reader.GetAttribute("color"); string height = reader.GetAttribute("height"); string width = reader.GetAttribute("width"); string area = reader.GetAttribute("area"); string laysInk = reader.GetAttribute("laysInk"); string orientation = reader.GetAttribute("orientation"); string penTip = reader.GetAttribute("penTip"); string penWidth = reader.GetAttribute("penWidth"); string penHeight = reader.GetAttribute("penHeight"); string raster = reader.GetAttribute("raster"); string substrokeOf = reader.GetAttribute("substrokeOf"); string p1 = reader.GetAttribute("p1"); string p2 = reader.GetAttribute("p2"); string x = reader.GetAttribute("x"); string y = reader.GetAttribute("y"); string probability = reader.GetAttribute("probability"); string text = reader.GetAttribute("text"); string leftx = reader.GetAttribute("leftx"); string topy = reader.GetAttribute("topy"); string control1 = reader.GetAttribute("control1"); string control2 = reader.GetAttribute("control2"); string start = reader.GetAttribute("start"); string end = reader.GetAttribute("end"); string source = reader.GetAttribute("source"); string classification = reader.GetAttribute("classification"); if (author != null) { shapeAttrs.Author = new Guid(author); } if (color != null) { shapeAttrs.Color = Convert.ToInt32(color); } if (height != null) { shapeAttrs.Height = Convert.ToSingle(height); } if (width != null) { shapeAttrs.Width = Convert.ToSingle(width); } if (area != null) { shapeAttrs.Area = Convert.ToSingle(area); // Convert.ToDouble(area); } if (laysInk != null) { shapeAttrs.LaysInk = Convert.ToBoolean(laysInk); } if (orientation != null) { shapeAttrs.Orientation = Convert.ToSingle(orientation); } else { shapeAttrs.Orientation = 0; // arbitrary set orientation to 0. } if (penTip != null) { shapeAttrs.PenTip = penTip; } if (penWidth != null) { shapeAttrs.PenWidth = Convert.ToSingle(penWidth); } if (penHeight != null) { shapeAttrs.PenHeight = Convert.ToSingle(penHeight); } if (raster != null) { shapeAttrs.Raster = raster; } if (substrokeOf != null) { shapeAttrs.SubstrokeOf = new Guid(substrokeOf); } if (p1 != null) { shapeAttrs.P1 = p1; } if (p2 != null) { shapeAttrs.P2 = p2; } if (x != null) { shapeAttrs.X = Convert.ToSingle(x); } if (y != null) { shapeAttrs.Y = Convert.ToSingle(y); } if (probability != null) { shapeAttrs.Probability = Convert.ToSingle(probability); } if (text != null) { shapeAttrs.Text = text; } if (leftx != null) { shapeAttrs.LeftX = Convert.ToSingle(leftx); } if (topy != null) { shapeAttrs.TopY = Convert.ToSingle(topy); } if (control1 != null) { shapeAttrs.Control1 = control1; } if (control2 != null) { shapeAttrs.Control2 = control2; } if (start != null) { shapeAttrs.Start = new Guid(start); } if (end != null) { shapeAttrs.End = new Guid(end); } if (source != null) { shapeAttrs.Source = source; } if (classification != null) { shapeAttrs.Classification = classification; } // Some local variables concerning the arguments List <Guid> args = new List <Guid>(); string uniformArgtype = null; bool isShape = false; List <Guid> shapeArgs = new List <Guid>(); List <Guid> strokeArgs = new List <Guid>(); List <Guid> substrokeArgs = new List <Guid>(); List <Guid> neighborArgs = new List <Guid>(); // Boolean to check if the current shape element is actually a Sketch.Shape if (!shapeAttrs.Type.ToLower().Equals("stroke") && !shapeAttrs.Type.ToLower().Equals("substroke")) { isShape = true; } reader.Read(); string argname = reader.Name; int tagNumber = int.MinValue; // Now read the subelements, until we get to the end of the shape while (reader.NodeType != XmlNodeType.EndElement) { argname = reader.Name; if (argname.ToLower().Equals("arg")) { string argtype = reader.GetAttribute("type"); string argid = reader.ReadElementString(); // Set the argtype (must be the same for all regular shapes, such as Strokes and Substrokes) if (uniformArgtype == null) { uniformArgtype = argtype; } // If the current element is not a Sketch.Shape if (!isShape) { // Check to make sure that the argument is the same if (uniformArgtype == argtype) { args.Add(new Guid(argid)); } else { throw new ApplicationException("Invalid Format: Only abnormal Shapes are allowed to contain multiple arg types"); } } // If the current shape is a Sketch.Shape else { // Add the argument to either a Substroke ArrayList or a Shape ArrayList if (argtype.ToLower().Equals("stroke")) { strokeArgs.Add(new Guid(argid)); } else if (argtype.ToLower().Equals("substroke")) { substrokeArgs.Add(new Guid(argid)); } else if (argtype.ToLower().Equals("shape")) { shapeArgs.Add(new Guid(argid)); } else { neighborArgs.Add(new Guid(argid)); } } } // TODO: Handle aliases else if (argname.ToLower().Equals("alias")) { string aliastype = reader.GetAttribute("type"); string aliasname = reader.GetAttribute("name"); string aliasid = reader.ReadElementString(); //s.Aliases.Add(new Shape.Alias(aliastype, aliasname, aliasid)); } else if (argname.ToLower().Equals("neighbor")) { // CODE TO WORK WITH NEIGHBORS string argtype = reader.GetAttribute("type"); string argid = reader.ReadElementString(); neighborArgs.Add(new Guid(argid)); } else if (argname.ToLower().Equals("subcircuit")) { tagNumber = Convert.ToInt32(reader.GetAttribute("tagNumber")); reader.Read(); } } // If the shape is a Substroke if (shapeAttrs.Type.ToLower().Equals("substroke")) { if (uniformArgtype.ToLower().Equals("point")) { this.substrokeToAttrs.Add(shapeAttrs.Id, shapeAttrs); this.substrokeToPointIDs.Add(shapeAttrs.Id, args); } else { throw new ApplicationException("Invalid Format: Substrokes must be made of points"); } } // If the shape is a Stroke else if (shapeAttrs.Type.ToLower().Equals("stroke")) { // If the arguments are Points we need to create a corresponding Substroke if (uniformArgtype.ToLower().Equals("point")) { Sketch.XmlStructs.XmlShapeAttrs substrokeAttrs = shapeAttrs.Clone(); // Create a new Substroke and link it to the Points in the hashtable substrokeAttrs.Name = "substroke"; substrokeAttrs.Type = "Substroke"; this.substrokeToAttrs.Add(substrokeAttrs.Id, substrokeAttrs); this.substrokeToPointIDs.Add(substrokeAttrs.Id, args); List <Guid> s = new List <Guid>(1); s.Add(substrokeAttrs.Id); this.strokeToAttrs.Add(shapeAttrs.Id, shapeAttrs); this.strokeToSubstrokeIDs.Add(shapeAttrs.Id, s); } else if (uniformArgtype.ToLower().Equals("substroke")) { this.strokeToAttrs.Add(shapeAttrs.Id, shapeAttrs); this.strokeToSubstrokeIDs.Add(shapeAttrs.Id, args); } else { throw new ApplicationException("Invalid Format: Strokes are required to have " + "Substroke or Point arguments"); } } // If the shape is a Sketch.Shape else { this.shapeToAttrs.Add(shapeAttrs.Id, shapeAttrs); this.shapeToShapeIDs.Add(shapeAttrs.Id, shapeArgs); this.shapeToStrokeIDs.Add(shapeAttrs.Id, strokeArgs); this.shapeToSubstrokeIDs.Add(shapeAttrs.Id, substrokeArgs); this.shapeToNeighborIDs.Add(shapeAttrs.Id, neighborArgs); if (tagNumber != int.MinValue) { this.shapeToTagNumber.Add(shapeAttrs.Id, tagNumber); } } // And consume the </shape> reader.ReadEndElement(); }
/// <summary> /// Constructs a sketch from the given stream /// </summary> /// <param name="reader">The XML reader that will read in XML data</param> private void CreateSketch(XmlTextReader reader) { // Read all the data from the XML file this.ReadSketchData(reader); List <Shape> shapes = new List <Shape>(); List <Stroke> strokes = new List <Stroke>(); Dictionary <Guid, Stroke> allStrokes = new Dictionary <Guid, Stroke>(); Dictionary <Guid, Substroke> allSubstrokes = new Dictionary <Guid, Substroke>(); Dictionary <Guid, Shape> allShapes = new Dictionary <Guid, Shape>(); // Cycle through the Stroke Id's pulled from the file foreach (KeyValuePair <Guid, XmlStructs.XmlShapeAttrs> stroke in this.strokeToAttrs) //foreach(KeyValuePair<Guid, ArrayList> stroke in this.strokeToSubstrokesHT) { XmlStructs.XmlShapeAttrs strokeAttrs = stroke.Value; List <Guid> substrokeIds = this.strokeToSubstrokeIDs[stroke.Key]; List <Substroke> substrokes = new List <Substroke>(); // Cycle through the Substroke Id's pulled from the file int len = substrokeIds.Count; // Check if the file had no strokes. if (len == 0) { Console.WriteLine("ERROR: File contains no strokes"); } for (int i = 0; i < len; ++i) { List <Guid> ptsArray = this.substrokeToPointIDs[substrokeIds[i]]; XmlStructs.XmlShapeAttrs substrokeAttrs = this.substrokeToAttrs[substrokeIds[i]]; List <Point> points = new List <Point>(); // Get all of the Points associated with the Substroke int len2 = ptsArray.Count; for (int k = 0; k < len2; ++k) { points.Add(this.pointsHT[ptsArray[k]]); } // Create a new Substroke and add it to the local Hashtable and Stroke ArrayList Substroke newSubstroke = new Substroke(points, substrokeAttrs); allSubstrokes.Add(newSubstroke.XmlAttrs.Id, newSubstroke); substrokes.Add(newSubstroke); } // Add a new Stroke Stroke newStroke = new Stroke(substrokes, strokeAttrs); allStrokes.Add(newStroke.XmlAttrs.Id, newStroke); strokes.Add(newStroke); } // Cycle through the Shape Id's pulled from the file //foreach (KeyValuePair<Guid, ArrayList> shape in this.shapeToArgsHT) foreach (KeyValuePair <Guid, XmlStructs.XmlShapeAttrs> shape in this.shapeToAttrs) { /* * XmlStructs.XmlShapeAttrs shapeAttrs = shape.Value; * * List<Shape> shapeIds = this.shapeToShapeIDs[shape.Key]; * List<Stroke> strokeIds = this.shapeToStrokeIDs[shape.Key]; * List<Substroke> substrokeIds = this.shapeToSubstrokeIDs[shape.Key]; */ List <Substroke> substrokes = RecShape(shape.Key, allStrokes, allSubstrokes); // Add a new Shape Shape currShape = new Shape(substrokes, shape.Value); shapes.Add(currShape); allShapes.Add(currShape.Id, currShape); } foreach (Shape s in shapes) { GetNeighbors(sketch, s, allShapes); } // Add the Shapes and Strokes to the Sketch sketch.AddStrokes(strokes); sketch.AddShapes(shapes); }
/// <summary> /// Constructs a sketch from the given stream /// </summary> /// <param name="reader">The XML reader that will read in XML data</param> private void CreateSketch(XmlTextReader reader) { // Read all the data from the XML file this.ReadSketchData(reader); List <Shape> shapes = new List <Shape>(); List <Stroke> strokes = new List <Stroke>(); Dictionary <Guid, Stroke> allStrokes = new Dictionary <Guid, Stroke>(); Dictionary <Guid, Substroke> allSubstrokes = new Dictionary <Guid, Substroke>(); Dictionary <Guid, Shape> allShapes = new Dictionary <Guid, Shape>(); // Cycle through the Stroke Id's pulled from the file foreach (KeyValuePair <Guid, XmlStructs.XmlShapeAttrs> stroke in this.strokeToAttrs) { XmlStructs.XmlShapeAttrs strokeAttrs = stroke.Value; List <Guid> substrokeIds = this.strokeToSubstrokeIDs[stroke.Key]; List <Substroke> substrokes = new List <Substroke>(); // Cycle through the Substroke Id's pulled from the file int len = substrokeIds.Count; // Check if the file had no strokes. if (len == 0) { Console.WriteLine("ERROR: File contains no strokes"); } for (int i = 0; i < len; ++i) { List <Guid> ptsArray = this.substrokeToPointIDs[substrokeIds[i]]; XmlStructs.XmlShapeAttrs substrokeAttrs = this.substrokeToAttrs[substrokeIds[i]]; List <Point> points = new List <Point>(); // Get all of the Points associated with the Substroke int len2 = ptsArray.Count; for (int k = 0; k < len2; ++k) { points.Add(this.pointsHT[ptsArray[k]]); } // Create a new Substroke and add it to the local Hashtable and Stroke ArrayList Substroke newSubstroke = new Substroke(points, substrokeAttrs); allSubstrokes.Add(newSubstroke.XmlAttrs.Id, newSubstroke); substrokes.Add(newSubstroke); } // Add a new Stroke Stroke newStroke = new Stroke(substrokes, strokeAttrs); allStrokes.Add(newStroke.XmlAttrs.Id, newStroke); strokes.Add(newStroke); } // Cycle through the Shape Id's pulled from the file foreach (KeyValuePair <Guid, XmlStructs.XmlShapeAttrs> shape in this.shapeToAttrs) { List <Substroke> substrokes = RecShape(shape.Key, allStrokes, allSubstrokes); // Add a new Shape Shape currShape = new Shape(substrokes, shape.Value); int tag = int.MinValue; if (this.shapeToTagNumber.ContainsKey(shape.Key)) { this.shapeToTagNumber.TryGetValue(shape.Key, out tag); } currShape.SubCircuitNumber = tag; shapes.Add(currShape); allShapes.Add(currShape.Id, currShape); } foreach (Shape s in shapes) { GetNeighbors(sketch, s, allShapes); } // Add the Shapes and Strokes to the Sketch sketch.AddStrokes(strokes); sketch.AddShapes(shapes); //Give the shapes the new tag numbers, so that viewing subcircuits works foreach (Sketch.Shape shape in Sketch.Shapes) { if (oldToNewTag.ContainsKey(shape.SubCircuitNumber)) { shape.SubCircuitNumber = oldToNewTag[shape.SubCircuitNumber]; } } }
static void Main(string[] args) { //if (args.Length == 0) //return; if (NUMBEST != 0) { string filePath = Directory.GetCurrentDirectory(); if (filePath.Contains("\\Code\\")) { filePath = filePath.Substring(0, filePath.IndexOf("\\Code\\") + 1); } TrainByNBest(filePath + "Data\\Gate Study Data\\LabeledPartsSketches", "*.xml"); return; } List <KeyValuePair <string, Dictionary <string, object> > > data = new List <KeyValuePair <string, Dictionary <string, object> > >(); Dictionary <string, List <string>[]> user2sketches = GetSketchesPerUser(args[0], args[1]); // Foreach user: train each of the recognizers foreach (KeyValuePair <string, List <string>[]> pair in user2sketches) { string user = pair.Key; int userNum; bool good = int.TryParse(user.Substring(0, 2), out userNum); if (good && userNum <= 0) { continue; } User u = new User(userNum.ToString()); PlatformUsed platform = PlatformUsed.TabletPC; if (user.Contains("P")) { platform = PlatformUsed.Wacom; } //Console.WriteLine("User: "******"NOT") { List <Substroke> strokes = new List <Substroke>(); foreach (Substroke s in shape.Substrokes) { if (s.Labels[s.Labels.Length - 1] == "Bubble") { strokes.Add(s); break; } } XmlStructs.XmlShapeAttrs attr = new XmlStructs.XmlShapeAttrs(); attr.Type = "NOTBUBBLE"; Shape nb = new Shape(strokes, attr); recognizer.Add(nb); } } } } recognizer.Save("ImageAlignerRecognizer" + user + ".iar"); int numRight = 0; int numWrong = 0; Dictionary <Shape, ImageTemplateResult> results = new Dictionary <Shape, ImageTemplateResult>(); foreach (string sketchFile in testFiles) { Sketch.Sketch sketch = new ReadXML(sketchFile).Sketch; sketch = General.ReOrderParentShapes(sketch); foreach (Shape shape in sketch.Shapes) { if (General.IsGate(shape) && shape.Substrokes[0].Labels[0] == shape.Label && shape.Label != "LabelBox") { ImageTemplateResult result = recognizer.Recognize(shape); if (result != null) { results.Add(shape, result); if (result.Name == shape.Label) { numRight++; } else { numWrong++; } } } } } int total = numRight + numWrong; Console.WriteLine("User: "******" Correct: " + numRight.ToString() + "/" + total.ToString()); if (args.Length > 2 && args[2] == "-v") { foreach (KeyValuePair <Shape, ImageTemplateResult> kv in results) { WriteResult(kv.Key, kv.Value); } } } }