示例#1
0
    public override void Show()
    {
        base.Show();
        arrivedInTime   = true;
        imageRecognizer = FindObjectOfType <ImageRecognizer>();
        Trip trip = GameManager.Instance.Player.Trip;

        fromTo.text = trip.CurrentCity.Name + " - " + trip.CurrentTransport.Option.To.Name;
        LoadTransportIcon();
        scanMarkerButton.SetActive(false);

        SetupEventGroup();
        eventGroup.Start();

        if (eventGroup.GetRemainingSeconds() > 25)
        {
            //MinigameController.Instance.LoadGame();
            quizScreen.SetActive(true);
            LoadQuestion();
            minigameSuccess = false;
            minigamePlaying = false;
        }
        else
        {
            minigamePlaying = false;
            minigameSuccess = true;
        }
    }
示例#2
0
        /// <summary>
        /// Construct the training data for the combo recognizer.
        /// </summary>
        /// <param name="testData">the data to test on</param>
        /// <param name="rubine">the rubine recognizer</param>
        /// <param name="dollar">the dollar recognizer</param>
        /// <param name="zernike">the zernike recognizer</param>
        /// <param name="image">the image recognizer</param>
        /// <returns>a list of tuples (s,f) where s is a shape type and f is a set of features</returns>
        private static List <KeyValuePair <ShapeType, Dictionary <string, object> > > TrainingDataCombo(
            List <Shape> testData,
            RubineRecognizerUpdateable rubine,
            DollarRecognizer dollar,
            ZernikeMomentRecognizerUpdateable zernike,
            ImageRecognizer image)
        {
            List <KeyValuePair <ShapeType, Dictionary <string, object> > > data = new List <KeyValuePair <ShapeType, Dictionary <string, object> > >();

            foreach (Shape shape in testData)
            {
                string z = zernike.Recognize(shape.SubstrokesL);

                List <ShapeType> img = image.Recognize(shape.SubstrokesL);

                List <string> r    = new List <string>();
                List <string> dAvg = new List <string>();
                List <string> d    = new List <string>();

                foreach (Substroke s in shape.SubstrokesL)
                {
                    r.Add(rubine.Recognize(s));
                    dAvg.Add(dollar.RecognizeAverage(s));
                    d.Add(dollar.Recognize(s));
                }

                Dictionary <string, object> features = ComboRecognizer.GetFeatures(shape.SubstrokesL.Count, z, img, r, dAvg, d);
                data.Add(new KeyValuePair <ShapeType, Dictionary <string, object> >(shape.Type, features));
            }

            return(data);
        }
示例#3
0
        public async Task <ImageInfoGet> Put([FromBody] object imageForServer)
        {
            Console.Out.WriteLine("Put");
            var des = JsonConvert.DeserializeObject <ImageInfoGet>(imageForServer.ToString());

            var tmp   = new ImageInfoGet();
            var image = dB.GetImage(des.Path, des.JpegCover);

            if (image == null)
            {
                ImageRecognizer imageRecognizer = new ImageRecognizer();

                var info = imageRecognizer.RecognizeImage(Convert.FromBase64String(des.JpegCover), des.Path);

                tmp.Class      = info.className[0];
                tmp.Confidence = info.confidence[0];

                tmp.Name      = des.Name;
                tmp.Path      = des.Path;
                tmp.JpegCover = des.JpegCover;

                dB.AddToDB(tmp);

                return(tmp);
            }
            return(image);
        }
示例#4
0
        static void Main(string[] args)
        {
            DirectoryInfo myDirectory = new DirectoryInfo(args.FirstOrDefault() ?? "images");

            ImageRecognizer obj = new ImageRecognizer(myDirectory, new WriteToConsole());

            var enterThread = new Thread(new ThreadStart(() =>
            {
                while (Console.ReadKey().Key != ConsoleKey.Enter)
                {
                }
                ImageRecognizer.cancelTokenSource.Cancel();
            }));

            enterThread.Start();
            obj.GetResults();

            // foreach (var item in obj.result)
            // {
            //     Console.WriteLine("Predicting contents of image...");
            //     Console.Write(item);
            //     Console.WriteLine();
            // }
            System.Environment.Exit(0);
        }
        public string DetectImage(byte[] img_bytes, string path)
        {
            Tuple <string, string> class_and_counter;
            string recognizedClass, counter;

            using (var context = new ImageContext())
            {
                class_and_counter = context.TryGetRecognizedImage(img_bytes);
            }
            if (class_and_counter != null)
            {
                recognizedClass = class_and_counter.Item1;
                counter         = class_and_counter.Item2;
            }
            else
            {
                using (var ms = new MemoryStream(img_bytes))
                {
                    Image img        = Image.FromStream(ms);
                    var   recognizer = new ImageRecognizer();
                    recognizedClass = recognizer.DetectImageClassSync(img, modelPath);
                    counter         = "0";
                }
                using (var context = new ImageContext())
                {
                    context.SaveRecognizedImage(img_bytes, recognizedClass);
                }
            }
            var response = new JsonObject();

            response.Add("class", recognizedClass);
            response.Add("db_queries", counter);
            response.Add("image_path", path);
            return(response.ToString());
        }
