public void TrainSet(EncogOCR_SketchData[] sketches, bool shouldGenerateGarbage = true)
            {
                // Assign a token so that only the latest result will be used
                long token = TokenGenerator.NextToken();
                _currentToken = token;

                _parent.lblTraining.Content = "training...";

                // Kill existing tasks
                //NOTE: Removing from the list is done in the continue
                foreach (var runningTask in _currentTasks)
                {
                    runningTask.Item2.Cancel();
                }

                // Group the sketches by name
                var groupedSketches = sketches.ToLookup(o => o.Name).
                    Select(o => Tuple.Create(o.Key, o.Select(p => p).ToArray())).
                    ToArray();
                if (groupedSketches.Length == 0)
                {
                    _parent._network = null;
                    _parent.lblTraining.Content = "";
                    return;
                }

                TrainNetwork(groupedSketches, token, shouldGenerateGarbage);
            }
Example #2
0
        private void AddSketch(EncogOCR_SketchData sketch)
        {
            _prevSketches.Add(sketch);

            // Find existing name node
            TreeViewItem nameNode = null;

            foreach (TreeViewItem node in pnlPreviousDrawings.Items)
            {
                if (((string)node.Header).Equals(sketch.Name, StringComparison.OrdinalIgnoreCase))
                {
                    nameNode = node;
                    break;
                }
            }

            if (nameNode == null)
            {
                // Create new
                nameNode = new TreeViewItem()
                {
                    Header = sketch.Name
                };

                pnlPreviousDrawings.Items.Add(nameNode);
            }

            // Add the image control to this name node
            nameNode.Items.Add(sketch.ImageControl);

            nameNode.IsExpanded = true;

            #region Update the sketch name combo

            string currentText = cboDrawingLabel.Text;
            cboDrawingLabel.Items.Clear();

            foreach (string comboItem in _prevSketches.Select(o => o.Name).Distinct().OrderBy(o => o))
            {
                cboDrawingLabel.Items.Add(comboItem);
            }

            cboDrawingLabel.Text = currentText;

            #endregion
        }
