示例#1
0
        /// <summary>
        /// Run the recognizer on a sketch.
        ///
        /// This method is multithreaded.
        ///
        /// Precondition: the sketch has been grouped into shapes.
        ///
        /// Postcondition: shape.Classification has been filled in with this recognizer's best guess
        /// for every shape in the sketch.
        /// </summary>
        /// <param name="featureSketch">the sketch to work on</param>
        public override void process(Featurefy.FeatureSketch featureSketch)
        {
            List <Thread> threads         = new List <Thread>(_numThreads);
            int           shapesPerWorker = featureSketch.NumShapes / _numThreads;
            int           finalEnd        = 0;

            // fork off (_numThreads - 1) threads, each with shapesPerWorker tasks to perform
            for (int i = 0; i < _numThreads - 1; i++)
            {
                int start = i * shapesPerWorker;
                int end   = start + shapesPerWorker;
                finalEnd = end;
                Worker worker = new Worker(_innerRecognizer, start, end, featureSketch);
                Thread t      = new Thread(worker.run);
                t.Name = "recognition worker thread " + i;
                threads.Add(t);
                t.Start();
            }

            // do the rest of the work on this thread
            Worker myWorker = new Worker(_innerRecognizer, finalEnd, featureSketch.NumShapes, featureSketch);

            myWorker.run();

            // join the other threads to make sure they finished
            foreach (Thread t in threads)
            {
                t.Join();
            }
        }