示例#6
0
        private static ComboRecognizer CreateCombo(string user, string dir)
        {
            string dollarStr   = dir + "\\Dollar" + user + ".dr";
            bool   dollarBool  = File.Exists(dollarStr);
            string rubineStr   = dir + "\\RubineLite" + user + ".rr";
            bool   rubineBool  = File.Exists(rubineStr);
            string zernikeStr  = dir + "\\ZernikeLite" + user + ".zr";
            bool   zernikeBool = File.Exists(zernikeStr);
            string imageStr    = dir + "\\Image" + user + ".ir";
            bool   imageBool   = File.Exists(imageStr);

            if (!(dollarBool && rubineBool && zernikeBool && imageBool))
            {
                return(null);
            }

            DollarRecognizer        dr = DollarRecognizer.Load(dollarStr);
            RubineRecognizer        rr = RubineRecognizer.Load(rubineStr);
            ZernikeMomentRecognizer zr = ZernikeMomentRecognizer.Load(zernikeStr);
            ImageRecognizer         ir = ImageRecognizer.Load(imageStr);

            ComboRecognizer combo = new ComboRecognizer(rr, dr, zr, ir);

            return(combo);
        }
 /// <summary>
 /// Constructor which takes in pre-trained recognizers, as well
 /// as a pre-trained Classifier (Naive Bayes)
 /// </summary>
 /// <param name="rubine">Pre-Trained Rubine Recognizer</param>
 /// <param name="dollar">Pre-Trained Dollar Recognizer</param>
 /// <param name="zernike">Pre-Trained Zernike Recognizer</param>
 /// <param name="image">Pre-Trained Image Recognizer</param>
 /// <param name="classifier">Pre-Trained NaiveBayes Classifier</param>
 public ComboRecognizer(RubineRecognizer rubine, DollarRecognizer dollar, ZernikeMomentRecognizer zernike, ImageRecognizer image, NaiveBayesUpdateable classifier)
 {
     _rubine          = rubine;
     _dollar          = dollar;
     _zernike         = zernike;
     _image           = image;
     _comboClassifier = classifier;
 }
示例#8
0
 public ImageSaver(Activity activity, Context context, Camera2Fragment owner, Image image)
 {
     this.owner      = owner;
     this.context    = context;
     this.activity   = activity;
     imageRecognizer = new ImageRecognizer(context, activity);
     mImage          = image ?? throw new System.ArgumentNullException("image");
 }
 /// <summary>
 /// Deserialization Constructor
 /// </summary>
 /// <param name="info"></param>
 /// <param name="ctxt"></param>
 public ComboRecognizer(SerializationInfo info, StreamingContext ctxt)
 {
     //Get the values from info and assign them to the appropriate properties
     _dollar          = (DollarRecognizer)info.GetValue("dollar", typeof(DollarRecognizer));
     _image           = (ImageRecognizer)info.GetValue("image", typeof(ImageRecognizer));
     _rubine          = (RubineRecognizer)info.GetValue("rubine", typeof(RubineRecognizer));
     _zernike         = (ZernikeMomentRecognizer)info.GetValue("zernike", typeof(ZernikeMomentRecognizer));
     _comboClassifier = (NaiveBayesUpdateable)info.GetValue("comboClassifier", typeof(NaiveBayesUpdateable));
 }
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();
        ImageRecognizer script = (ImageRecognizer)target;

        if (GUILayout.Button("UploadImage"))
        {
            script.UpdloadScreen();
        }
    }
示例#11
0
 private void button2_Click(object sender, EventArgs e)
 {
     image = new ImageRecognizer((Bitmap)pictureBox1.Image, (byte)separateValue.Value, 0);
     image.TransformToBlackAndWhite();
     pictureBox2.Image = image.OutputImage;
     image.RecognizePixelsToGroups();
     image.PaintFromGroupMap();
     pictureBox3.Image = image.OutputImage;
     DrawHistogram(zedGraphControl2, pictureBox1);
 }