Example #3
0
        /// <summary>
        /// This compares the strokes (ignores token)
        /// </summary>
        private static bool IsSame_Strokes(EncogOCR_SketchData sketch1, EncogOCR_SketchData sketch2)
        {
            if (sketch1.Strokes.Length != sketch2.Strokes.Length)
            {
                return(false);
            }

            if (!Enumerable.Range(0, sketch1.Strokes.Length).
                All(o =>
            {
                if (sketch1.Strokes[o].Points.Length != sketch2.Strokes[o].Points.Length)
                {
                    return(false);
                }

                if (sketch1.Strokes[o].Color != sketch2.Strokes[o].Color)
                {
                    return(false);
                }

                if (!sketch1.Strokes[o].Thickness.IsNearValue(sketch2.Strokes[o].Thickness))
                {
                    return(false);
                }

                return(true);
            }))
            {
                return(false);
            }

            // Compare each point
            for (int outer = 0; outer < sketch1.Strokes.Length; outer++)
            {
                for (int inner = 0; inner < sketch1.Strokes[outer].Points.Length; inner++)
                {
                    if (!Math2D.IsNearValue(sketch1.Strokes[outer].Points[inner], sketch2.Strokes[outer].Points[inner]))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Example #4
0
        private void btnStoreDrawing_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (cboDrawingLabel.Text == "")
                {
                    MessageBox.Show("Please give this drawing a name", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                if (_currentSketch == null)
                {
                    RedrawSmallImage();
                }

                #region Create sketch for storage

                EncogOCR_SketchData sketch = new EncogOCR_SketchData()
                {
                    Name          = cboDrawingLabel.Text,
                    InkCanvasSize = new Size(canvasInk.ActualWidth, canvasInk.ActualHeight),
                    Strokes       = _currentSketch.Strokes.ToArray(),
                };

                sketch.GenerateBitmap(_pixels);
                sketch.GenerateImageControl();

                #endregion

                AddSketch(sketch);
                TrainNetwork();

                //NOTE: Event listeners will clear the rest based on this
                canvasInk.Strokes.Clear();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Example #5
0
        /// <summary>
        /// It's ok to add the same sketch multiple times.  Only one copy will be kept (based on token)
        /// </summary>
        public void AddSketch(EncogOCR_SketchData sketch)
        {
            if (_vectorImages.Any(o => o.Token == sketch.Token))
            {
                // Already have it
                return;
            }
            else if (sketch.Strokes.Length == 0 && _vectorImages.Any(o => o.Strokes.Length == 0))
            {
                // Only store one blank image
                return;
            }
            else if (_vectorImages.AsParallel().Any(o => IsSame_Strokes(o, sketch)))
            {
                // When they draw a test image, it gets added.  Then when they hit store, a duplicate gets added (different token), so
                // look for an exact dupe
                return;
            }

            _vectorImages.Add(sketch);

            EnsureDotCreated(sketch);
        }
Example #6
0
        /// <summary>
        /// This clears everything except:
        ///     session names out of the combo box
        ///     pixels
        ///     pen size
        /// </summary>
        private void ClearEverything()
        {
            if (_visualizer != null)
            {
                _visualizer.Clear();
            }

            _currentSketch = null;
            grdGuessDetails.Children.Clear();
            grdGuessDetails.RowDefinitions.Clear();

            pnlPreviousDrawings.Items.Clear();
            _prevSketches.Clear();

            cboDrawingLabel.Items.Clear();

            canvasInk.Strokes.Clear();

            _network = null;

            RedrawSmallImage();
            RedrawPreviousImages(true);
        }
Example #7
0
        private void RedrawSmallImage()
        {
            //canvasPixels.Source = UtilityWPF.RenderControl(canvasInk, _pixels, _pixels, true);

            _currentSketch = new EncogOCR_SketchData()
            {
                Name    = cboDrawingLabel.Text,
                Strokes = canvasInk.Strokes.
                          Select(o => new EncogOCR_StrokeDefinition(o)).
                          ToArray(),
                InkCanvasSize = new Size(canvasInk.ActualWidth, canvasInk.ActualHeight),
            };

            _currentSketch.GenerateBitmap(_pixels);

            canvasPixels.Source = _currentSketch.Bitmap;

            RecognizeImage();

            if (_visualizer != null)
            {
                _visualizer.AddSketch(_currentSketch.Clone());
            }
        }
Example #8
0
        private void EnsureDotCreated(EncogOCR_SketchData sketch)
        {
            if (_dots == null)
            {
                return;
            }
            else if (_dots.Dots.Any(o => o.Token == sketch.Token))
            {
                return;
            }

            Dot dot = new Dot(sketch.Token)
            {
                VectorSource = sketch.Clone(),      // cloning to ensure the sketch passed in doesn't get manipulated.  NOTE: The clone will have a different token
                Position     = Math3D.GetRandomVector_Spherical(RADIUS).ToPoint(),
            };

            _dots.Dots.Add(dot);

            if (_networkOutputs != null)
            {
                ReconstructDot(dot);
            }
        }
        /// <summary>
        /// This clears everything except:
        ///     session names out of the combo box
        ///     pixels
        ///     pen size
        /// </summary>
        private void ClearEverything()
        {
            if (_visualizer != null)
            {
                _visualizer.Clear();
            }

            _currentSketch = null;
            grdGuessDetails.Children.Clear();
            grdGuessDetails.RowDefinitions.Clear();

            pnlPreviousDrawings.Items.Clear();
            _prevSketches.Clear();

            cboDrawingLabel.Items.Clear();

            canvasInk.Strokes.Clear();

            _network = null;

            RedrawSmallImage();
            RedrawPreviousImages(true);
        }
        private static SketchSample[] TestSamples_InputOutput(TrainedNework_Simple network, EncogOCR_SketchData[] inputSketches)
        {
            List<SketchSample> retVal = new List<SketchSample>();

            int inputSize = network.Network.InputCount;
            int outputSize = network.Network.OutputCount;

            // Inputs
            foreach (EncogOCR_SketchData input in inputSketches)
            {
                double[] output = new double[outputSize];
                network.Network.Compute(input.NNInput, output);

                retVal.Add(new SketchSample() { NNInput = input.NNInput, NNOutput = output });
            }

            // Solid Colors
            for (int cntr = 0; cntr <= 16; cntr++)
            {
                double val = cntr / 16d;

                double[] input = Enumerable.Range(0, inputSize).Select(o => val).ToArray();
                double[] output = new double[outputSize];

                network.Network.Compute(input, output);

                retVal.Add(new SketchSample() { NNInput = input, NNOutput = output });
            }

            //TODO: Generate random brush stroke images
            //TODO: Generate random pixelated images

            return retVal.ToArray();
        }
        private void EnsureDotCreated(EncogOCR_SketchData sketch)
        {
            if (_dots == null)
            {
                return;
            }
            else if (_dots.Dots.Any(o => o.Token == sketch.Token))
            {
                return;
            }

            Dot dot = new Dot(sketch.Token)
            {
                VectorSource = sketch.Clone(),      // cloning to ensure the sketch passed in doesn't get manipulated.  NOTE: The clone will have a different token
                Position = Math3D.GetRandomVector_Spherical(RADIUS).ToPoint(),
            };

            _dots.Dots.Add(dot);

            if (_networkOutputs != null)
            {
                ReconstructDot(dot);
            }
        }
Example #12
0
        private void RedrawSmallImage()
        {
            //canvasPixels.Source = UtilityWPF.RenderControl(canvasInk, _pixels, _pixels, true);

            _currentSketch = new EncogOCR_SketchData()
            {
                Name = cboDrawingLabel.Text,
                Strokes = canvasInk.Strokes.
                    Select(o => new EncogOCR_StrokeDefinition(o)).
                    ToArray(),
                InkCanvasSize = new Size(canvasInk.ActualWidth, canvasInk.ActualHeight),
            };

            _currentSketch.GenerateBitmap(_pixels);

            canvasPixels.Source = _currentSketch.Bitmap;

            RecognizeImage();

            if (_visualizer != null)
            {
                _visualizer.AddSketch(_currentSketch.Clone());
            }
        }
Example #13
0
        private void AddSketch(EncogOCR_SketchData sketch)
        {
            _prevSketches.Add(sketch);

            // Find existing name node
            TreeViewItem nameNode = null;
            foreach (TreeViewItem node in pnlPreviousDrawings.Items)
            {
                if (((string)node.Header).Equals(sketch.Name, StringComparison.OrdinalIgnoreCase))
                {
                    nameNode = node;
                    break;
                }
            }

            if (nameNode == null)
            {
                // Create new
                nameNode = new TreeViewItem() { Header = sketch.Name };

                pnlPreviousDrawings.Items.Add(nameNode);
            }

            // Add the image control to this name node
            nameNode.Items.Add(sketch.ImageControl);

            nameNode.IsExpanded = true;

            #region Update the sketch name combo

            string currentText = cboDrawingLabel.Text;
            cboDrawingLabel.Items.Clear();

            foreach (string comboItem in _prevSketches.Select(o => o.Name).Distinct().OrderBy(o => o))
            {
                cboDrawingLabel.Items.Add(comboItem);
            }

            cboDrawingLabel.Text = currentText;

            #endregion
        }
        private void StrokeCollection_StrokesChanged(object sender, System.Windows.Ink.StrokeCollectionChangedEventArgs e)
        {
            try
            {
                EncogOCR_SketchData sketch = new EncogOCR_SketchData()
                {
                    Name = "",
                    Strokes = canvasInk.Strokes.
                        Select(o => new EncogOCR_StrokeDefinition(o)).
                        ToArray(),
                    InkCanvasSize = new Size(canvasInk.ActualWidth, canvasInk.ActualHeight),
                };

                sketch.GenerateBitmap(IMAGESIZE);

                // The bitmap is white on black, switch to black on white
                double[] inverted = sketch.NNInput.
                    Select(o => 1d - o).
                    ToArray();

                double[] converted = inverted;
                if (_patternStorage != null)
                {
                    converted = _patternStorage.Convert_Local_External(converted);
                }

                DrawImage(imageCurrent, converted);

                panelGuessedImages.Children.Clear();

                if (_patternStorage != null)
                {
                    double[][] recognized = _patternStorage.Recognize(inverted);

                    #region show thumbnails

                    if (recognized != null)
                    {
                        foreach (var guessImage in recognized)
                        {
                            DrawImage(panelGuessedImages.Children, guessImage);
                        }
                    }

                    #endregion
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Example #15
0
            private static void GenerateGarbageData(EncogOCR_SketchData[] sketches, int outputSize, List<double[]> inputs, List<double[]> outputs)
            {
                #region validate
#if DEBUG
                if (sketches.Select(o => o.BitmapColors.Width).Distinct().Count() != 1 || sketches.Select(o => o.BitmapColors.Height).Distinct().Count() != 1)
                {
                    throw new ApplicationException("Stored images are different sizes");
                }
#endif
                #endregion

                double[] zeroOutput = Enumerable.Range(0, outputSize).Select(o => 0d).ToArray();

                #region efficient if only a final is needed

                //Color[][] colors = sketches.
                //    Select(o => o.BitmapColors.GetColors(0, 0, o.Bitmap.PixelWidth, o.Bitmap.PixelHeight)).
                //    ToArray();

                //bool[] isBlack = Enumerable.Range(0, colors[0].Length).
                //    AsParallel().
                //    Select(o => new { Index = o, IsBlack = colors.Any(p => p[o].A > 200 && Math3D.Avg(p[o].R, p[o].G, p[o].B) < 20) }).
                //    OrderBy(o => o.Index).
                //    Select(o => o.IsBlack).
                //    ToArray();

                #endregion

                // Figure out which pixels of each sketch are black
                bool[][] isBlack = sketches.
                    Select(o => o.BitmapColors.GetColors(0, 0, o.BitmapColors.Width, o.BitmapColors.Height)).
                    Select(o => o.Select(p => p.A > 200 && Math1D.Avg(p.R, p.G, p.B) < 20).ToArray()).
                    ToArray();

                // Or the images together
                bool[] composite = Enumerable.Range(0, isBlack[0].Length).
                    AsParallel().
                    Select(o => new { Index = o, IsBlack = isBlack.Any(p => p[o]) }).
                    OrderBy(o => o.Index).
                    Select(o => o.IsBlack).
                    ToArray();

                #region Blank sketch

                double[] percentBlack = isBlack.
                    Select(o => o.Sum(p => p ? 1d : 0d) / o.Length).
                    ToArray();

                if (percentBlack.All(o => o > .01))
                {
                    // None of the inputs are blank, so make blank a garbage state
                    inputs.Add(Enumerable.Range(0, composite.Length).Select(o => 0d).ToArray());
                    outputs.Add(zeroOutput);
                }

                #endregion
                #region Inverted sketch

                // Making this, because the assumption is that if they draw in a region outside any of the inputs, then it should be a zero output

                inputs.Add(composite.Select(o => o ? 0d : 1d).ToArray());
                outputs.Add(zeroOutput);

                #endregion

                //TODO: Do a few subsets of inverted

            }
        /// <summary>
        /// It's ok to add the same sketch multiple times.  Only one copy will be kept (based on token)
        /// </summary>
        public void AddSketch(EncogOCR_SketchData sketch)
        {
            if (_vectorImages.Any(o => o.Token == sketch.Token))
            {
                // Already have it
                return;
            }
            else if (sketch.Strokes.Length == 0 && _vectorImages.Any(o => o.Strokes.Length == 0))
            {
                // Only store one blank image
                return;
            }
            else if (_vectorImages.AsParallel().Any(o => IsSame_Strokes(o, sketch)))
            {
                // When they draw a test image, it gets added.  Then when they hit store, a duplicate gets added (different token), so
                // look for an exact dupe
                return;
            }

            _vectorImages.Add(sketch);

            EnsureDotCreated(sketch);
        }
Example #17
0
        private void btnStoreDrawing_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (cboDrawingLabel.Text == "")
                {
                    MessageBox.Show("Please give this drawing a name", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                if (_currentSketch == null)
                {
                    RedrawSmallImage();
                }

                #region Create sketch for storage

                EncogOCR_SketchData sketch = new EncogOCR_SketchData()
                {
                    Name = cboDrawingLabel.Text,
                    InkCanvasSize = new Size(canvasInk.ActualWidth, canvasInk.ActualHeight),
                    Strokes = _currentSketch.Strokes.ToArray(),
                };

                sketch.GenerateBitmap(_pixels);
                sketch.GenerateImageControl();

                #endregion

                AddSketch(sketch);
                TrainNetwork();

                //NOTE: Event listeners will clear the rest based on this
                canvasInk.Strokes.Clear();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        /// <summary>
        /// This compares the strokes (ignores token)
        /// </summary>
        private static bool IsSame_Strokes(EncogOCR_SketchData sketch1, EncogOCR_SketchData sketch2)
        {
            if (sketch1.Strokes.Length != sketch2.Strokes.Length)
            {
                return false;
            }

            if (!Enumerable.Range(0, sketch1.Strokes.Length).
                All(o =>
                    {
                        if (sketch1.Strokes[o].Points.Length != sketch2.Strokes[o].Points.Length)
                            return false;

                        if (sketch1.Strokes[o].Color != sketch2.Strokes[o].Color)
                            return false;

                        if (!sketch1.Strokes[o].Thickness.IsNearValue(sketch2.Strokes[o].Thickness))
                            return false;

                        return true;
                    }))
            {
                return false;
            }

            // Compare each point
            for (int outer = 0; outer < sketch1.Strokes.Length; outer++)
            {
                for (int inner = 0; inner < sketch1.Strokes[outer].Points.Length; inner++)
                {
                    if (!Math2D.IsNearValue(sketch1.Strokes[outer].Points[inner], sketch2.Strokes[outer].Points[inner]))
                    {
                        return false;
                    }
                }
            }

            return true;
        }
        private static SketchDots TestSamples(TrainedNework_Simple network, EncogOCR_SketchData[] inputSketches, double[] hues)
        {
            // Run a bunch of test images through the NN
            //NOTE: Only .NNInput and .NNOutput props are populated
            SketchSample[] sketches = TestSamples_InputOutput(network, inputSketches);

            // Build a visual with each sketch as a dot
            Visual3D visual = TestSamples_Draw(sketches, hues);

            // Calculate the forces between each sketch
            Tuple<int, int, double>[] distance_Input, distance_Output;
            TestSamples_Distance(out distance_Input, out distance_Output, sketches);

            return new SketchDots()
            {
                Sketches = sketches,
                Visual = visual,
                Distances_Input = distance_Input,
                Distances_Output = distance_Output,
            };
        }