/// <summary>
        /// Constructor
        /// </summary>
        /// <param name="sketch">SketchPanel to add a label to</param>
        /// <param name="inkStrokes">InkOverlay strokes</param>
        /// <param name="inkStrokes">A StrokeCollection strokes</param>
        /// <param name="label">Label to apply</param>
        public ApplyLabelCmd(SketchPanel sketch, StrokeCollection inkStrokes,
                             string label, bool userSpecifiedGroup = true, bool userSpecifiedLabel = true)
        {
            isUndoable = false;

            this.sketchPanel        = sketch;
            this.label              = label;
            this.inkStrokes         = inkStrokes;
            this.userSpecifiedGroup = userSpecifiedGroup;
            this.userSpecifiedLabel = userSpecifiedLabel;
            labelColor              = LogicDomain.getType(label).Color;

            // Save the original labels of the substrokes
            origLabels       = new Dictionary <string, Data.Pair <ShapeType, StrokeCollection> >();
            unlabeledStrokes = new StrokeCollection();

            foreach (Stroke stroke in inkStrokes)
            {
                Sketch.Substroke sub = sketchPanel.InkSketch.GetSketchSubstrokeByInk(stroke);

                if (sub.ParentShape != null)
                {
                    if (!origLabels.ContainsKey(sub.ParentShape.Name))
                    {
                        origLabels[sub.ParentShape.Name] = new Data.Pair <ShapeType, StrokeCollection>(sub.ParentShape.Type, new StrokeCollection());
                    }
                    origLabels[sub.ParentShape.Name].B.Add(stroke);
                }
                else
                {
                    unlabeledStrokes.Add(stroke);
                }
            }
        }
        private Rect centerDrawing()
        {
            removeGate();
            Rect bounds;

            if (gateChooser.SelectedItem == defaultChoice || (string)((ComboBoxItem)gateChooser.SelectedItem).Content == freehandString)
            {
                gate = null;
                return(new Rect());
            }

            gate = LogicDomain.getType((string)((ComboBoxItem)(gateChooser.SelectedItem)).Content);

            // Bounds are currently arbitrary, place shape template in the middle of canvas
            if (gate != LogicDomain.NOTBUBBLE)
            {
                bounds = new Rect(inkCanvas.Width / 2 - GATE_WIDTH / 2, inkCanvas.Height / 2 - GATE_HEIGHT / 2, GATE_WIDTH, GATE_HEIGHT);
            }
            else
            {
                bounds = new Rect(inkCanvas.Width / 2 - NOTBUBBLE_DIAMETER / 2, inkCanvas.Height / 2 - NOTBUBBLE_DIAMETER / 2, NOTBUBBLE_DIAMETER, NOTBUBBLE_DIAMETER);
            }


            // This is so NANDs look like ANDs with NOTBUBBLEs
            // Same goes for all gates in the OR family
            if (gate == LogicDomain.AND)
            {
                bounds.Width = bounds.Width - bounds.Width / 4;
            }
            else if (gate == LogicDomain.OR)
            {
                bounds.Width = bounds.Width - bounds.Width / 6 - bounds.Width / 4;
            }
            else if (gate == LogicDomain.NOR)
            {
                bounds.Width = bounds.Width - bounds.Width / 6;
            }
            else if (gate == LogicDomain.XOR)
            {
                bounds.Width = bounds.Width - bounds.Width / 4;
            }

            DrawingImage drawingImage = new DrawingImage(gateDrawer.DrawGate(gate, bounds, false, true));

            gateImage        = new Image();
            gateImage.Source = drawingImage;

            InkCanvas.SetLeft(gateImage, bounds.Left);
            InkCanvas.SetTop(gateImage, bounds.Top);

            inkCanvas.Children.Add(gateImage);
            return(bounds);
        }
        /// <summary>
        /// Convert a sketch from
        /// </summary>
        /// <param name="originalSketch"></param>
        public void translateSketch(ref Sketch.Sketch originalSketch)
        {
            foreach (Shape shape in originalSketch.Shapes)
            {
                ShapeType type = shape.Type;

                if (labelMap.ContainsKey(type.Name)) // Convert it if it's in our map
                {
                    shape.Type = LogicDomain.getType(labelMap[type.Name]);
                }
                else if (this.verbose)
                {
                    System.Console.Error.WriteLine("Type {0} not specified in label map", type);
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Constructor
        /// </summary>
        public RemoveLabelCmd(SketchPanel sketch, StrokeCollection inkStrokes, string label)
        {
            isUndoable = true;

            sketchPanel     = sketch;
            this.inkStrokes = inkStrokes;
            this.label      = Domain.LogicDomain.getType(label);

            labelColor = LogicDomain.getType(label).Color;

            labeledStrokes = new StrokeCollection();
            foreach (Stroke stroke in inkStrokes)
            {
                if (stroke.DrawingAttributes.Color == labelColor)
                {
                    labeledStrokes.Add(stroke);
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Loads the given domain file.
        /// <seealso cref="Labeler.MainForm.LoadDomain"/>
        /// </summary>
        /// <param name="domainFilePath">the file path to load</param>
        /// <returns>the DomainInfo loaded</returns>
        public static DomainInfo LoadDomainInfo(string domainFilePath)
        {
            // Check to see if there is a domain file to load for this feedback mechanism
            if (domainFilePath == null)
            {
                return(null);
            }

            // Make sure file exists
            if (!System.IO.File.Exists(domainFilePath))
            {
                return(null);
            }

            // Load domain file
            System.IO.StreamReader sr = new System.IO.StreamReader(domainFilePath);

            DomainInfo domain = new DomainInfo();
            string     line   = sr.ReadLine();

            string[] words = line.Split(null);

            // The first two lines are useless
            line = sr.ReadLine();
            line = sr.ReadLine();

            // Then the rest are labels
            while (line != null && line != "")
            {
                words = line.Split(null);

                string label = words[0];
                string color = words[1];

                domain.AddLabel(LogicDomain.getType(label), (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(color));
                line = sr.ReadLine();
            }

            sr.Close();

            return(domain);
        }
Exemple #6
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);
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Essentially re-trains the classifier using the stored instances
        /// </summary>
        public void UpdateClassifier()
        {
            // List of each class - go through all examples once to get complete list of classes
            List <ShapeType> classes = new List <ShapeType>();

            foreach (KeyValuePair <string, Dictionary <string, object> > example in _examples)
            {
                if (!classes.Contains(LogicDomain.getType(example.Key)))
                {
                    classes.Add(LogicDomain.getType(example.Key));
                }
            }


            #region Initialize Probability stuff
            //////////////////////////////////////////////////
            //////////////////////////////////////////////////
            // 4 Pieces of information needed to calculate all
            // feature likelyhoods given class

            // needed for priors and feature value likelyhood
            int numExamples = _examples.Count;
            if (numExamples == 0)
            {
                return;
            }

            // Prior probabilities of a class
            // Initialize them all to have 0.0 prior probability
            Dictionary <ShapeType, double> Priors = new Dictionary <ShapeType, double>();
            foreach (ShapeType cls in classes)
            {
                Priors.Add(cls, 0.0);
            }

            // Likelyhood of a feature value
            // Initialize all top level dictionary entries
            Dictionary <string, Dictionary <object, double> > FeatureValue_Likelyhood =
                new Dictionary <string, Dictionary <object, double> >();
            foreach (string feature in _featureNames)
            {
                FeatureValue_Likelyhood.Add(feature, new Dictionary <object, double>());
            }

            // Likelyhood of a class given a feature value
            // Initialize all top and 2nd level dictionary entries
            Dictionary <string, Dictionary <object, Dictionary <ShapeType, double> > > Class_Given_FeatureValue_Likelyhood =
                new Dictionary <string, Dictionary <object, Dictionary <ShapeType, double> > >();
            foreach (string feature in _featureNames)
            {
                Class_Given_FeatureValue_Likelyhood.Add(feature, new Dictionary <object, Dictionary <ShapeType, double> >());
            }
            //////////////////////////////////////////////////
            //////////////////////////////////////////////////
            #endregion


            #region Initialize Counting Stuff
            //////////////////////////////////////////////////
            //////////////////////////////////////////////////
            // Counts necessary to calculate likelyhoods

            // How many occurances there are of each class - for prior probabilities
            // Initialize all the class counts to 0
            Dictionary <string, int> Count_Class = new Dictionary <string, int>();
            foreach (ShapeType cls in classes)
            {
                Count_Class.Add(cls.Name, 0);
            }

            // For FeatureValueLikelyhood
            //   - Count of the number of times Feature_i = f
            // Initialize all top level dictionary entries
            Dictionary <string, Dictionary <object, int> > Count_Feature_Eq_f =
                new Dictionary <string, Dictionary <object, int> >(_featureNames.Count);
            foreach (string feature in _featureNames)
            {
                Count_Feature_Eq_f.Add(feature, new Dictionary <object, int>());
            }

            // Given a class, how many times was this value observed
            // For ClassGivenFeatureLikelyhood
            //   - Count of the number of times Class_j = c AND Feature_i = f
            // Initialize all top and 2nd level dictionary entries
            // First dictionary = feature name to 2nd dictionary
            // Second dictionary = feature value to 3rd dictionary
            // Third dictionary = class name to occurance count
            Dictionary <string, Dictionary <object, Dictionary <string, int> > > Count_Class_Eq_c_given_Feature_Eq_f =
                new Dictionary <string, Dictionary <object, Dictionary <string, int> > >();
            foreach (string feature in _featureNames)
            {
                Count_Class_Eq_c_given_Feature_Eq_f.Add(feature, new Dictionary <object, Dictionary <string, int> >());
            }
            //////////////////////////////////////////////////
            //////////////////////////////////////////////////
            #endregion


            #region Go through every single example and count feature occurances and class occurances
            foreach (KeyValuePair <string, Dictionary <string, object> > example in _examples)
            {
                string className = example.Key;
                Count_Class[className]++;

                Dictionary <string, object> features = example.Value;

                // Count the number of occurances of each feature value.
                foreach (string fName in _featureNames)
                {
                    // feature value
                    object value;

                    if (features.TryGetValue(fName, out value))
                    {
                        // count of instances of this value across all classes
                        Dictionary <object, int> count;
                        if (Count_Feature_Eq_f.TryGetValue(fName, out count))
                        {
                            if (count.ContainsKey(value))
                            {
                                count[value]++;
                            }
                            else
                            {
                                count.Add(value, 1);
                            }
                        }

                        // count of instances of this value in this class ONLY
                        Dictionary <string, int> countPerClass;
                        if (Count_Class_Eq_c_given_Feature_Eq_f[fName].TryGetValue(value, out countPerClass))
                        {
                            if (countPerClass.ContainsKey(className))
                            {
                                countPerClass[className]++;
                            }
                            else
                            {
                                countPerClass.Add(className, 1);
                            }
                        }
                        else
                        {
                            Dictionary <string, int> clsCount = new Dictionary <string, int>();
                            clsCount.Add(className, 1);
                            Count_Class_Eq_c_given_Feature_Eq_f[fName].Add(value, clsCount);
                        }
                    }
                }
            }
            #endregion


            #region Calculate all the probabilities

            // Get the prior probabilities for each class
            foreach (ShapeType cls in classes)
            {
                int count;
                if (Count_Class.TryGetValue(cls.Name, out count))
                {
                    double prior = (double)count / numExamples;
                    Priors[cls] = prior;
                }
            }

            // Likelyhood for feature value throughout all classes
            foreach (string fName in _featureNames)
            {
                Dictionary <object, int> count_for_Feature_i;
                if (Count_Feature_Eq_f.TryGetValue(fName, out count_for_Feature_i))
                {
                    foreach (KeyValuePair <object, int> pair in count_for_Feature_i)
                    {
                        double p_F = (double)pair.Value / numExamples;
                        p_F = Math.Min(Math.Max(p_F, MIN_PROBABILITY), 1.0 - MIN_PROBABILITY);
                        if (FeatureValue_Likelyhood[fName].ContainsKey(pair.Key))
                        {
                            FeatureValue_Likelyhood[fName][pair.Key] = p_F;
                        }
                        else
                        {
                            FeatureValue_Likelyhood[fName].Add(pair.Key, p_F);
                        }
                    }
                }
            }

            // Likelyhood for feature value per class
            foreach (string fName in _featureNames)
            {
                foreach (KeyValuePair <object, Dictionary <string, int> > pair in Count_Class_Eq_c_given_Feature_Eq_f[fName])
                {
                    object value = pair.Key;
                    Class_Given_FeatureValue_Likelyhood[fName].Add(value, new Dictionary <ShapeType, double>());
                    double p_F = FeatureValue_Likelyhood[fName][value];


                    int sum = 0;
                    foreach (KeyValuePair <string, int> clsCount in pair.Value)
                    {
                        sum += clsCount.Value;
                    }

                    foreach (ShapeType cls in classes)
                    {
                        if (pair.Value.ContainsKey(cls.Name))
                        {
                            double p_C         = Priors[cls];
                            double v           = (double)pair.Value[cls.Name] / sum;
                            double p_C_given_F = Math.Min(Math.Max(v, MIN_PROBABILITY), 1.0 - MIN_PROBABILITY);
                            double p_F_given_C = p_C_given_F * p_F / p_C;
                            Class_Given_FeatureValue_Likelyhood[fName][value].Add(cls, p_F_given_C);
                        }
                        else
                        {
                            Class_Given_FeatureValue_Likelyhood[fName][value].Add(cls, MIN_PROBABILITY);
                        }
                    }
                }
            }


            #endregion

            // Sort the dictionaries...for fun and ease of reading when debugging
            Dictionary <string, Dictionary <object, double> > fvl = new Dictionary <string, Dictionary <object, double> >();
            foreach (KeyValuePair <string, Dictionary <object, double> > pair in FeatureValue_Likelyhood)
            {
                List <object> v_keys = new List <object>(pair.Value.Keys);
                v_keys.Sort();
                Dictionary <object, double> v = new Dictionary <object, double>();
                foreach (object value in v_keys)
                {
                    v.Add(value, pair.Value[value]);
                }

                fvl.Add(pair.Key, v);
            }

            List <ShapeType> p_keys = new List <ShapeType>(Priors.Keys);
            p_keys.Sort();
            Dictionary <ShapeType, double> p = new Dictionary <ShapeType, double>();
            foreach (ShapeType key in p_keys)
            {
                p.Add(key, Priors[key]);
            }


            Dictionary <string, Dictionary <object, Dictionary <ShapeType, double> > > cgfvl = new Dictionary <string, Dictionary <object, Dictionary <ShapeType, double> > >();
            foreach (KeyValuePair <string, Dictionary <object, Dictionary <ShapeType, double> > > pair in Class_Given_FeatureValue_Likelyhood)
            {
                List <object> v_keys = new List <object>(pair.Value.Keys);
                v_keys.Sort();
                Dictionary <object, Dictionary <ShapeType, double> > v = new Dictionary <object, Dictionary <ShapeType, double> >();
                foreach (object value in v_keys)
                {
                    v.Add(value, pair.Value[value]);
                }

                cgfvl.Add(pair.Key, v);
            }


            // Update the Classifier
            _classifier = new NaiveBayes(classes, _featureNames, p, fvl, cgfvl);
        }
Exemple #8
0
 public Color GetColor(string label)
 {
     return(GetColor(LogicDomain.getType(label)));
 }