示例#12
0
        static async Task Main(string[] args)
        {
            string imagesPath = (args.Length == 0) ? @"D:\Pictires\Desktop" : args[0];

            ImageRecognizer.onnxModelPath = (args.Length == 2) ? args[1]: "resnet34-v1-7.onnx";

            ImageRecognizer.ImageRecognizerResultUpdate += OutputRecognitionHandler;

            await ImageRecognizer.RecognitionAsync(imagesPath);
        }
示例#13
0
 private void button2_Click(object sender, EventArgs e)
 {
     image = new ImageRecognizer((Bitmap)pictureBox1.Image, (byte)separateValue.Value, (int)MinSquare.Value, (int)KMedianNumber.Value, (double)areaCoefficient.Value,
                                 (double)perimeterCoefficient.Value, (double)elongationCoefficient.Value, (double)DensityCoefficient.Value, (double)massCenterCoefficient.Value);
     image.TransformToBlackAndWhite();
     pictureBox2.Image = image.OutputImage;
     image.RecognizePixelsToGroups();
     image.SetPixelsToObjectGroupsWithFilter();
     image.SetObjectsToGroups();
     image.PaintFromGroupMap();
     pictureBox3.Image = image.OutputImage;
     DrawHistogram(zedGraphControl2, pictureBox1);
 }
示例#14
0
        public async Task <string> Recognize()
        {
            ImageObject[] images = new ImageObject[1] {
                _targObject
            };

            var objLists = await ImageRecognizer.RecognizeAsync(_mvSceneSource, images);

            foreach (var ResultRecog in objLists)
            {
                _success          = ResultRecog.Success;
                _recognizedTarget = ConvertToPoints(ResultRecog.Region);
            }
            return(_sceneImagePath);
        }
示例#15
0
        static void Main(string[] args)
        {
            string modelPath = @"C:\csharp\MnistImageRecognizer\model\model.onnx";
            //  string data_path = Console.ReadLine();
            string dataPath = @"C:\csharp\MnistImageRecognizer\mnist_data_large\";

            ImageRecognizer recognizer = new ImageRecognizer();
            var             results    = recognizer.RunModelInference(modelPath, dataPath);
            string          result;

            while (!results.IsAddingCompleted)
            {
                while (results.TryTake(out result))
                {
                    Console.WriteLine(result);
                }
            }
        }
示例#16
0
        private void DrawTheImage()
        {
            ImageRecognizer imageRecongizer = new ImageRecognizer(this.image, 128, 0);

            imageRecongizer.TransformToBlackAndWhite();
            this.image = imageRecongizer.OutputImage;
            for (int i = 0; i < this.width; i++)
            {
                for (int j = 0; j < this.height; j++)
                {
                    if (this.image.GetPixel(i, j).R == 0)
                    {
                        this.draws[j * this.width + i] = 1;
                    }
                    else
                    {
                        this.draws[j * this.width + i] = -1;
                    }
                }
            }

            this.panel1.Refresh();
        }