示例#2
0
        /// <summary>
        /// Look at any out-of-context shapes in the sketch and refine them by
        /// removing a substroke. (We may want to try removing more strokes later).
        ///
        /// We assume that the substroke should be a wire, and we remove it
        /// from the shape. Then we regroup the shape without the substroke,
        /// re-recognize it, and check to see if it makes sense. If it does,
        /// keep it. If not, try again with a different substroke.
        /// </summary>
        public void StrokeShedRefine(Featurefy.FeatureSketch featureSketch)
        {
            foreach (Sketch.Shape shape in featureSketch.Sketch.Shapes)
            {
                bool valid = _domain.IsProperlyConnected(shape);

                // If the shape wansn't specified by the user, doesn't fit
                // its context, and is a gate
                if ((!shape.AlreadyGrouped) &&
                    (!valid || (shape.Probability < _thresholdProbability)) &&
                    (shape.Classification == LogicDomain.GATE_CLASS))
                {
                    float            bestProb      = 0F;
                    Sketch.Substroke bestSubstroke = null;

                    foreach (Sketch.Substroke substroke in shape.Substrokes)
                    {
                        // See how helpful it is to let the shape
                        // shed this stroke
                        float shedProb = strokeShedHelpfulness(shape, substroke, featureSketch);
                        if (shedProb > bestProb)
                        {
                            bestProb      = shedProb;
                            bestSubstroke = substroke;
                        }
                    }

                    // If hypotheticaly shedding one of the substrokes
                    // enhanced the recognition of the shape, do it for real
                    //if (bestProb > shape.Probability) // NOT SURE IF WE WANT TO KEEP THIS
                    shedStroke(shape, bestSubstroke, featureSketch);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Recognizes a given shape and updates the shape accordingly.
        /// </summary>
        /// <param name="shape">The shape to recogize</param>
        /// <param name="featureSketch">A featuresketch</param>
        public override void recognize(Sketch.Shape shape, Featurefy.FeatureSketch featureSketch)
        {
            // Make sure we do nothing if the user specified the label
            if (shape.AlreadyLabeled)
            {
                return;
            }

            // Use a particular recognizer based on how the shape was
            // classified.

            if (shape.Classification == LogicDomain.WIRE_CLASS)
            {
                _wireRecognizer.recognize(shape, featureSketch);
            }
            else if (shape.Classification == LogicDomain.TEXT_CLASS)
            {
                _textRecognizer.recognize(shape, featureSketch);
            }
            else if (shape.Classification == LogicDomain.GATE_CLASS)
            {
                _gateRecognizer.recognize(shape, featureSketch);
            }
            else
            {
                Console.WriteLine(
                    "Error in shape recognition: cannot recognize" +
                    " a shape with the classification \"" +
                    shape.Classification + "\"");
            }
        }
示例#4
0
 public virtual void process(Featurefy.FeatureSketch featureSketch)
 {
     foreach (Sketch.Shape shape in featureSketch.Sketch.Shapes)
     {
         orient(shape, featureSketch);
     }
 }
        public void FeatureSketchCreationBehavior()
        {
            /*
             * Problem description:
             * When a sketch contains duplicated points, the creation of a FeatureSketch
             * may delete those points.
             */

            Sketch.Sketch sketch = Sketches.newValidSketch();

            // Duplicate a point in the sketch
            Sketch.Shape shape = sketch.Shapes[0];

            List <Sketch.Point> points = new List <Sketch.Point>(shape.Substrokes[0].Points);

            points.Add(points[points.Count - 1]);

            Sketch.Substroke substroke = new Sketch.Substroke(points);
            sketch.AddStroke(new Sketch.Stroke(substroke));
            shape.AddSubstroke(substroke);

            Sketch.Sketch clone = sketch.Clone();

            Assert.IsTrue(sketch.Equals(clone), "Sketch is not equal to its clone");

            Featurefy.FeatureSketch featureSketch = newValidFeatureSketch(new Sketch.Project(sketch));

            Assert.IsTrue(sketch.Equals(clone), "FeatureSketch creation modified original sketch");
        }
示例#6
0
        /// <summary>
        /// Refines the recognition after the shapes have all been recognized.
        ///
        /// Precondition: ConnectSketch() has been called.
        /// </summary>
        public void RefineSketch(Featurefy.FeatureSketch _featuresketch)
        {
            _refinement.process(_featuresketch);

            if (debug)
            {
                Console.WriteLine("Connections:");
                foreach (Sketch.Shape shape in _featuresketch.Sketch.Shapes)
                {
                    Console.Write("  --> " + shape.Name + ": ");
                    bool first = true;
                    foreach (Sketch.Shape connectedShape in shape.ConnectedShapes)
                    {
                        if (!first)
                        {
                            Console.Write(", ");
                        }
                        first = false;

                        Console.Write(connectedShape.Name);
                    }
                    Console.WriteLine();
                }
            }
        }
        /// <summary>
        /// Recognize what gate a shape is using the ComboRecgonizer,
        /// and update the shape with the results.
        /// </summary>
        /// <param name="shape">
        /// The shape to recognize (should be a gate)
        /// </param>
        public override void recognize(Sketch.Shape shape, Featurefy.FeatureSketch featureSketch)
        {
            // Initialize variables to store results in
            ShapeType bestType        = new ShapeType();
            float     bestProbability = 0F;
            double    bestOrientation;

            // Recognize the shape and pick out the best option
            Dictionary <ShapeType, double> alternativeTypes = Recognize(shape, out bestOrientation);

            foreach (KeyValuePair <ShapeType, double> pair in alternativeTypes)
            {
                ShapeType type = pair.Key;
                double    prob = pair.Value;
                if (prob > bestProbability)
                {
                    bestType        = type;
                    bestProbability = (float)prob;
                }
            }

            // Update the shape to reflect this recognition
            shape.setRecognitionResults(
                bestType,
                bestProbability,
                alternativeTypes,
                bestOrientation);
        }
示例#8
0
 /// <summary>
 /// Create a new worker.
 /// </summary>
 /// <param name="inner">the recognizer to use</param>
 /// <param name="start">the first shape to recognize (inclusive)</param>
 /// <param name="end">the last shape to recognize (exclusive)</param>
 /// <param name="featureSketch">the sketch whose shapes we'll work on</param>
 public Worker(Recognizer inner, int start, int end, Featurefy.FeatureSketch featureSketch)
 {
     _innerRecognizer = inner;
     _start           = start;
     _end             = end;
     _featureSketch   = featureSketch;
     _shapes          = _featureSketch.Sketch.Shapes;
 }
        public static InkToSketchWPF.InkCanvasSketch newInkCanvasSketch()
        {
            // Manually construct the necessary data members
            Sketch.Sketch           sketch        = new Sketch.Sketch();
            Featurefy.FeatureSketch featureSketch = UnitTests.FeaturefyOperations.newValidFeatureSketch(new Sketch.Project(sketch));
            InkCanvas inkcanvas = new InkCanvas();

            return(new InkToSketchWPF.InkCanvasSketch(inkcanvas, featureSketch));
        }
示例#10
0
        /// <summary>
        /// After the sketch has been recognized, we can look at the context of each shape.
        /// If a shape is out of context (for example, if a NOT gate is connected to three wires),
        /// then we assign the shape the next most likely label.
        /// </summary>
        /// <param name="featureSketch">the sketch to process</param>
        public virtual void process(Featurefy.FeatureSketch featureSketch)
        {
            if (DEBUG)
            {
                Console.WriteLine("\nCareful Context Refinement");
            }

            foreach (Sketch.Shape shape in featureSketch.Sketch.Shapes)
            {
                bool valid = _domain.IsProperlyConnected(shape);

                if (valid || shape.AlreadyGrouped)
                {
                    continue;
                }

                ShapeType originalType        = shape.Type;
                string    originalName        = shape.Name;
                float     originalProbability = shape.Probability;

                // If a shape only has one connection,
                // it is assumed to be a label.
                if (shape.ConnectedShapes.Count == 1)
                {
                    foreach (Sketch.Substroke substroke in shape.Substrokes)
                    {
                        substroke.Classification = LogicDomain.TEXT_CLASS;
                    }
                    _sketchRecognizer.processShape(shape, featureSketch);
                    if (shape.Probability < 0.5)
                    {
                        // we probably made a mistake, so revert.
                        shape.Type        = originalType;
                        shape.Name        = originalName;
                        shape.Probability = originalProbability;
                    }
                }

                if (Domain.LogicDomain.IsGate(shape.Type))
                {
                    nextBestLabel(shape);
                    if (!_domain.IsProperlyConnected(shape))
                    {
                        // the next best type wasn't properly connected either
                        // so we probably want to stick with our first type
                        shape.Type        = originalType;
                        shape.Name        = originalName;
                        shape.Probability = originalProbability;
                    }
                }

                if (DEBUG && ((originalName != shape.Name) || (originalType != shape.Type))) // if it changed
                {
                    Console.WriteLine("    " + originalName + " (" + originalType + ") -> " + shape.Name + " (" + shape.Type + "); confidence = " + shape.Probability);
                }
            }
        }
示例#11
0
 /// <summary>
 /// Run the recognizer on a sketch.
 ///
 /// Precondition: the sketch has been grouped into shapes.
 ///
 /// Postcondition: shape.Type and shape.Probability have been filled in with
 /// this recognizer's best guess for every shape in the sketch.
 /// </summary>
 /// <param name="featureSketch">the sketch to work on</param>
 public void process(Featurefy.FeatureSketch featureSketch)
 {
     foreach (Sketch.Shape shape in featureSketch.Sketch.Shapes)
     {
         if (shape.AlreadyLabeled || !canRecognize(shape.Classification))
         {
             continue;
         }
         processShape(shape, featureSketch);
     }
 }
 public void process(Featurefy.FeatureSketch featureSketch)
 {
     Sketch.Sketch sketch = featureSketch.Sketch;
     foreach (Sketch.Shape shape in sketch.Shapes)
     {
         if (shape.Type != new Domain.ShapeType())
         {
             shape.AlreadyLabeled = true;
             shape.AlreadyGrouped = true;
         }
     }
 }
示例#13
0
        /// <summary>
        /// Test the validity of each labeled shape.
        /// </summary>
        /// <returns>A dictionary mapping shapes to validity.</returns>
        public Dictionary <Sketch.Shape, bool> TestValidity(Featurefy.FeatureSketch _featuresketch)
        {
            Sketch.Sketch sketch = _featuresketch.Sketch;
            Dictionary <Sketch.Shape, bool> dict = new Dictionary <Sketch.Shape, bool>();

            foreach (Sketch.Shape shape in sketch.Shapes)
            {
                dict.Add(shape, _domain.IsProperlyConnected(shape));
            }

            return(dict);
        }
示例#14
0
        /// <summary>
        /// Construct a sketch modification. Computes the benefit of this action
        /// by computing the difference in the given energy function from
        /// performing the given sketch operation.
        /// </summary>
        public SketchModification(Featurefy.FeatureSketch sketch, ISketchOperation op, Func <Featurefy.FeatureSketch, double> energyFunc)
        {
            _sketch = sketch.Sketch;
            _op     = op;

            double initialEnergy = energyFunc(sketch);

            op.perform();
            double finalEnergy = energyFunc(sketch);

            op.undo();
            _benefit = finalEnergy - initialEnergy;
        }
示例#15
0
        /// <summary>
        /// Classifies only the given substrokes.
        ///
        /// Postcondition: substroke.Classification is "Wire," "Gate," "Label," or "Unknown" for
        /// every substroke in the list. Strokes are not reclassified if they have a parent
        /// shape with AlreadyLabeled set to true.
        /// </summary>
        /// <param name="sketch">the sketch to use</param>
        /// <param name="featureSketch">the featureSketch to use</param>
        public virtual void process(Featurefy.FeatureSketch featureSketch, IEnumerable <Sketch.Substroke> substrokes)
        {
            foreach (Sketch.Substroke substroke in substrokes)
            {
                Sketch.Shape parent = substroke.ParentShape;
                if (parent != null && parent.AlreadyLabeled)
                {
                    continue;
                }

                substroke.Classification = classify(substroke, featureSketch);
            }
        }
示例#16
0
        /// <summary>
        /// Classifies all the substrokes in a sketch.
        ///
        /// Postcondition: substroke.Classification is "Wire," "Gate," "Label," or "Unknown" for
        /// every substroke in the sketch. Strokes are not reclassified if they have a parent
        /// shape with AlreadyLabeled set to true.
        /// </summary>
        /// <param name="sketch">the sketch to use</param>
        public virtual void process(Featurefy.FeatureSketch sketch)
        {
            foreach (Sketch.Substroke substroke in sketch.Sketch.Substrokes)
            {
                Sketch.Shape parent = substroke.ParentShape;
                if (parent != null && parent.AlreadyLabeled)
                {
                    continue;
                }

                classify(substroke, sketch);
            }
        }
        /// <summary>
        /// After the sketch has been recognized, we can look at the context of each shape.
        /// If a shape is out of context (for example, if a NOT gate is connected to three wires),
        /// then we assign the shape the next most likely label.
        /// </summary>
        /// <param name="featureSketch">the sketch to process</param>
        public void process(Featurefy.FeatureSketch featureSketch)
        {
            if (DEBUG)
            {
                Console.WriteLine("Context Refinement");
            }

            // Refine three times... (THIS IS A MAGIC NUMBER I PULLED OUT OF THE AIR).
            int CONTEXT_REFINE_ITERATIONS = 3;

            for (int i = 0; i < CONTEXT_REFINE_ITERATIONS; i++)
            {
                foreach (Sketch.Shape shape in featureSketch.Sketch.Shapes)
                {
                    bool valid = _domain.IsProperlyConnected(shape);

                    if (valid || shape.AlreadyGrouped)
                    {
                        continue;
                    }

                    ShapeType originalType = shape.Type;
                    string    originalName = shape.Name;

                    // If a shape only has one connection, it is assumed to be a label
                    if (shape.ConnectedShapes.Count == 1)
                    {
                        foreach (Sketch.Substroke substroke in shape.Substrokes)
                        {
                            substroke.Classification = "Text";
                        }
                        _sketchRecognizer.recognize(shape, featureSketch);
                    }
                    else
                    {
                        if (Domain.LogicDomain.IsGate(shape.Type))
                        {
                            nextBestLabel(shape);
                        }
                    }

                    if (DEBUG && ((originalName != shape.Name) || (originalType != shape.Type))) // if it changed
                    {
                        Console.WriteLine("    " + originalName + " (" + originalType + ") -> " + shape.Name + " (" + shape.Type + ")");
                    }
                }
            }
        }
示例#18
0
        public void process(Featurefy.FeatureSketch featureSketch)
        {
            _sketch = featureSketch.Sketch;
            List <Shape> notbubbles = Data.Utils.filter(_sketch.Shapes, delegate(Shape s) { return(s.Type == LogicDomain.NOTBUBBLE); });

            foreach (Shape bubble in notbubbles)
            {
                foreach (Shape connected in bubble.ConnectedShapes)
                {
                    if (tryToMerge(bubble, connected))
                    {
                        break;
                    }
                }
            }
        }
示例#19
0
        /// <summary>
        /// Regroups and recognizes the shape
        /// </summary>
        /// <param name="shape"></param>
        private void regroupShape(Sketch.Shape shape, Featurefy.FeatureSketch _featuresketch)
        {
            if (shape.Type == new ShapeType())
            {
                _strokeClassifier.process(_featuresketch, shape.Substrokes);
            }

            if (shape.Substrokes.Length > 0)
            {
                // Determine the majority classification
                Dictionary <string, int> counts = new Dictionary <string, int>();
                foreach (Sketch.Substroke substroke in shape.Substrokes)
                {
                    if (!counts.ContainsKey(substroke.Classification))
                    {
                        counts.Add(substroke.Classification, 0);
                    }
                    counts[substroke.Classification]++;
                }

                string bestClassification = LogicDomain.GATE_CLASS;
                int    bestCount          = 0;
                foreach (KeyValuePair <string, int> pair in counts)
                {
                    if (pair.Value > bestCount)
                    {
                        bestCount          = pair.Value;
                        bestClassification = pair.Key;
                    }
                }

                // Give all the substrokes the same classification since they are in the same group
                shape.Classification = bestClassification;
                if (!shape.AlreadyLabeled)
                {
                    _sketchRecognizer.processShape(shape, _featuresketch);
                }
            }

            else
            {
                Console.WriteLine("WARNING No substrokes available");
            }

            MakeShapeNamesUnique(_featuresketch);
        }
示例#20
0
        public virtual void orient(Shape shape, Featurefy.FeatureSketch featureSketch)
        {
            ShapeType    type = shape.Type;
            BitmapSymbol defn = new BitmapSymbol();

            foreach (BitmapSymbol template in _templates)
            {
                if (template.SymbolType == type)
                {
                    defn = template;
                    break;
                }
            }

            BitmapSymbol unknown = new BitmapSymbol(shape.SubstrokesL);

            shape.Orientation = unknown.bestOrientation(defn);
        }
示例#21
0
        /// <summary>
        /// Recognizes the text a shape forms, and updates the
        /// shape with the recognition results (the text and the
        /// likelihood that the recognition was correct).
        ///
        /// This method does not use the featureSketch argument.
        ///
        /// Postcondition: the shape is of type IO and its Name
        /// property tells what text it was recognized as.
        /// </summary>
        /// <param name="shape">The shape to recognize</param>
        /// <param name="featureSketch">Not used.</param>
        public override void recognize(Sketch.Shape shape, Featurefy.FeatureSketch featureSketch)
        {
            // Prepare the shape for recognition
            SketchOrInkConverter converter = new SketchOrInkConverter();

            _microsoftTextRecognizer.Strokes = converter.convertToInk(shape);

            // Try to recognize the shape
            RecognitionStatus status;
            RecognitionResult result;

            result = _microsoftTextRecognizer.Recognize(out status);

            // Origanize the results
            string shapeName   = "";
            float  probability = 0F;

            if ((result != null) && (status == RecognitionStatus.NoError))
            {
                shapeName = result.TopString;
                switch (result.TopConfidence)
                {
                case RecognitionConfidence.Poor:
                    probability = .1F;
                    break;

                case RecognitionConfidence.Intermediate:
                    probability = .5F;
                    break;

                case RecognitionConfidence.Strong:
                    probability = .9F;
                    break;
                }
            }

            // Update the shape to reflect these results
            if (debug)
            {
                Console.WriteLine("Found input/output label: " + shapeName + " (confidence = " + probability + ")");
            }
            shape.setRecognitionResults(LogicDomain.TEXT, probability, shapeName);
        }
示例#22
0
        /// <summary>
        /// Uses the RecognitionInterfaces.Recognizer recognize method
        /// which recognizes and assigns the type of a shape.  This
        /// implementation allows the use of the learnFromExample
        /// method in Interface Functions.
        /// </summary>
        /// <param name="shape">The shape to recognize</param>
        /// <param name="featureSketch">The featureSketch to use</param>
        public override void recognize(Sketch.Shape shape, Featurefy.FeatureSketch featureSketch)
        {
            BitmapSymbol      unknown = new BitmapSymbol(shape.SubstrokesL);
            List <SymbolRank> results = unknown.Recognize(_templates);

            if (results.Count > 0)
            {
                // Populate the dictionary of alterateTypes with all of the ShapeTypes in results
                Dictionary <ShapeType, double> alternateTypes = new Dictionary <ShapeType, double>();

                if (debug)
                {
                    Console.WriteLine("\nRecognition results: ");
                }

                foreach (SymbolRank result in results)
                {
                    if (!alternateTypes.ContainsKey(result.SymbolType))
                    {
                        alternateTypes.Add(result.SymbolType, getProbability(result.SymbolType, results));
                    }

                    if (debug)
                    {
                        Console.WriteLine(result.SymbolType + " with template " + result.SymbolName);
                    }
                }

                ShapeType type = results[0].SymbolType;          // the most likely type

                float probability = (float)alternateTypes[type]; // grab the probability of our most likely type

                alternateTypes.Remove(type);                     // the most likely type is NOT an alternate

                shape.setRecognitionResults(
                    type,
                    probability,
                    alternateTypes,
                    results[0].BestOrientation,
                    results[0].SymbolName);
            }
        }
示例#23
0
        /// <summary>
        /// Create a Recognition Manager for the given sketch panel with default settings.
        /// Settings are loaded from file settings.txt
        /// </summary>
        /// <param name="p">a sketch panel to manage</param>
        public RecognitionManager(SketchPanelLib.SketchPanel p)
        {
            // Load settings from text file
            string directory        = AppDomain.CurrentDomain.BaseDirectory;
            string SettingsFilename = directory + "//settings.txt";

            _filenames = Files.SettingsReader.readSettings(SettingsFilename);

            // Initialize the recognition machines
            _domain           = ContextDomain.CircuitDomain.GetInstance();
            _strokeClassifier = RecognitionPipeline.createDefaultClassifier();
            _strokeGrouper    = RecognitionPipeline.createDefaultGrouper();
            _sketchRecognizer = RecognitionPipeline.createDefaultRecognizer();
            _connector        = RecognitionPipeline.createDefaultConnector();
            _refinement       = RecognitionPipeline.createDefaultRefiner(_connector, _sketchRecognizer);

            // Add events
            _panel         = p;
            _featuresketch = p.InkSketch.FeatureSketch;
        }
示例#24
0
        /// <summary>
        /// Pick out the shapes that still that do not match their context,
        /// try grouping neighboring strokes into them (i.e. they steal a neighboring stroke),
        /// and if this puts it in context, keep it.
        ///
        /// NOTE: we're only considering gates at the moment
        /// </summary>
        public void StrokeStealRefine(Featurefy.FeatureSketch featureSketch)
        {
            foreach (Sketch.Shape shape in featureSketch.Sketch.Shapes)
            {
                bool valid = _domain.IsProperlyConnected(shape);

                // If the shape was not specified by the user, doesn't fit its
                // context, and is a gate
                if (!valid && !shape.AlreadyGrouped && shape.Classification == LogicDomain.GATE_CLASS)
                {
                    float            bestProb      = 0F;
                    Sketch.Substroke bestSubstroke = null;

                    // For each neighboring shape, try stealing a stroke until
                    // one fits well given that the user did not specify it
                    List <Sketch.Shape> neighbors = featureSketch.Sketch.neighboringShapes(shape);
                    foreach (Sketch.Shape neighbor in neighbors)
                    {
                        if (!neighbor.AlreadyGrouped)
                        {
                            foreach (Sketch.Substroke substroke in neighbor.Substrokes)
                            {
                                float stealProb = strokeStealHelpfulness(shape, substroke, featureSketch);
                                if (stealProb > bestProb)
                                {
                                    bestProb      = stealProb;
                                    bestSubstroke = substroke;
                                }
                            }
                        }
                    }

                    // Only steal the substroke that gives the best new shape
                    stealStroke(shape, bestSubstroke, featureSketch);
                }
            }
        }
示例#25
0
        /// <summary>
        /// Uses the cached result if it is available, or makes a call to the inner
        /// recognizer otherwise. This method is thread-safe provided that
        ///    1. the underlying recognizer's "recognize" method is thread-safe
        ///    2. this method will not be called concurrently on the same shape
        /// </summary>
        /// <param name="shape">the shape to recognize</param>
        /// <param name="featureSketch">the featureSketch to work on</param>
        public override void recognize(Sketch.Shape shape, Featurefy.FeatureSketch featureSketch)
        {
            int hash = shape.GetHashCode();

            // Safely determine if the value is already cached. We never remove cached
            // results, so it is safe to release the lock afterward.
            bool isCached;

            lock (_typeResults)
                isCached = _typeResults.ContainsKey(hash);

            if (isCached)
            {
                // Write the cached results to the shape. Since we can assume that
                // we don't need to lock the shape, all we need to synchronize on is
                // the dictionary when we retreive results.
                ShapeType type;
                float     prob;
                lock (_typeResults)
                {
                    type = LogicDomain.getType(_typeResults[hash]);
                    prob = _probabilityResults[hash];
                }
                shape.setRecognitionResults(type, prob);
            }
            else
            {
                // We only need a lock here when we write results to the dictionary.
                _innerRecognizer.recognize(shape, featureSketch);
                lock (_typeResults)
                {
                    _typeResults.Add(hash, shape.Type.Name);
                    _probabilityResults.Add(hash, shape.Probability);
                }
            }
        }
示例#26
0
        public virtual void orient(Shape shape, Featurefy.FeatureSketch featureSketch)
        {
            ShapeType    type = shape.Type;
            BitmapSymbol defn = new BitmapSymbol();

            // TODO: should we use multiple templates, or just one?
            foreach (BitmapSymbol template in _templates)
            {
                if (template.SymbolType == type)
                {
                    defn = template;
                    break;
                }
            }

            BitmapSymbol unknown = _shapesToSymbols[shape];

            shape.Orientation = unknown.bestOrientation(defn);

#if JESSI
            Console.WriteLine("The final shape orientation is " + shape.Orientation);
            Console.WriteLine();
#endif
        }
示例#27
0
 /// <summary>
 /// Ensure that all the shape names in the sketch are unique.
 /// </summary>
 public void MakeShapeNamesUnique(Featurefy.FeatureSketch _featuresketch)
 {
     new Refiner.UniqueNamer().process(_featuresketch);
 }
示例#28
0
 /// <summary>
 /// Recognizes a shape and updates values in shape (through setRecognitionResults).
 /// Also notes which template was used for template ranking purposes.
 /// </summary>
 /// <param name="shape">The shape to recognize</param>
 /// <param name="featureSketch">The featureSketch containing the shape.
 ///     Never used in this function, but kept around because this function is overriding another.</param>
 public override void recognize(Sketch.Shape shape, Featurefy.FeatureSketch featureSketch)
 {
     base.recognize(shape, featureSketch);
     //++_templateUsage[shape.Type][base.findTemplate(shape.TemplateName)]; // increment the number of times that BitmapSymbol has been used
 }
示例#29
0
 /// <summary>
 /// Rerecognizes the strokes given as a single group
 /// </summary>
 public void RerecognizeGroup(Sketch.Shape shape, Featurefy.FeatureSketch _featuresketch)
 {
     regroupShape(shape, _featuresketch);
     shape.ClearConnections();
     _connector.connect(shape, _featuresketch.Sketch);
 }
示例#30
0
        // It should be noted that the functions to create the ARFF files are somewhat of a hack. They work, on my computer.
        // They may also work on yours. Hopefully once the ARFF files are created nobody will ever have to use these functions
        // again, but we're leaving them here anyways. Use at your own risk and feel free to email me if you have questions.
        //      Good luck!  -- Jessi Peck, Sketcher 2011, [email protected]
        /// <summary>
        /// Create ARFF files for the classifier and grouper from a set of sketches
        /// </summary>
        /// <param name="fileList">a list of sketch file names</param>
        public static void createARFFs(List <string> fileList)
        {
            // These dictionaries will store the feature values for each of the ARFF files we're creating
            Dictionary <double[], string> strokeValues = new Dictionary <double[], string>();
            Dictionary <string, Dictionary <double[], string> > groupValues = new Dictionary <string, Dictionary <double[], string> >();

            groupValues.Add(TEXT, new Dictionary <double[], string>());
            groupValues.Add(WIRE, new Dictionary <double[], string>());
            groupValues.Add(GATE, new Dictionary <double[], string>());

            // These lists will store the names of the features for the ARFF files we're creating
            List <string> strokeNames = new List <string>();
            List <string> groupNames  = new List <string>();

            // Stores each stroke's classification.
            Dictionary <Substroke, string> strokeClassifications = new Dictionary <Substroke, string>();

            Dictionary <string, string> settingsFiles = Files.SettingsReader.readSettings();

            bool firstFile = true;

            foreach (string file in fileList)
            {
                if (!file.EndsWith(".xml"))
                {
                    continue;
                }                                         // only read .xml files

                //Console.WriteLine("Reading file " + file);

                // Load the sketch from the file and make it into a feature sketch
                Sketch.Sketch           sketch        = new ConverterXML.ReadXML(file).Sketch;
                Featurefy.FeatureSketch featureSketch = Featurefy.FeatureSketch.MakeFeatureSketch(new Sketch.Project(sketch), settingsFiles);

                // Get featureSketch to tell you the feature values for each individual stroke in the sketch
                Dictionary <Substroke, double[]> classificationDict = new Dictionary <Substroke, double[]>();
                foreach (Substroke substroke in sketch.Substrokes)
                {
                    classificationDict.Add(substroke, featureSketch.GetValuesSingle(substroke));
                }

                // Classify each substroke based on what shape it's a part of
                foreach (Sketch.Shape shape in sketch.Shapes)
                {
                    string classif = shape.Type.Classification;
                    if (classif == UNKNOWN)
                    {
                        continue;
                    }

                    foreach (Substroke stroke in shape.Substrokes)
                    {
                        strokeValues.Add(classificationDict[stroke], classif);
                        strokeClassifications.Add(stroke, classif);
                    }
                }

                #region Bad XML File Catcher
                // This shouldn't be necessary if your XML files are properly formatted,
                // but it's here just in case.
                List <Substroke> badStrokes = new List <Substroke>();
                foreach (Substroke strokeToCheck in classificationDict.Keys)
                {
                    if (classificationDict[strokeToCheck].Length != 27)
                    {
                        Console.WriteLine("OH MAN. GET VALUES SINGLE FAILS.");
                        Console.WriteLine("Your length of features is " + classificationDict[strokeToCheck].Length + " elements long.");
                        badStrokes.Add(strokeToCheck);
                    }
                }

                foreach (Substroke naughtyStroke in badStrokes)
                {
                    strokeValues.Remove(classificationDict[naughtyStroke]);
                    strokeClassifications.Remove(naughtyStroke);
                    classificationDict.Remove(naughtyStroke);
                    Console.WriteLine("You will never see that stroke again.");
                }
                #endregion

                // Get featureSketch to tell you the feature values for each pair of strokes in the sketch
                Dictionary <string, Dictionary <Featurefy.FeatureStrokePair, double[]> > grouperDict = featureSketch.GetValuesPairwise(strokeClassifications);

                // You only need to call this once, might as well be on the first file you do.
                if (firstFile)
                {
                    strokeNames = featureNames(featureSketch.FeatureListSingle); // set up the list of feature names for stroke classification
                    groupNames  = featureNames(featureSketch.FeatureListPair);   // set up the list of feature names for stroke grouping
                    firstFile   = false;
                }

                // Adds feature values for grouping to groupValues
                getGroupValues(ref groupValues, grouperDict);
            }
            // Populate the lists of class names
            List <string> strokeClasses, groupClasses;
            classNames(out strokeClasses, out groupClasses);

            string directory = AppDomain.CurrentDomain.BaseDirectory;

            // write ARFF for stroke classifier
            writeARFFfile(directory + STROKE + ARFF, strokeNames, strokeValues, strokeClasses);

            // write ARFF for stroke grouper x3
            writeARFFfile(directory + TEXT_GROUP + ARFF, groupNames, groupValues[TEXT], groupClasses);
            //writeARFFfile(directory + WIRE_GROUP + ARFF, groupNames, groupValues[WIRE], groupClasses);
            writeARFFfile(directory + GATE_GROUP + ARFF, groupNames, groupValues[GATE], groupClasses);

            //Console.WriteLine("ARFF files created!");
        }