diff --git a/DigitDisplay.sln b/DigitDisplay.sln
index bd2b6a4..9842dc5 100644
--- a/DigitDisplay.sln
+++ b/DigitDisplay.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25123.0
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2010
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitDisplay", "DigitDisplay\DigitDisplay.csproj", "{8E1C0000-6DD5-42E0-8DAD-D75AF1FC249F}"
EndProject
@@ -13,6 +13,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FunctionalRecognizer", "Fun
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recognizer", "Recognizer\Recognizer.csproj", "{F15E6F19-7B0D-48A5-B505-7C9658D208CC}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObservationLoader", "ObservationLoader\ObservationLoader.csproj", "{301EC918-D5E6-4C89-9CD0-84C35FC7413C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -39,8 +41,15 @@ Global
{F15E6F19-7B0D-48A5-B505-7C9658D208CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F15E6F19-7B0D-48A5-B505-7C9658D208CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F15E6F19-7B0D-48A5-B505-7C9658D208CC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {301EC918-D5E6-4C89-9CD0-84C35FC7413C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {301EC918-D5E6-4C89-9CD0-84C35FC7413C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {301EC918-D5E6-4C89-9CD0-84C35FC7413C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {301EC918-D5E6-4C89-9CD0-84C35FC7413C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {FC5565F2-8C3B-4A75-97DA-2219CC4C2A83}
+ EndGlobalSection
EndGlobal
diff --git a/DigitDisplay/App.config b/DigitDisplay/App.config
index b63f556..efa21db 100644
--- a/DigitDisplay/App.config
+++ b/DigitDisplay/App.config
@@ -1,7 +1,7 @@
-
+
-
+
@@ -9,4 +9,4 @@
-
\ No newline at end of file
+
diff --git a/DigitDisplay/App.xaml.cs b/DigitDisplay/App.xaml.cs
index 177f8df..9126f5c 100644
--- a/DigitDisplay/App.xaml.cs
+++ b/DigitDisplay/App.xaml.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Data;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Windows;
+using System.Windows;
namespace DigitDisplay
{
diff --git a/DigitDisplay/DigitDisplay.csproj b/DigitDisplay/DigitDisplay.csproj
index 7c7af54..3c83bae 100644
--- a/DigitDisplay/DigitDisplay.csproj
+++ b/DigitDisplay/DigitDisplay.csproj
@@ -9,11 +9,12 @@
Properties
DigitDisplay
DigitDisplay
- v4.5
+ v4.6.1
512
{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
4
true
+
AnyCPU
@@ -40,6 +41,9 @@
+
+ ..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll
+
@@ -57,11 +61,8 @@
MSBuild:Compile
Designer
-
- ParallelRecognizerControl.xaml
-
-
- RecognizerControl.xaml
+
+ RecognizerUserControl.xaml
MSBuild:Compile
@@ -76,14 +77,10 @@
MainWindow.xaml
Code
-
+
MSBuild:Compile
Designer
-
- Designer
- MSBuild:Compile
-
@@ -103,6 +100,7 @@
ResXFileCodeGenerator
Resources.Designer.cs
+
SettingsSingleFileGenerator
Settings.Designer.cs
@@ -123,6 +121,10 @@
{ff2cd045-8b57-422c-954a-ab2cbbe6c065}
FunctionalRecognizer
+
+ {301ec918-d5e6-4c89-9cd0-84c35fc7413c}
+ ObservationLoader
+
diff --git a/DigitDisplay/ImageHelper.cs b/DigitDisplay/ImageHelper.cs
index 3333318..578e269 100644
--- a/DigitDisplay/ImageHelper.cs
+++ b/DigitDisplay/ImageHelper.cs
@@ -1,11 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
+using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using System.Windows.Media.Imaging;
namespace DigitDisplay
diff --git a/DigitDisplay/MainWindow.xaml.cs b/DigitDisplay/MainWindow.xaml.cs
index 23362db..f19079d 100644
--- a/DigitDisplay/MainWindow.xaml.cs
+++ b/DigitDisplay/MainWindow.xaml.cs
@@ -1,22 +1,15 @@
-using DigitLoader;
-using Microsoft.FSharp.Core;
-using System;
+using System;
+using DigitLoader;
using System.Configuration;
-using System.Drawing;
-using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
+using ObservationLoader;
namespace DigitDisplay
{
- public partial class MainWindow : Window
+ public partial class MainWindow
{
- SolidColorBrush redBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 150, 150));
- SolidColorBrush whiteBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 255, 255));
-
public MainWindow()
{
InitializeComponent();
@@ -29,32 +22,41 @@ private void GoButton_Click(object sender, RoutedEventArgs e)
LeftPanel.Children.Clear();
RightPanel.Children.Clear();
- string[] rawData = FileLoader.LoadDataStrings();
+ var rawData = FileLoader.LoadObservations();
- var parallelManhattanRecognizer = new ParallelRecognizerControl(
- "Parallel Manhattan Classifier", Recognizer.manhattanClassifier,
+ var parallelManhattanRecognizer = new RecognizerUserControl(
+ "Parallel Manhattan Classifier", DispatchManhattanParallelForEach,
rawData);
LeftPanel.Children.Add(parallelManhattanRecognizer);
- var manhattanRecognizer = new RecognizerControl(
- "Manhattan Classifier", Recognizer.manhattanClassifier,
+ var manhattanRecognizer = new RecognizerUserControl(
+ "Manhattan Classifier", DispatchManhattanTasks,
rawData);
RightPanel.Children.Add(manhattanRecognizer);
+ }
- //var euclideanRecognizer = new RecognizerControl(
- // "Euclidean Classifier", Recognizer.euclideanClassifier,
- // rawData);
- //RightPanel.Children.Add(euclideanRecognizer);
-
- //var nullRecognizer = new RecognizerControl(
- // "Null Classifier", (FSharpFunc)Recognizer.nullClassifier,
- // rawData);
- //RightPanel.Children.Add(nullRecognizer);
+ private static void DispatchManhattanParallelForEach((Observation observation, Action showResult)[] input)
+ {
+ var uiContext = SynchronizationContext.Current;
+ ThreadPool.QueueUserWorkItem(state => Parallel.ForEach(input, current =>
+ {
+ var predicted = Recognizer.predict(current.observation.Pixels, Recognizer.manhattanClassifier);
+ uiContext.Post(_ => current.showResult(predicted), null);
+ }));
+ }
- //var firstPixelRecognizer = new RecognizerControl(
- // "FirstPixel Classifier", (FSharpFunc)Recognizer.firstPixelClassifier,
- // rawData);
- //LeftPanel.Children.Add(firstPixelRecognizer);
+ private static void DispatchManhattanTasks((Observation observation, Action showResult)[] input)
+ {
+ foreach (var current in input)
+ {
+ Task
+ .Run(() => Recognizer.predict(current.observation.Pixels, Recognizer.manhattanClassifier))
+ .ContinueWith(t =>
+ {
+ current.showResult(t.Result);
+ },
+ TaskScheduler.FromCurrentSynchronizationContext());
+ }
}
}
}
diff --git a/DigitDisplay/ParallelRecognizerControl.xaml b/DigitDisplay/ParallelRecognizerControl.xaml
deleted file mode 100644
index bb27611..0000000
--- a/DigitDisplay/ParallelRecognizerControl.xaml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/DigitDisplay/ParallelRecognizerControl.xaml.cs b/DigitDisplay/ParallelRecognizerControl.xaml.cs
deleted file mode 100644
index bb447ab..0000000
--- a/DigitDisplay/ParallelRecognizerControl.xaml.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-using DigitLoader;
-using Microsoft.FSharp.Core;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-
-namespace DigitDisplay
-{
- public partial class ParallelRecognizerControl : UserControl
- {
- string classifierName;
- FSharpFunc classifier;
- string[] rawData;
- //ConcurrentQueue predictions = new ConcurrentQueue();
-
- DateTimeOffset startTime;
- SolidColorBrush redBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 150, 150));
- SolidColorBrush whiteBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 255, 255));
- int errors = 0;
-
- public ParallelRecognizerControl(string classifierName, FSharpFunc classifier,
- string[] rawData)
- {
- InitializeComponent();
- this.classifierName = classifierName;
- this.classifier = classifier;
- this.rawData = rawData;
- Loaded += RecognizerControl_Loaded;
- }
-
- private void RecognizerControl_Loaded(object sender, RoutedEventArgs e)
- {
-
- ClassifierText.Text = classifierName;
- PopulatePanel(rawData);
- }
-
- private struct PredictionData
- {
- public string prediction;
- public string actual;
- public string imageData;
- }
-
- private void PopulatePanel(string[] rawData)
- {
- startTime = DateTime.Now;
-
- var options = new ParallelOptions();
- options.TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
-
- var loopResult = Parallel.ForEach(rawData, s =>
- {
- int act = s.Split(',').Select(x => Convert.ToInt32(x)).First();
- int[] ints = s.Split(',').Select(x => Convert.ToInt32(x)).Skip(1).ToArray();
- var result = Recognizer.predict(ints, classifier);
-
- //predictions.Enqueue(new PredictionData() {
- // prediction = result, actual = act.ToString(), imageData = s });
-
- Task.Factory.StartNew(() =>
- CreateUIElements(result, act.ToString(), s, DigitsBox),
- CancellationToken.None,
- TaskCreationOptions.None,
- options.TaskScheduler
- );
- });
-
- //Parallel.Invoke(options, () =>
- //{
- // PredictionData d;
- // while (predictions.TryDequeue(out d))
- // {
- // if (d.imageData != null)
- // CreateUIElements(d.prediction, d.actual, d.imageData, DigitsBox);
- // }
- //});
- }
-
- private void CreateUIElements(string prediction, string actual, string imageData,
- Panel panel)
- {
- Bitmap image = DigitBitmap.GetBitmapFromRawData(imageData);
-
- var multiplier = 1.5;
- var imageControl = new System.Windows.Controls.Image();
- imageControl.Source = image.ToWpfBitmap();
- imageControl.Stretch = Stretch.UniformToFill;
- imageControl.Width = imageControl.Source.Width * multiplier;
- imageControl.Height = imageControl.Source.Height * multiplier;
-
- var textBlock = new TextBlock();
- textBlock.Height = imageControl.Height;
- textBlock.Width = imageControl.Width;
- textBlock.FontSize = 12; // * multiplier;
- textBlock.TextAlignment = TextAlignment.Center;
- textBlock.Text = prediction;
-
- var button = new Button();
- var backgroundBrush = whiteBrush;
- button.Background = backgroundBrush;
- button.Click += ToggleCorrectness;
-
- var buttonContent = new StackPanel();
- buttonContent.Orientation = Orientation.Horizontal;
- button.Content = buttonContent;
-
- if (prediction != actual)
- {
- button.Background = redBrush;
- errors++;
- ErrorBlock.Text = $"Errors: {errors}";
- }
-
- buttonContent.Children.Add(imageControl);
- buttonContent.Children.Add(textBlock);
-
- panel.Children.Add(button);
-
- TimeSpan duration = DateTimeOffset.Now - startTime;
- TimingBlock.Text = $"Duration (seconds): {duration.TotalSeconds:0}";
- }
-
- private void ToggleCorrectness(object sender, RoutedEventArgs e)
- {
- var button = sender as Button;
- if (button == null) return;
-
- if (button.Background == whiteBrush)
- {
- button.Background = redBrush;
- errors++;
- }
- else
- {
- button.Background = whiteBrush;
- errors--;
- }
- ErrorBlock.Text = $"Errors: {errors}";
- }
- }
-}
diff --git a/DigitDisplay/Properties/AssemblyInfo.cs b/DigitDisplay/Properties/AssemblyInfo.cs
index 5ffcb34..a82d524 100644
--- a/DigitDisplay/Properties/AssemblyInfo.cs
+++ b/DigitDisplay/Properties/AssemblyInfo.cs
@@ -1,6 +1,4 @@
using System.Reflection;
-using System.Resources;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
diff --git a/DigitDisplay/Properties/Resources.Designer.cs b/DigitDisplay/Properties/Resources.Designer.cs
index d0f6630..ef490bc 100644
--- a/DigitDisplay/Properties/Resources.Designer.cs
+++ b/DigitDisplay/Properties/Resources.Designer.cs
@@ -1,17 +1,17 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.34014
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
-namespace DigitDisplay.Properties
-{
-
-
+namespace DigitDisplay.Properties {
+ using System;
+
+
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
@@ -19,51 +19,43 @@ namespace DigitDisplay.Properties
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources
- {
-
+ internal class Resources {
+
private static global::System.Resources.ResourceManager resourceMan;
-
+
private static global::System.Globalization.CultureInfo resourceCulture;
-
+
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources()
- {
+ internal Resources() {
}
-
+
///
/// Returns the cached ResourceManager instance used by this class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager
- {
- get
- {
- if ((resourceMan == null))
- {
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DigitDisplay.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
-
+
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture
- {
- get
- {
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
return resourceCulture;
}
- set
- {
+ set {
resourceCulture = value;
}
}
diff --git a/DigitDisplay/Properties/Settings.Designer.cs b/DigitDisplay/Properties/Settings.Designer.cs
index fa5dec5..f2a0bc6 100644
--- a/DigitDisplay/Properties/Settings.Designer.cs
+++ b/DigitDisplay/Properties/Settings.Designer.cs
@@ -1,28 +1,24 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.34014
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
-namespace DigitDisplay.Properties
-{
-
-
+namespace DigitDisplay.Properties {
+
+
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
- internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
- {
-
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-
- public static Settings Default
- {
- get
- {
+
+ public static Settings Default {
+ get {
return defaultInstance;
}
}
diff --git a/DigitDisplay/RecognizerControl.xaml.cs b/DigitDisplay/RecognizerControl.xaml.cs
deleted file mode 100644
index 7a01256..0000000
--- a/DigitDisplay/RecognizerControl.xaml.cs
+++ /dev/null
@@ -1,127 +0,0 @@
-using DigitLoader;
-using Microsoft.FSharp.Core;
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-
-namespace DigitDisplay
-{
- public partial class RecognizerControl : UserControl
- {
- string classifierName;
- FSharpFunc classifier;
- string[] rawData;
-
- DateTimeOffset startTime;
- SolidColorBrush redBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 150, 150));
- SolidColorBrush whiteBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 255, 255));
- int errors = 0;
-
- public RecognizerControl(string classifierName, FSharpFunc classifier,
- string[] rawData)
- {
- InitializeComponent();
- this.classifierName = classifierName;
- this.classifier = classifier;
- this.rawData = rawData;
- Loaded += RecognizerControl_Loaded;
- }
-
- private void RecognizerControl_Loaded(object sender, RoutedEventArgs e)
- {
-
- ClassifierText.Text = classifierName;
- PopulatePanel(rawData);
- }
-
- private void PopulatePanel(string[] rawData)
- {
- var tasks = new List>();
- foreach (var imageString in rawData)
- {
- int actual = imageString.Split(',').Select(x => Convert.ToInt32(x)).First();
- var task = Task.Run(() =>
- {
- int[] ints = imageString.Split(',').Select(x => Convert.ToInt32(x)).Skip(1).ToArray();
- return Recognizer.predict(ints, classifier);
- }
- );
- tasks.Add(task);
- task.ContinueWith(t =>
- {
- CreateUIElements(t.Result, actual.ToString(), imageString, DigitsBox);
- },
- TaskScheduler.FromCurrentSynchronizationContext()
- );
- }
- Task.WhenAny(tasks).ContinueWith(t => startTime = DateTime.Now);
- }
-
- private void CreateUIElements(string prediction, string actual, string imageData,
- Panel panel)
- {
- Bitmap image = DigitBitmap.GetBitmapFromRawData(imageData);
-
- var multiplier = 1.5;
- var imageControl = new System.Windows.Controls.Image();
- imageControl.Source = image.ToWpfBitmap();
- imageControl.Stretch = Stretch.UniformToFill;
- imageControl.Width = imageControl.Source.Width * multiplier;
- imageControl.Height = imageControl.Source.Height * multiplier;
-
- var textBlock = new TextBlock();
- textBlock.Height = imageControl.Height;
- textBlock.Width = imageControl.Width;
- textBlock.FontSize = 12; // * multiplier;
- textBlock.TextAlignment = TextAlignment.Center;
- textBlock.Text = prediction;
-
- var button = new Button();
- var backgroundBrush = whiteBrush;
- button.Background = backgroundBrush;
- button.Click += ToggleCorrectness;
-
- var buttonContent = new StackPanel();
- buttonContent.Orientation = Orientation.Horizontal;
- button.Content = buttonContent;
-
- if (prediction != actual)
- {
- button.Background = redBrush;
- errors++;
- ErrorBlock.Text = $"Errors: {errors}";
- }
-
- buttonContent.Children.Add(imageControl);
- buttonContent.Children.Add(textBlock);
-
- panel.Children.Add(button);
-
- TimeSpan duration = DateTimeOffset.Now - startTime;
- TimingBlock.Text = $"Duration (seconds): {duration.TotalSeconds:0}";
- }
-
- private void ToggleCorrectness(object sender, RoutedEventArgs e)
- {
- var button = sender as Button;
- if (button == null) return;
-
- if (button.Background == whiteBrush)
- {
- button.Background = redBrush;
- errors++;
- }
- else
- {
- button.Background = whiteBrush;
- errors--;
- }
- ErrorBlock.Text = $"Errors: {errors}";
- }
- }
-}
diff --git a/DigitDisplay/RecognizerControl.xaml b/DigitDisplay/RecognizerUserControl.xaml
similarity index 91%
rename from DigitDisplay/RecognizerControl.xaml
rename to DigitDisplay/RecognizerUserControl.xaml
index 590ab0d..22c08a5 100644
--- a/DigitDisplay/RecognizerControl.xaml
+++ b/DigitDisplay/RecognizerUserControl.xaml
@@ -1,9 +1,8 @@
-
diff --git a/DigitDisplay/RecognizerUserControl.xaml.cs b/DigitDisplay/RecognizerUserControl.xaml.cs
new file mode 100644
index 0000000..f753f59
--- /dev/null
+++ b/DigitDisplay/RecognizerUserControl.xaml.cs
@@ -0,0 +1,100 @@
+using DigitLoader;
+using System;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using ObservationLoader;
+
+namespace DigitDisplay
+{
+ public partial class RecognizerUserControl
+ {
+ private static readonly SolidColorBrush RedBrush = new SolidColorBrush(Color.FromRgb(255, 150, 150));
+ private static readonly SolidColorBrush WhiteBrush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
+
+ private DateTimeOffset _startTime;
+ private int _errors;
+ public RecognizerUserControl(string classifierName, Action<(Observation, Action)[]> dispatcher,
+ Observation[] rawData)
+ {
+ InitializeComponent();
+ ClassifierText.Text = classifierName;
+
+ Loaded += (_, __) => PopulatePanel(rawData, dispatcher) ;
+ }
+
+ private void PopulatePanel(Observation[] input, Action<(Observation, Action)[]> dispatcher)
+ {
+ (Observation, Action)[] toDispatch = input.Zip(input.Select(CreateButton), (observation, show) => (observation, show)).ToArray();
+ _startTime = DateTimeOffset.Now;
+ dispatcher(toDispatch);
+ }
+
+ private Action CreateButton(Observation observation)
+ {
+ var imageSource = DigitBitmap.GetBitmapFromRawData(observation.Pixels).ToWpfBitmap();
+ var image = new Image
+ {
+ Source = imageSource,
+ Stretch = Stretch.UniformToFill,
+ Width = imageSource.Width * 1.5,
+ Height = imageSource.Height * 1.5
+ };
+ var textBlock = new TextBlock
+ {
+ Height = image.Height,
+ Width = image.Width,
+ FontSize = 12,
+ TextAlignment = TextAlignment.Center
+ };
+
+ var button = new Button();
+ button.Click += ToggleCorrectness;
+ button.Background = WhiteBrush;
+
+ var buttonContent = new StackPanel { Orientation = Orientation.Horizontal };
+ buttonContent.Children.Add(image);
+ buttonContent.Children.Add(textBlock);
+ button.Content = buttonContent;
+
+ void ShowButton(string predicted)
+ {
+ textBlock.Text = predicted;
+ if (predicted != observation.Label)
+ {
+ button.Background = RedBrush;
+ ChangeErrorsCount(1);
+ }
+ DigitsBox.Children.Add(button);
+
+ TimingBlock.Text = "Duration (seconds): " + (DateTimeOffset.Now - _startTime).TotalSeconds.ToString("0");
+ }
+
+ return ShowButton;
+ }
+
+ private void ToggleCorrectness(object sender, RoutedEventArgs e)
+ {
+ switch (sender)
+ {
+ case Button whiteButton when ReferenceEquals(whiteButton.Background, WhiteBrush):
+ whiteButton.Background = RedBrush;
+ ChangeErrorsCount(1);
+ break;
+ case Button redButton when ReferenceEquals(redButton.Background, RedBrush):
+ redButton.Background = WhiteBrush;
+ ChangeErrorsCount(-1);
+ break;
+ default:
+ return;
+ }
+ }
+
+ private void ChangeErrorsCount(int errorDiff)
+ {
+ _errors += errorDiff;
+ ErrorBlock.Text = "Errors: " + _errors.ToString("0");
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigitDisplay/packages.config b/DigitDisplay/packages.config
new file mode 100644
index 0000000..61fc68c
--- /dev/null
+++ b/DigitDisplay/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/DigitLoader.Test/DigitBitmapTest.cs b/DigitLoader.Test/DigitBitmapTest.cs
index 3874193..d15604f 100644
--- a/DigitLoader.Test/DigitBitmapTest.cs
+++ b/DigitLoader.Test/DigitBitmapTest.cs
@@ -1,5 +1,4 @@
-using System;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace DigitLoader.Test
{
@@ -7,7 +6,7 @@ namespace DigitLoader.Test
public class DigitBitmapTest
{
// Sample Record
- string sample = "3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,130,190,254,254,250,175,135,96,96,16,4,0,0,0,0,0,0,0,0,0,0,0,0,0,26,102,186,254,254,248,222,222,225,254,254,254,254,254,206,112,4,0,0,0,0,0,0,0,0,0,0,0,207,254,254,177,117,39,0,0,56,248,102,48,48,103,192,254,135,0,0,0,0,0,0,0,0,0,0,0,91,111,36,0,0,0,0,0,72,92,0,0,0,0,12,224,210,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,139,240,254,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,121,220,254,244,194,15,0,0,0,0,0,0,0,0,0,0,0,0,0,8,107,112,112,112,87,112,141,218,248,177,68,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,221,254,254,254,254,254,225,104,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,32,32,32,32,130,215,195,47,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,111,231,174,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,18,0,0,0,0,0,0,0,0,0,40,228,205,35,0,0,0,0,0,0,0,0,0,0,0,0,22,234,42,0,0,0,0,0,0,0,0,0,0,56,212,226,38,0,0,0,0,0,0,0,0,0,0,0,96,157,0,0,0,0,0,0,0,0,0,0,0,0,30,215,188,9,0,0,0,0,0,0,0,0,0,0,96,142,0,0,0,0,0,0,0,0,0,0,0,0,0,86,254,68,0,0,0,0,0,0,0,0,0,0,71,202,15,0,0,0,0,0,0,0,0,0,0,0,0,6,214,151,0,0,0,0,0,0,0,0,0,0,10,231,86,2,0,0,0,0,0,0,0,0,0,0,0,0,191,207,0,0,0,0,0,0,0,0,0,0,0,93,248,129,7,0,0,0,0,0,0,0,0,0,0,117,238,112,0,0,0,0,0,0,0,0,0,0,0,0,94,248,209,73,12,0,0,0,0,0,0,42,147,252,136,9,0,0,0,0,0,0,0,0,0,0,0,0,0,48,160,215,230,158,74,64,94,153,223,250,214,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,129,189,234,224,255,194,134,75,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
+ int[] sample = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,130,190,254,254,250,175,135,96,96,16,4,0,0,0,0,0,0,0,0,0,0,0,0,0,26,102,186,254,254,248,222,222,225,254,254,254,254,254,206,112,4,0,0,0,0,0,0,0,0,0,0,0,207,254,254,177,117,39,0,0,56,248,102,48,48,103,192,254,135,0,0,0,0,0,0,0,0,0,0,0,91,111,36,0,0,0,0,0,72,92,0,0,0,0,12,224,210,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,139,240,254,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,121,220,254,244,194,15,0,0,0,0,0,0,0,0,0,0,0,0,0,8,107,112,112,112,87,112,141,218,248,177,68,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,221,254,254,254,254,254,225,104,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,32,32,32,32,130,215,195,47,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,111,231,174,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,18,0,0,0,0,0,0,0,0,0,40,228,205,35,0,0,0,0,0,0,0,0,0,0,0,0,22,234,42,0,0,0,0,0,0,0,0,0,0,56,212,226,38,0,0,0,0,0,0,0,0,0,0,0,96,157,0,0,0,0,0,0,0,0,0,0,0,0,30,215,188,9,0,0,0,0,0,0,0,0,0,0,96,142,0,0,0,0,0,0,0,0,0,0,0,0,0,86,254,68,0,0,0,0,0,0,0,0,0,0,71,202,15,0,0,0,0,0,0,0,0,0,0,0,0,6,214,151,0,0,0,0,0,0,0,0,0,0,10,231,86,2,0,0,0,0,0,0,0,0,0,0,0,0,191,207,0,0,0,0,0,0,0,0,0,0,0,93,248,129,7,0,0,0,0,0,0,0,0,0,0,117,238,112,0,0,0,0,0,0,0,0,0,0,0,0,94,248,209,73,12,0,0,0,0,0,0,42,147,252,136,9,0,0,0,0,0,0,0,0,0,0,0,0,0,48,160,215,230,158,74,64,94,153,223,250,214,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,129,189,234,224,255,194,134,75,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int[] array0 = new int[28] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] array1 = new int[28] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
diff --git a/DigitLoader.Test/DigitLoader.Test.csproj b/DigitLoader.Test/DigitLoader.Test.csproj
index 84b618d..9cfbb38 100644
--- a/DigitLoader.Test/DigitLoader.Test.csproj
+++ b/DigitLoader.Test/DigitLoader.Test.csproj
@@ -8,7 +8,7 @@
Properties
DigitLoader.Test
DigitLoader.Test
- v4.5
+ v4.6.1
512
{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
10.0
@@ -16,6 +16,7 @@
$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
False
UnitTest
+
true
diff --git a/DigitLoader.Test/Properties/AssemblyInfo.cs b/DigitLoader.Test/Properties/AssemblyInfo.cs
index 38aa4cc..aa7d11e 100644
--- a/DigitLoader.Test/Properties/AssemblyInfo.cs
+++ b/DigitLoader.Test/Properties/AssemblyInfo.cs
@@ -1,5 +1,4 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
diff --git a/DigitLoader/DigitBitmap.cs b/DigitLoader/DigitBitmap.cs
index 0f56629..a863624 100644
--- a/DigitLoader/DigitBitmap.cs
+++ b/DigitLoader/DigitBitmap.cs
@@ -1,20 +1,12 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
+using System.Drawing;
using System.Linq;
namespace DigitLoader
{
public class DigitBitmap
{
- public static int[][] GenerateDigitArray(string input)
+ public static int[][] GenerateDigitArray(int[] integerData)
{
- var rawData = input.Split(',');
- var integerData = rawData
- //.Skip(1)
- .Select(x => Convert.ToInt32(x))
- .ToArray();
-
var output = new int[28][];
for (int i = 0; i < 28; i++)
{
@@ -26,7 +18,7 @@ public static int[][] GenerateDigitArray(string input)
return output;
}
- public static Bitmap GetBitmapFromRawData(string input)
+ public static Bitmap GetBitmapFromRawData(int[] input)
{
var digitArray = GenerateDigitArray(input);
@@ -42,6 +34,5 @@ public static Bitmap GetBitmapFromRawData(string input)
digitBitmap.MakeTransparent(Color.White);
return digitBitmap;
}
-
}
}
diff --git a/DigitLoader/DigitLoader.csproj b/DigitLoader/DigitLoader.csproj
index 54ac029..84233c0 100644
--- a/DigitLoader/DigitLoader.csproj
+++ b/DigitLoader/DigitLoader.csproj
@@ -9,8 +9,9 @@
Properties
DigitLoader
DigitLoader
- v4.5
+ v4.6.1
512
+
true
@@ -45,6 +46,12 @@
+
+
+ {301ec918-d5e6-4c89-9cd0-84c35fc7413c}
+ ObservationLoader
+
+