示例#17
0
        public void SelectDirectory()
        {
            string stream = folderDialog.OpenFolder();

            if (!stream.Equals(String.Empty))
            {
                Progress = 0;
                ClassVMs = new ObservableCollection <ImageClassVM>();

                db = new Database.ApplicationContext();
                var dir = Directory.GetFiles(stream);
                Images = new ObservableCollection <ImageVM>();
                List <string> fileNames = new List <string>();

                foreach (var file in dir)
                {
                    bool flag     = false;
                    var  fileInfo = new FileInfo(file);

                    foreach (var img in db.Images)
                    {
                        if (fileInfo.FullName == img.Path)
                        {
                            var code1 = ConvertImageToByteArray(fileInfo.FullName);
                            IStructuralEquatable equ = code1;
                            var code2 = img.Details.Image;
                            if (equ.Equals(code2, EqualityComparer <object> .Default))
                            {
                                img.count++;

                                db.SaveChanges();
                                Images.Add(new ImageVM(fileInfo.FullName, fileInfo.Name, img.Confidence, img.ClassName));

                                flag = true;
                                Progress++;

                                dispatcher.BeginInvoke(new Action(() =>
                                {
                                    if (ClassVMs.Count() > 0)
                                    {
                                        bool flag1 = false;
                                        foreach (var imgClass in ClassVMs)
                                        {
                                            if (imgClass.Type == img.ClassName)
                                            {
                                                imgClass.Count++;
                                                flag1 = true;
                                                break;
                                            }
                                        }
                                        if (!flag1)
                                        {
                                            ClassVMs.Add(new ImageClassVM(img.ClassName, 1));
                                        }
                                    }
                                    else
                                    {
                                        ClassVMs.Add(new ImageClassVM(img.ClassName, 1));
                                    }
                                }));
                                break;
                            }
                        }
                    }

                    if (!flag)
                    {
                        Images.Add(new ImageVM(fileInfo.FullName, fileInfo.Name));
                        fileNames.Add(fileInfo.FullName);
                    }
                }

                imageRecognizer = new ImageRecognizer(fileNames, new ForResults(this));
            }
        }
 /// <summary>
 /// Constructor which takes in pre-trained recognizers
 /// </summary>
 /// <param name="rubine">Pre-Trained Rubine Recognizer</param>
 /// <param name="dollar">Pre-Trained Dollar Recognizer</param>
 /// <param name="zernike">Pre-Trained Zernike Recognizer</param>
 /// <param name="image">Pre-Trained Image Recognizer</param>
 public ComboRecognizer(RubineRecognizer rubine, DollarRecognizer dollar, ZernikeMomentRecognizer zernike, ImageRecognizer image)
     : this(rubine, dollar, zernike, image, new NaiveBayesUpdateable())
 {
 }
示例#19
0
 void Start()
 {
     imageRecognizer = FindObjectOfType <ImageRecognizer>();
 }
示例#20
0
        /// <summary>
        /// Arguments
        ///    0: the directory to find files
        ///    1: a string to filter filenames (e.g., "*.xml")
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                return;
            }


            // Get the list of files
            Console.WriteLine("Finding sketch files...");
            List <string> allSketches = new List <string>(System.IO.Directory.GetFiles(args[0], args[1]));

            Console.WriteLine("    found " + allSketches.Count + " sketches");


            // Load all the shapes in all the sketches
            Console.WriteLine("Loading full data set...");
            List <Shape> shapeData = GetShapeData(allSketches);

            Console.WriteLine("    found " + shapeData.Count + " gates");


            // Print classes found
            HashSet <ShapeType> types = new HashSet <ShapeType>();

            foreach (Shape shape in shapeData)
            {
                types.Add(shape.Type);
            }
            Console.WriteLine("Found " + types.Count + " types:");
            foreach (ShapeType type in types)
            {
                Console.WriteLine("    " + type);
            }

            // Save all the shapes to images in the "sketches" folder
            string outputPath = @"sketches\";

            Console.WriteLine("Saving gates to '" + outputPath + "'...");
            if (!System.IO.Directory.Exists(outputPath))
            {
                System.IO.Directory.CreateDirectory(outputPath);
            }
            foreach (Shape shape in shapeData)
            {
                System.Drawing.Bitmap b = ToBitmap.createFromShape(shape, 30, 30, true);
                shape.bitmap = b;
                string filename = String.Format(outputPath + shape.Type + "-{0:x}.png", shape.GetHashCode());
                b.Save(filename);
            }
            Console.WriteLine("    finished saving gates");


            // Train the base recognizers on all the data
            Console.WriteLine("Training recognizers on all data...");

#if false
            Console.WriteLine("    rubine");
            RubineRecognizerUpdateable rubine = new RubineRecognizerUpdateable(shapeData);
            rubine.Save("Rubine.rru");
            rubine.LiteRecognizer.Save("RubineLite.rr");

            Console.WriteLine("    dollar");
            DollarRecognizer dollar = new DollarRecognizer(shapeData);
            dollar.Save("Dollar.dr");
#else
            RubineRecognizerUpdateable rubine = new RubineRecognizerUpdateable();
            rubine.Save("Rubine.rru");
            rubine.LiteRecognizer.Save("RubineLite.rr");

            DollarRecognizer dollar = new DollarRecognizer();
            dollar.Save("Dollar.dr");
