예제 #1
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);
                }
            }
        }
예제 #2
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);
                }
            }
        }
예제 #3
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);
        }
예제 #4
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);
                }
            }
        }
        /// <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 + ")");
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Goes through every shape in the sketch and creates a text box for it
        /// </summary>
        private void MakeTextBlocks()
        {
            //System.Console.WriteLine("Making Text Boxes");
            toolTips.Clear();

            foreach (Sketch.Shape shape in sketchPanel.Sketch.Shapes)
            {
                if (shape.Substrokes.Length == 0)
                {
                    return;
                }

                // Set Content and Color
                Popup newTextBlock = new Popup();

                ContextDomain.ContextDomain contextDomain = ContextDomain.CircuitDomain.GetInstance();

                // Make text box.  Feel free to change FontWeight, FontSize, etc.
                TextBlock newChild = new TextBlock();

                if (debug)
                {
                    newChild.Text  = shape.Name + " (" + shape.Type.Name + ")";
                    newChild.Text += "\nOrientation: " + shape.Orientation;
                    newChild.Text += "\nTemplate: " + shape.TemplateName;
                    //newChild.Text += "\nConnected shapes: ";
                    //foreach (Sketch.Shape connectedShape in shape.ConnectedShapes)
                    //newChild.Text += connectedShape.Name + ", ";
                    newChild.Text += "\nProperly Connected: " + (contextDomain.IsProperlyConnected(shape) ? "yes" : "no");
                }
                else
                {
                    newChild.Text = shape.Type.Name;
                }

                newChild.Background = Brushes.Transparent;
                newChild.FontWeight = System.Windows.FontWeights.Bold;

                newTextBlock.Child  = newChild;
                newTextBlock.IsOpen = false;

                newTextBlock.AllowsTransparency = true;

                newTextBlock.Visibility      = System.Windows.Visibility.Visible;
                newTextBlock.PlacementTarget = sketchPanel.InkCanvas;
                newTextBlock.Placement       = PlacementMode.RelativePoint;

                // Find strokes
                StrokeCollection strokes = new StrokeCollection();
                foreach (Sketch.Substroke sub in shape.Substrokes)
                {
                    strokes.Add(sketchPanel.InkSketch.GetInkStrokeBySubstroke(sub));
                }

                // Set Position and Add to Canvas and our collection
                newTextBlock.VerticalOffset   = strokes.GetBounds().Top + strokes.GetBounds().Height / 2;
                newTextBlock.HorizontalOffset = strokes.GetBounds().Left + strokes.GetBounds().Width / 2;
                subscribed = true;
                //sketchPanel.InkCanvas.Children.Add(newTextBlock);
                toolTips.Add(shape, newTextBlock);
            }
        }