#endif

            Console.WriteLine("    zernike");
            ZernikeMomentRecognizerUpdateable zernike = new ZernikeMomentRecognizerUpdateable(shapeData);
            zernike.Save("Zernike.zru");
            zernike.LiteRecognizer.Save("ZernikeLite.zr");

            Console.WriteLine("    image");
            ImageRecognizer image = new ImageRecognizer(shapeData);
            image.Save("Image.ir");

            Console.WriteLine("    finished training recognizers");

            RubineRecognizer        fullRubine  = rubine.LiteRecognizer;
            DollarRecognizer        fullDollar  = dollar;
            ZernikeMomentRecognizer fullZernike = zernike.LiteRecognizer;
            ImageRecognizer         fullImage   = image;


            // Split the data up per-user
            Console.WriteLine("Loading per-user data...");
            Dictionary <string, List <Shape>[]> user2data = GetSketchesPerUser(allSketches);
            Console.WriteLine("    found " + user2data.Count + " users");


            // Foreach user: train each of the recognizers and accumulate training data
            // for the combo recognizer
            List <KeyValuePair <ShapeType, Dictionary <string, object> > > data = new List <KeyValuePair <ShapeType, Dictionary <string, object> > >();
            foreach (KeyValuePair <string, List <Shape>[]> pair in user2data)
            {
                string user = pair.Key;

                ////////////////////////////////////////
                ////////////   Train   /////////////////
                ////////////////////////////////////////

                Console.WriteLine("User: "******"    rubine");
                rubine = new RubineRecognizerUpdateable(trainingSet);
                rubine.Save("Rubine" + user + ".rru");
                rubine.LiteRecognizer.Save("RubineLite" + user + ".rr");

                Console.WriteLine("    dollar");
                dollar = new DollarRecognizer(trainingSet);
                dollar.Save("Dollar" + user + ".dr");
#else
                rubine = new RubineRecognizerUpdateable();
                rubine.Save("Rubine" + user + ".rru");
                rubine.LiteRecognizer.Save("RubineLite" + user + ".rr");

                dollar = new DollarRecognizer();
                dollar.Save("Dollar" + user + ".dr");
#endif

                Console.WriteLine("    zernike");
                zernike = new ZernikeMomentRecognizerUpdateable(trainingSet);
                zernike.Save("Zernike" + user + ".zru");
                zernike.LiteRecognizer.Save("ZernikeLite" + user + ".zr");

                Console.WriteLine("    image");
                image = new ImageRecognizer(trainingSet);
                image.Save("Image" + user + ".ir");
                fullImage = image;

                ////////////////////////////////////////
                //////////// Evaluate //////////////////
                ////////////////////////////////////////


                List <Shape> testingSet = pair.Value[1];

                // Create the training data for the combo recognizer
                List <KeyValuePair <ShapeType, Dictionary <string, object> > > comboTrainingData = TrainingDataCombo(testingSet, rubine, dollar, zernike, image);
                foreach (KeyValuePair <ShapeType, Dictionary <string, object> > pair2 in comboTrainingData)
                {
                    data.Add(pair2);
                }
            }

            if (data.Count == 0)
            {
                throw new Exception("no data!");
            }

            List <string> features = new List <string>();
            foreach (KeyValuePair <ShapeType, Dictionary <string, object> > instance in data)
            {
                foreach (string feature in instance.Value.Keys)
                {
                    if (!features.Contains(feature))
                    {
                        features.Add(feature);
                    }
                }
            }

            Console.WriteLine("Found " + data.Count + " data points and " + features.Count + " features.");

            ComboRecognizer combo = new ComboRecognizer(fullRubine, fullDollar, fullZernike, fullImage);
            combo.TrainCombo(features, data);
            combo.Save("Combo.cru");

            Console.WriteLine("Naive bayes updatable has " + combo.ComboClassifier.Examples.Count + " examples.");
            Console.WriteLine("Naive bayes updatable has " + combo.ComboClassifier.Classifier.Classes.Count + " classes:");
            foreach (ShapeType cls in combo.ComboClassifier.Classifier.Classes)
            {
                Console.WriteLine("    " + cls);
            }

            Console.WriteLine("Press ENTER to continue...");
            Console.ReadLine();
        }
示例#21
0
        /// <summary>
        /// Arguments
        ///    0: the directory to find files
        ///    1: directory to find real-world data (recursive)
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                return;
            }

            // Get the list of files
            Console.WriteLine("Finding sketch files...");
            List <string> allSketches = new List <string>(System.IO.Directory.GetFiles(args[0], "*.xml"));

            Console.WriteLine("    found " + allSketches.Count + " sketches");


            // Load all the shapes in all the sketches
            Console.WriteLine("Loading full data set...");
            List <Shape> shapeData = GetShapeData(allSketches);

            Console.WriteLine("    found " + shapeData.Count + " gates");


            // Print classes found
            HashSet <ShapeType> types = new HashSet <ShapeType>();

            foreach (Shape shape in shapeData)
            {
                types.Add(shape.Type);
            }
            Console.WriteLine("Found " + types.Count + " types:");
            foreach (ShapeType type in types)
            {
                Console.WriteLine("    " + type);
            }

            // Save all the shapes to images in the "sketches" folder
            string outputPath = @"shapes\";

            Console.WriteLine("Saving gates to '" + outputPath + "'...");
            if (!System.IO.Directory.Exists(outputPath))
            {
                System.IO.Directory.CreateDirectory(outputPath);
            }
            foreach (Shape shape in shapeData)
            {
                System.Drawing.Bitmap b = shape.createBitmap(100, 100, true);
                shape.TemplateDrawing = b;
                string filename = String.Format(outputPath + shape.Type + "-{0:x}.png", shape.GetHashCode());
                b.Save(filename);
            }
            Console.WriteLine("    finished saving gates");


            // Train the base recognizers on all the data
            Console.WriteLine("Training recognizers on all data...");

#if false
            Console.WriteLine("    rubine");
            RubineRecognizerUpdateable rubine = new RubineRecognizerUpdateable(shapeData);
            rubine.Save("Rubine.rru");
            rubine.LiteRecognizer.Save("RubineLite.rr");

            Console.WriteLine("    dollar");
            DollarRecognizer dollar = new DollarRecognizer(shapeData);
            dollar.Save("Dollar.dr");

            RubineRecognizerUpdateable rubine = new RubineRecognizerUpdateable();
            rubine.Save("Rubine.rru");
            rubine.LiteRecognizer.Save("RubineLite.rr");

            DollarRecognizer dollar = new DollarRecognizer();
            dollar.Save("Dollar.dr");

            Console.WriteLine("    zernike");
            ZernikeMomentRecognizerUpdateable zernike = new ZernikeMomentRecognizerUpdateable(shapeData);
            zernike.Save("Zernike.zru");
            zernike.LiteRecognizer.Save("ZernikeLite.zr");
#endif

            Console.WriteLine("    adaptive image");
            AdaptiveImageRecognizer adaptiveimage = new AdaptiveImageRecognizer(shapeData);
            adaptiveimage.Save("AdaptiveImage.air");

            Console.WriteLine("    image");
            ImageRecognizer image = new ImageRecognizer(shapeData);
            image.Save("Image.ir");

            Console.WriteLine("    finished training recognizers");

#if false
            RubineRecognizer        fullRubine  = rubine.LiteRecognizer;
            DollarRecognizer        fullDollar  = dollar;
            ZernikeMomentRecognizer fullZernike = zernike.LiteRecognizer;

            ImageRecognizer fullImage = image;

            // Split the data up per-user
            Console.WriteLine("Loading per-user data...");
            Dictionary <string, List <Shape>[]> user2data = GetSketchesPerUser(allSketches);
            Console.WriteLine("    found " + user2data.Count + " users");


            // Foreach user: train each of the recognizers and accumulate training data
            // for the combo recognizer
            List <KeyValuePair <ShapeType, Dictionary <string, object> > > data = new List <KeyValuePair <ShapeType, Dictionary <string, object> > >();
            foreach (KeyValuePair <string, List <Shape>[]> pair in user2data)
            {
                string user = pair.Key;

                ////////////////////////////////////////
                ////////////   Train   /////////////////
                ////////////////////////////////////////

                Console.WriteLine("User: "******"    rubine");
                rubine = new RubineRecognizerUpdateable(trainingSet);
                rubine.Save("Rubine" + user + ".rru");
                rubine.LiteRecognizer.Save("RubineLite" + user + ".rr");

                Console.WriteLine("    dollar");
                dollar = new DollarRecognizer(trainingSet);
                dollar.Save("Dollar" + user + ".dr");
#else
                rubine = new RubineRecognizerUpdateable();
                rubine.Save("Rubine" + user + ".rru");
                rubine.LiteRecognizer.Save("RubineLite" + user + ".rr");

                dollar = new DollarRecognizer();
                dollar.Save("Dollar" + user + ".dr");
#endif

                Console.WriteLine("    zernike");
                zernike = new ZernikeMomentRecognizerUpdateable(trainingSet);
                zernike.Save("Zernike" + user + ".zru");
                zernike.LiteRecognizer.Save("ZernikeLite" + user + ".zr");

                Console.WriteLine("    image");
                image = new ImageRecognizer(trainingSet);
                image.Save("Image" + user + ".ir");
                fullImage = image;

                ////////////////////////////////////////
                //////////// Evaluate //////////////////
                ////////////////////////////////////////


                List <Shape> testingSet = pair.Value[1];

                // Create the training data for the combo recognizer
                List <KeyValuePair <ShapeType, Dictionary <string, object> > > comboTrainingData = TrainingDataCombo(testingSet, rubine, dollar, zernike, image);
                foreach (KeyValuePair <ShapeType, Dictionary <string, object> > pair2 in comboTrainingData)
                {
                    data.Add(pair2);
                }
            }

            if (data.Count == 0)
            {
                throw new Exception("no data!");
            }

            List <string> features = new List <string>();
            foreach (KeyValuePair <ShapeType, Dictionary <string, object> > instance in data)
            {
                foreach (string feature in instance.Value.Keys)
                {
                    if (!features.Contains(feature))
                    {
                        features.Add(feature);
                    }
                }
            }

            Console.WriteLine("Found " + data.Count + " data points and " + features.Count + " features.");

            ComboRecognizer combo = new ComboRecognizer(fullRubine, fullDollar, fullZernike, fullImage);
            combo.TrainCombo(features, data);
            combo.Save("Combo.cru");

            Console.WriteLine("Naive bayes updatable has " + combo.ComboClassifier.Examples.Count + " examples.");
            Console.WriteLine("Naive bayes updatable has " + combo.ComboClassifier.Classifier.Classes.Count + " classes:");
            foreach (ShapeType cls in combo.ComboClassifier.Classifier.Classes)
            {
                Console.WriteLine("    " + cls);
            }
#endif

            Console.WriteLine("Training neural image recognizer on real-world data...");
            List <Shape> goodGates;                  // list of correctly-identified gates
            List <Shape> badGates;                   // list of shapes grouped as gates that aren't
            Dictionary <Shape, string> shapeSources; // map of shapes to source filename

            string cacheFile = outputPath + "goodAndBadGates.data";
            if (!System.IO.File.Exists(cacheFile))
            {
                goodGates    = new List <Shape>();
                badGates     = new List <Shape>();
                shapeSources = new Dictionary <Shape, string>();

                Grouper             grouper    = RecognitionPipeline.createDefaultGrouper();
                Classifier          classifier = RecognitionPipeline.createDefaultClassifier();
                RecognitionPipeline pipeline   = new RecognitionPipeline(classifier, grouper);
                var files = Files.FUtil.AllFiles(args[1], Files.Filetype.XML, true);
                Console.WriteLine("    Found " + files.Count() + " real-world sketches");
                int i = 1;
                foreach (string file in files)
                {
                    Console.WriteLine("    Sketch " + i + " / " + files.Count());
                    i++;

                    Sketch.Sketch sketch   = new ReadXML(file).Sketch;
                    Sketch.Sketch original = sketch.Clone();

                    sketch.RemoveLabels();
                    sketch.resetShapes();

                    pipeline.process(sketch);

                    foreach (Sketch.Shape shape in sketch.Shapes)
                    {
                        if (shape.Classification != LogicDomain.GATE_CLASS)
                        {
                            continue;
                        }

                        Shape originalGate = original.ShapesL.Find(delegate(Shape s) { return(s.GeometricEquals(shape)); });

                        if (originalGate != null && originalGate.Classification == LogicDomain.GATE_CLASS)
                        {
                            goodGates.Add(shape);
                        }
                        else
                        {
                            // We can't just say "this is a bad gate." If it wasn't found,
                            // the shape might be an XOR gate missing the back, or a NAND
                            // gate missing a bubble. We will apply the following heuristic:
                            //    if all the strokes in the shape are part of the same
                            //    shape in the original sketch and that shape in the
                            //    original sketch is a gate, this is not a bad gate.

                            // a shape consists of one or more substrokes from shapes in the
                            // original, correct sketch
                            HashSet <Shape> originalShapes = new HashSet <Shape>();
                            foreach (Substroke substroke in shape.Substrokes)
                            {
                                Substroke originalSubstroke = original.SubstrokesL.Find(delegate(Substroke s) { return(s.GeometricEquals(substroke)); });
                                if (originalSubstroke == null)
                                {
                                    throw new Exception("A substroke is missing in the original sketch???");
                                }
                                if (originalSubstroke.ParentShape != null)
                                {
                                    originalShapes.Add(originalSubstroke.ParentShape);
                                }
                            }

                            List <Shape> originalShapesL = originalShapes.ToList();
                            if (originalShapesL.Count != 1 || originalShapesL[0].Classification != LogicDomain.GATE_CLASS)
                            {
                                badGates.Add(shape);
                            }
                        }
                        shapeSources.Add(shape, file);
                    }
                }

                Console.WriteLine("Saving found gates to " + cacheFile);
                var stream     = System.IO.File.Open(cacheFile, System.IO.FileMode.Create);
                var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                bformatter.Serialize(stream, Tuple.Create(goodGates, badGates, shapeSources));
                stream.Close();
            }
            else
            {
                Console.WriteLine("Loading good and bad gates from " + cacheFile);
                var stream     = System.IO.File.Open(cacheFile, System.IO.FileMode.Open);
                var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                var data       = (Tuple <List <Shape>, List <Shape>, Dictionary <Shape, string> >)bformatter.Deserialize(stream);
                stream.Close();

                goodGates    = data.Item1;
                badGates     = data.Item2;
                shapeSources = data.Item3;
            }
            Console.WriteLine("    Found " + goodGates.Count + " good gates, " + badGates.Count + " bad gates");

            ImageRecognizer innerNeuralRecgonizer = image;
            string          neuralPath            = @"neuralResults\";
            string          arffFilename          = "data.arff";
            if (!System.IO.Directory.Exists(neuralPath))
            {
                System.IO.Directory.CreateDirectory(neuralPath);
            }

            Console.WriteLine("    Writing ARFF file '" + neuralPath + arffFilename + "'...");
            TextWriter arffWriter = new StreamWriter(neuralPath + arffFilename);
            NeuralImageRecognizer.WriteARFF(arffWriter, innerNeuralRecgonizer, goodGates, badGates);
            arffWriter.Close();

            Console.WriteLine("    Training the network...");

            // Network settings -- determined empircally
            NeuralNetworkInfo info = new NeuralNetworkInfo();
            info.Layers            = new int[] { 8, 1 };
            info.NumTrainingEpochs = 1000;
            info.LearningRate      = 0.05;
            info.Momentum          = 0.2;
            NeuralImageRecognizer neuralImage = new NeuralImageRecognizer(innerNeuralRecgonizer, goodGates, badGates, info);

            neuralImage.Save("NeuralImage.nir");


            Console.WriteLine("    Testing the network (results in " + neuralPath + ")...");
            neuralImage = NeuralImageRecognizer.Load("NeuralImage.nir");

            TextWriter writer = new StreamWriter(neuralPath + "info.csv");

            writer.WriteLine("Sketch File, Shape Bitmap, Good?, Tanimoto, Yule, Partial Hausdorff, Modified Hausdorff, Output Confidence");

            int falseNegatives = 0;
            foreach (Shape gate in goodGates)
            {
                ImageRecognitionResult result = (ImageRecognitionResult)neuralImage.recognize(gate, null);
                if (result.Confidence < 0.5)
                {
                    falseNegatives++;
                }

                System.Drawing.Bitmap b = gate.createBitmap(100, 100, true);
                string filename         = String.Format("good-" + "-{0:x}.png", gate.GetHashCode());
                b.Save(neuralPath + filename);

                writer.WriteLine(shapeSources[gate] + "," + filename +
                                 ", 1, " +
                                 result.Tanimoto + ", " +
                                 result.Yule + ", " +
                                 result.PartialHausdorff + ", " +
                                 result.ModifiedHausdorff + ", " +
                                 result.Confidence);
            }
            Console.WriteLine("    Good gates with low confidence: " + falseNegatives + "/" + (goodGates.Count));

            int falsePositives = 0;
            foreach (Shape gate in badGates)
            {
                ImageRecognitionResult result = (ImageRecognitionResult)neuralImage.recognize(gate, null);
                if (result.Confidence > 0.5)
                {
                    falsePositives++;
                }

                System.Drawing.Bitmap b = gate.createBitmap(100, 100, true);
                string filename         = String.Format("bad-" + "-{0:x}.png", gate.GetHashCode());
                b.Save(neuralPath + filename);

                writer.WriteLine(shapeSources[gate] + "," + filename +
                                 ", 0, " +
                                 result.Tanimoto + ", " +
                                 result.Yule + ", " +
                                 result.PartialHausdorff + ", " +
                                 result.ModifiedHausdorff + ", " +
                                 result.Confidence);
            }
            Console.WriteLine("    Bad gates with high confidence: " + falsePositives + "/" + (badGates.Count));
            writer.Close();

            Console.WriteLine("Press ENTER to continue...");
            Console.ReadLine();
        }