├── .gitattributes ├── .gitignore ├── 3rdParty ├── AForge.Imaging.dll ├── AForge.Math.dll └── AForge.dll ├── Binaries ├── AForge.Imaging.dll ├── AForge.Math.dll ├── AForge.dll ├── MachineLearningOCRTool.exe ├── MachineLearningOCRTool.exe.config ├── MathNet.Numerics.IO.dll └── MathNet.Numerics.dll ├── InputSheet.docx ├── MachineLearningOCRTool.sln ├── MachineLearningOCRTool ├── App.config ├── Common.cs ├── Controls │ ├── BlobPanel.Designer.cs │ ├── BlobPanel.cs │ └── BlobPanel.resx ├── Enums.cs ├── MachineLearningOCRTool.csproj ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Views │ ├── OCRTool.Designer.cs │ ├── OCRTool.cs │ └── OCRTool.resx └── packages.config ├── README.md ├── license.txt └── packages ├── MathNet.Numerics.2.5.0 ├── MathNet.Numerics.2.5.0.nupkg ├── MathNet.Numerics.2.5.0.nuspec ├── lib │ ├── net40 │ │ ├── MathNet.Numerics.IO.dll │ │ ├── MathNet.Numerics.IO.xml │ │ ├── MathNet.Numerics.dll │ │ └── MathNet.Numerics.xml │ └── portable-net40+windows8+wp8+sl5 │ │ ├── MathNet.Numerics.dll │ │ └── MathNet.Numerics.xml ├── license.txt └── readme.txt └── repositories.config /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | 11 | [Dd]ebug/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | [Bb]in/ 16 | [Oo]bj/ 17 | 18 | # MSTest test Results 19 | [Tt]est[Rr]esult*/ 20 | [Bb]uild[Ll]og.* 21 | 22 | *_i.c 23 | *_p.c 24 | *.ilk 25 | *.meta 26 | *.obj 27 | *.pch 28 | *.pdb 29 | *.pgc 30 | *.pgd 31 | *.rsp 32 | *.sbr 33 | *.tlb 34 | *.tli 35 | *.tlh 36 | *.tmp 37 | *.tmp_proj 38 | *.log 39 | *.vspscc 40 | *.vssscc 41 | .builds 42 | *.pidb 43 | *.log 44 | *.scc 45 | 46 | # Visual C++ cache files 47 | ipch/ 48 | *.aps 49 | *.ncb 50 | *.opensdf 51 | *.sdf 52 | *.cachefile 53 | 54 | # Visual Studio profiler 55 | *.psess 56 | *.vsp 57 | *.vspx 58 | 59 | # Guidance Automation Toolkit 60 | *.gpState 61 | 62 | # ReSharper is a .NET coding add-in 63 | _ReSharper*/ 64 | *.[Rr]e[Ss]harper 65 | 66 | # TeamCity is a build add-in 67 | _TeamCity* 68 | 69 | # DotCover is a Code Coverage Tool 70 | *.dotCover 71 | 72 | # NCrunch 73 | *.ncrunch* 74 | .*crunch*.local.xml 75 | 76 | # Installshield output folder 77 | [Ee]xpress/ 78 | 79 | # DocProject is a documentation generator add-in 80 | DocProject/buildhelp/ 81 | DocProject/Help/*.HxT 82 | DocProject/Help/*.HxC 83 | DocProject/Help/*.hhc 84 | DocProject/Help/*.hhk 85 | DocProject/Help/*.hhp 86 | DocProject/Help/Html2 87 | DocProject/Help/html 88 | 89 | # Click-Once directory 90 | publish/ 91 | 92 | # Publish Web Output 93 | *.Publish.xml 94 | *.pubxml 95 | 96 | # NuGet Packages Directory 97 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 98 | #packages/ 99 | 100 | # Windows Azure Build Output 101 | csx 102 | *.build.csdef 103 | 104 | # Windows Store app package directory 105 | AppPackages/ 106 | 107 | # Others 108 | sql/ 109 | *.Cache 110 | ClientBin/ 111 | [Ss]tyle[Cc]op.* 112 | ~$* 113 | *~ 114 | *.dbmdl 115 | *.[Pp]ublish.xml 116 | *.pfx 117 | *.publishsettings 118 | 119 | # RIA/Silverlight projects 120 | Generated_Code/ 121 | 122 | # Backup & report files from converting an old project file to a newer 123 | # Visual Studio version. Backup files are not needed, because we have git ;-) 124 | _UpgradeReport_Files/ 125 | Backup*/ 126 | UpgradeLog*.XML 127 | UpgradeLog*.htm 128 | 129 | # SQL Server files 130 | App_Data/*.mdf 131 | App_Data/*.ldf 132 | 133 | 134 | #LightSwitch generated files 135 | GeneratedArtifacts/ 136 | _Pvt_Extensions/ 137 | ModelManifest.xml 138 | 139 | # ========================= 140 | # Windows detritus 141 | # ========================= 142 | 143 | # Windows image file caches 144 | Thumbs.db 145 | ehthumbs.db 146 | 147 | # Folder config file 148 | Desktop.ini 149 | 150 | # Recycle Bin used on file shares 151 | $RECYCLE.BIN/ 152 | 153 | # Mac desktop service store files 154 | .DS_Store 155 | -------------------------------------------------------------------------------- /3rdParty/AForge.Imaging.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/3rdParty/AForge.Imaging.dll -------------------------------------------------------------------------------- /3rdParty/AForge.Math.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/3rdParty/AForge.Math.dll -------------------------------------------------------------------------------- /3rdParty/AForge.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/3rdParty/AForge.dll -------------------------------------------------------------------------------- /Binaries/AForge.Imaging.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/Binaries/AForge.Imaging.dll -------------------------------------------------------------------------------- /Binaries/AForge.Math.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/Binaries/AForge.Math.dll -------------------------------------------------------------------------------- /Binaries/AForge.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/Binaries/AForge.dll -------------------------------------------------------------------------------- /Binaries/MachineLearningOCRTool.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/Binaries/MachineLearningOCRTool.exe -------------------------------------------------------------------------------- /Binaries/MachineLearningOCRTool.exe.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Binaries/MathNet.Numerics.IO.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/Binaries/MathNet.Numerics.IO.dll -------------------------------------------------------------------------------- /Binaries/MathNet.Numerics.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/Binaries/MathNet.Numerics.dll -------------------------------------------------------------------------------- /InputSheet.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/InputSheet.docx -------------------------------------------------------------------------------- /MachineLearningOCRTool.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MachineLearningOCRTool", "MachineLearningOCRTool\MachineLearningOCRTool.csproj", "{6337A099-D1CC-44D6-857C-FE0E44E5C0D7}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {6337A099-D1CC-44D6-857C-FE0E44E5C0D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {6337A099-D1CC-44D6-857C-FE0E44E5C0D7}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {6337A099-D1CC-44D6-857C-FE0E44E5C0D7}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {6337A099-D1CC-44D6-857C-FE0E44E5C0D7}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Common.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | 5 | namespace MachineLearningOCRTool 6 | { 7 | public static class Common 8 | { 9 | private static string[] m_letters = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", 10 | "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", 11 | "U", "V", "W", "X", "Y", "Z"}; 12 | 13 | public static string[] Letters {get { return m_letters; }} 14 | 15 | public static void ForEach(this IEnumerable enumeration, Action action) 16 | { 17 | foreach (T item in enumeration) 18 | { 19 | action(item); 20 | } 21 | } 22 | 23 | public static void SetDoubleBuffered(System.Windows.Forms.Control c) 24 | { 25 | System.Reflection.PropertyInfo aProp = 26 | typeof(System.Windows.Forms.Control).GetProperty( 27 | "DoubleBuffered", 28 | System.Reflection.BindingFlags.NonPublic | 29 | System.Reflection.BindingFlags.Instance); 30 | 31 | aProp.SetValue(c, true, null); 32 | } 33 | 34 | public static int GetColorAverage(Color color) 35 | { 36 | return (color.R + color.G + color.B)/3; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Controls/BlobPanel.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace MachineLearningOCRTool.Controls 2 | { 3 | partial class BlobPanel 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); 33 | this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 34 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); 35 | this.contextMenuStrip1.SuspendLayout(); 36 | this.SuspendLayout(); 37 | // 38 | // contextMenuStrip1 39 | // 40 | this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 41 | this.deleteToolStripMenuItem}); 42 | this.contextMenuStrip1.Name = "contextMenuStrip1"; 43 | this.contextMenuStrip1.Size = new System.Drawing.Size(155, 26); 44 | // 45 | // deleteToolStripMenuItem 46 | // 47 | this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem"; 48 | this.deleteToolStripMenuItem.Size = new System.Drawing.Size(154, 22); 49 | this.deleteToolStripMenuItem.Text = "Delete Selected"; 50 | this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteToolStripMenuItem_Click); 51 | // 52 | // toolTip1 53 | // 54 | this.toolTip1.AutoPopDelay = 30000; 55 | this.toolTip1.InitialDelay = 500; 56 | this.toolTip1.ReshowDelay = 100; 57 | // 58 | // BlobPanel 59 | // 60 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 61 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 62 | this.Name = "BlobPanel"; 63 | this.Load += new System.EventHandler(this.BlobPanel_Load); 64 | this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.BlobPanel_MouseClick); 65 | this.contextMenuStrip1.ResumeLayout(false); 66 | this.ResumeLayout(false); 67 | 68 | } 69 | 70 | #endregion 71 | 72 | private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; 73 | private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem; 74 | private System.Windows.Forms.ToolTip toolTip1; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Controls/BlobPanel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Windows.Forms; 4 | 5 | namespace MachineLearningOCRTool.Controls 6 | { 7 | public partial class BlobPanel : UserControl 8 | { 9 | #region Members 10 | 11 | public event EventHandler SelectedChanged; 12 | public event EventHandler DeleteRequest; 13 | 14 | private bool m_resize; 15 | private string m_description; 16 | 17 | #endregion 18 | 19 | #region Properties 20 | 21 | public bool Selected { get; set; } 22 | public int RowIndex { get; set; } 23 | public string Title { get; set; } 24 | public string Description 25 | { 26 | get { return m_description; } 27 | set 28 | { 29 | m_description = value; 30 | toolTip1.SetToolTip(this, m_description); 31 | } 32 | } 33 | 34 | #endregion 35 | 36 | public BlobPanel() 37 | { 38 | InitializeComponent(); 39 | 40 | // Use double-buffering for flicker-free updating: 41 | SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw, true); 42 | SetStyle(ControlStyles.SupportsTransparentBackColor, true); 43 | } 44 | 45 | private void BlobPanel_Load(object sender, EventArgs e) 46 | { 47 | // Set some properties. 48 | BackColor = Color.Transparent; 49 | ForeColor = Color.Red; 50 | BorderStyle = BorderStyle.None; 51 | Selected = false; 52 | 53 | // Register to events. 54 | MouseLeave += BlobPanel_MouseLeave; 55 | MouseMove += BlobPanel_MouseMove; 56 | MouseDown += BlobPanel_MouseDown; 57 | MouseUp += BlobPanel_MouseUp; 58 | Paint += BlobPanel_Paint; 59 | } 60 | 61 | #region Methods 62 | 63 | /// 64 | /// Checks whether the given location is on the edge of the panel (i.e the resizing zone). 65 | /// 66 | private EdgeEnum IsOnEdge(Point location) 67 | { 68 | if (location.X <= 2) 69 | { 70 | return EdgeEnum.Left; 71 | } 72 | if (Math.Abs(location.X - Width) <= 2) 73 | { 74 | return EdgeEnum.Right; 75 | } 76 | if (location.Y <= 2) 77 | { 78 | return EdgeEnum.Top; 79 | } 80 | if (Math.Abs(location.Y - Height) <= 2) 81 | { 82 | return EdgeEnum.Bottom; 83 | } 84 | 85 | return EdgeEnum.None; 86 | } 87 | 88 | /// 89 | /// Resizes the panel. 90 | /// 91 | public void Resize(int width, int height) 92 | { 93 | int wDiff = width - Width; 94 | int hDiff = height - Height; 95 | 96 | Width += wDiff; 97 | Height += hDiff; 98 | Location = new Point(Location.X - wDiff / 2, Location.Y - hDiff/2); 99 | } 100 | 101 | /// 102 | /// Raises the SelectedChanged event. 103 | /// 104 | protected virtual void OnSelectedChanged(EventArgs args) 105 | { 106 | if (SelectedChanged != null) 107 | SelectedChanged(this, args); 108 | } 109 | 110 | /// 111 | /// Raises the DeleteRequest event. 112 | /// 113 | protected virtual void OnDeleteRequest(EventArgs args) 114 | { 115 | if (DeleteRequest != null) 116 | DeleteRequest(this, args); 117 | } 118 | 119 | #endregion 120 | 121 | #region EventHandlers 122 | 123 | private void BlobPanel_Paint(object sender, PaintEventArgs e) 124 | { 125 | // Get the border width. 126 | int size = 1; 127 | if (Selected) 128 | size = 2; 129 | 130 | // Draw the border only. 131 | e.Graphics.DrawRectangle(new Pen(ForeColor, size), Rectangle.Inflate(ClientRectangle, -1*size, -1*size)); 132 | } 133 | 134 | private void BlobPanel_MouseDown(object sender, MouseEventArgs e) 135 | { 136 | // We care only for right-click. 137 | if (e.Button != MouseButtons.Left) 138 | return; 139 | 140 | // Check on what edge we are clicked. 141 | EdgeEnum edge = IsOnEdge(e.Location); 142 | 143 | // If we are not on any edge it means we should select this blob. 144 | if (edge == EdgeEnum.None) 145 | { 146 | // Flip the selection flag on the Panel and raise event. 147 | Selected = !Selected; 148 | OnSelectedChanged(EventArgs.Empty); 149 | Invalidate(); 150 | 151 | return; 152 | } 153 | 154 | // We are on some edge, activate the resizing. 155 | m_resize = true; 156 | } 157 | 158 | private void BlobPanel_MouseUp(object sender, MouseEventArgs e) 159 | { 160 | // Stop resizing. 161 | m_resize = false; 162 | } 163 | 164 | private void BlobPanel_MouseMove(object sender, MouseEventArgs e) 165 | { 166 | // Get what edge we are on. 167 | EdgeEnum edge = IsOnEdge(e.Location); 168 | 169 | switch (edge) 170 | { 171 | case EdgeEnum.Left: 172 | // Set the resize cursor 173 | Cursor = Cursors.SizeWE; 174 | 175 | // If resizing update location and width. 176 | if (m_resize) 177 | { 178 | // Since we are resizing the left border we need to move the entire panel, so first we move it. 179 | Location = new Point(Location.X + e.X, Location.Y); 180 | 181 | // Since we moved the panel we need now to extend (or shrink) it accordingly. 182 | Width += -1*e.X; 183 | Invalidate(); 184 | } 185 | break; 186 | case EdgeEnum.Right: 187 | // Set the resize cursor 188 | Cursor = Cursors.SizeWE; 189 | 190 | // If resizing update location and width. 191 | if (m_resize) 192 | { 193 | // We move the right panel, so all we do is update the width accordingly (no need to move the panel). 194 | Width = e.X; 195 | Invalidate(); 196 | } 197 | break; 198 | case EdgeEnum.Top: 199 | // Set the resize cursor 200 | Cursor = Cursors.SizeNS; 201 | 202 | // If resizing update location and width. 203 | if (m_resize) 204 | { 205 | // Since we are resizing the top border we need to move the entire panel, so first we move it. 206 | Location = new Point(Location.X, Location.Y + e.Y); 207 | 208 | // Since we moved the panel we need now to extend (or shrink) it accordingly. 209 | Height += -1*e.Y; 210 | Invalidate(); 211 | } 212 | break; 213 | case EdgeEnum.Bottom: 214 | // Set the resize cursor 215 | Cursor = Cursors.SizeNS; 216 | 217 | // If resizing update location and width. 218 | if (m_resize) 219 | { 220 | // We move the bottom panel, so all we do is update the height accordingly (no need to move the panel). 221 | Height = e.Y; 222 | Invalidate(); 223 | } 224 | break; 225 | default: 226 | // Set the select cursor 227 | Cursor = Cursors.Hand; 228 | break; 229 | } 230 | } 231 | 232 | private void BlobPanel_MouseLeave(object sender, EventArgs e) 233 | { 234 | // Reset the cursor when we leave the panel. 235 | Cursor = Cursors.Default; 236 | } 237 | 238 | private void deleteToolStripMenuItem_Click(object sender, EventArgs e) 239 | { 240 | // Hide the context menu and raise the delete event. 241 | contextMenuStrip1.Hide(); 242 | OnDeleteRequest(EventArgs.Empty); 243 | } 244 | 245 | private void BlobPanel_MouseClick(object sender, MouseEventArgs e) 246 | { 247 | // Shoe context menu on right-click. 248 | if (e.Button == MouseButtons.Right) 249 | contextMenuStrip1.Show(PointToScreen(e.Location)); 250 | } 251 | 252 | #endregion 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Controls/BlobPanel.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 172, 17 125 | 126 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Enums.cs: -------------------------------------------------------------------------------- 1 | namespace MachineLearningOCRTool 2 | { 3 | public enum EdgeEnum 4 | { 5 | None, 6 | Top, 7 | Bottom, 8 | Left, 9 | Right 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/MachineLearningOCRTool.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6337A099-D1CC-44D6-857C-FE0E44E5C0D7} 8 | WinExe 9 | Properties 10 | MachineLearningOCRTool 11 | MachineLearningOCRTool 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | publish\ 23 | true 24 | Disk 25 | false 26 | Foreground 27 | 7 28 | Days 29 | false 30 | false 31 | true 32 | 0 33 | 1.0.0.%2a 34 | false 35 | false 36 | true 37 | 38 | 39 | AnyCPU 40 | true 41 | full 42 | false 43 | bin\Debug\ 44 | DEBUG;TRACE 45 | prompt 46 | 4 47 | 48 | 49 | AnyCPU 50 | pdbonly 51 | true 52 | bin\Release\ 53 | TRACE 54 | prompt 55 | 4 56 | 57 | 58 | 59 | False 60 | ..\3rdParty\AForge.dll 61 | 62 | 63 | ..\3rdParty\AForge.Imaging.dll 64 | 65 | 66 | ..\packages\MathNet.Numerics.2.5.0\lib\net40\MathNet.Numerics.dll 67 | 68 | 69 | ..\packages\MathNet.Numerics.2.5.0\lib\net40\MathNet.Numerics.IO.dll 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | UserControl 87 | 88 | 89 | BlobPanel.cs 90 | 91 | 92 | 93 | Form 94 | 95 | 96 | OCRTool.cs 97 | 98 | 99 | 100 | 101 | BlobPanel.cs 102 | 103 | 104 | OCRTool.cs 105 | 106 | 107 | ResXFileCodeGenerator 108 | Resources.Designer.cs 109 | Designer 110 | 111 | 112 | True 113 | Resources.resx 114 | 115 | 116 | 117 | SettingsSingleFileGenerator 118 | Settings.Designer.cs 119 | 120 | 121 | True 122 | Settings.settings 123 | True 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | False 132 | Microsoft .NET Framework 4.5 %28x86 and x64%29 133 | true 134 | 135 | 136 | False 137 | .NET Framework 3.5 SP1 Client Profile 138 | false 139 | 140 | 141 | False 142 | .NET Framework 3.5 SP1 143 | false 144 | 145 | 146 | 147 | 154 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using MachineLearningOCRTool.Views; 4 | 5 | namespace MachineLearningOCRTool 6 | { 7 | static class Program 8 | { 9 | /// 10 | /// The main entry point for the application. 11 | /// 12 | [STAThread] 13 | static void Main() 14 | { 15 | Application.EnableVisualStyles(); 16 | Application.SetCompatibleTextRenderingDefault(false); 17 | Application.Run(new OCRTool()); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MachineLearningOCRTool")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("MachineLearningOCRTool")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a4fdd4a3-1d40-4b46-acc0-d29033bc9600")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.17929 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MachineLearningOCRTool.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MachineLearningOCRTool.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.17929 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MachineLearningOCRTool.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("")] 29 | public string InputImage { 30 | get { 31 | return ((string)(this["InputImage"])); 32 | } 33 | set { 34 | this["InputImage"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("")] 41 | public string ModelParams { 42 | get { 43 | return ((string)(this["ModelParams"])); 44 | } 45 | set { 46 | this["ModelParams"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("")] 53 | public string OutputFile { 54 | get { 55 | return ((string)(this["OutputFile"])); 56 | } 57 | set { 58 | this["OutputFile"] = value; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Views/OCRTool.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace MachineLearningOCRTool.Views 2 | { 3 | partial class OCRTool 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OCRTool)); 33 | this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); 34 | this.btnOpenFile = new System.Windows.Forms.Button(); 35 | this.txtFile = new System.Windows.Forms.TextBox(); 36 | this.pictureBox1 = new System.Windows.Forms.PictureBox(); 37 | this.panel1 = new System.Windows.Forms.Panel(); 38 | this.button1 = new System.Windows.Forms.Button(); 39 | this.txtPostMergeFilter = new System.Windows.Forms.NumericUpDown(); 40 | this.label1 = new System.Windows.Forms.Label(); 41 | this.label2 = new System.Windows.Forms.Label(); 42 | this.txtPreMergeFilter = new System.Windows.Forms.NumericUpDown(); 43 | this.lblSelected = new System.Windows.Forms.Label(); 44 | this.label3 = new System.Windows.Forms.Label(); 45 | this.txtHeightMergeSense = new System.Windows.Forms.NumericUpDown(); 46 | this.label4 = new System.Windows.Forms.Label(); 47 | this.txtWidthMergeSense = new System.Windows.Forms.NumericUpDown(); 48 | this.label5 = new System.Windows.Forms.Label(); 49 | this.txtBinThershold = new System.Windows.Forms.NumericUpDown(); 50 | this.chkShowBinarize = new System.Windows.Forms.CheckBox(); 51 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 52 | this.label6 = new System.Windows.Forms.Label(); 53 | this.txtResizeInterval = new System.Windows.Forms.NumericUpDown(); 54 | this.btnResRight = new System.Windows.Forms.Button(); 55 | this.btnResLeft = new System.Windows.Forms.Button(); 56 | this.btnResDown = new System.Windows.Forms.Button(); 57 | this.btnResUp = new System.Windows.Forms.Button(); 58 | this.chkShowRows = new System.Windows.Forms.CheckBox(); 59 | this.btnExport = new System.Windows.Forms.Button(); 60 | this.label7 = new System.Windows.Forms.Label(); 61 | this.label8 = new System.Windows.Forms.Label(); 62 | this.txtOutput = new System.Windows.Forms.TextBox(); 63 | this.btnPredict = new System.Windows.Forms.Button(); 64 | this.txtModelParams = new System.Windows.Forms.TextBox(); 65 | this.label9 = new System.Windows.Forms.Label(); 66 | this.txtExtractedBackColor = new System.Windows.Forms.NumericUpDown(); 67 | this.label10 = new System.Windows.Forms.Label(); 68 | this.btnOpenModelFile = new System.Windows.Forms.Button(); 69 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); 70 | this.label12 = new System.Windows.Forms.Label(); 71 | this.label11 = new System.Windows.Forms.Label(); 72 | this.txtExportSize = new System.Windows.Forms.NumericUpDown(); 73 | this.groupBox2 = new System.Windows.Forms.GroupBox(); 74 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 75 | this.panel1.SuspendLayout(); 76 | ((System.ComponentModel.ISupportInitialize)(this.txtPostMergeFilter)).BeginInit(); 77 | ((System.ComponentModel.ISupportInitialize)(this.txtPreMergeFilter)).BeginInit(); 78 | ((System.ComponentModel.ISupportInitialize)(this.txtHeightMergeSense)).BeginInit(); 79 | ((System.ComponentModel.ISupportInitialize)(this.txtWidthMergeSense)).BeginInit(); 80 | ((System.ComponentModel.ISupportInitialize)(this.txtBinThershold)).BeginInit(); 81 | this.groupBox1.SuspendLayout(); 82 | ((System.ComponentModel.ISupportInitialize)(this.txtResizeInterval)).BeginInit(); 83 | ((System.ComponentModel.ISupportInitialize)(this.txtExtractedBackColor)).BeginInit(); 84 | ((System.ComponentModel.ISupportInitialize)(this.txtExportSize)).BeginInit(); 85 | this.groupBox2.SuspendLayout(); 86 | this.SuspendLayout(); 87 | // 88 | // openFileDialog1 89 | // 90 | this.openFileDialog1.InitialDirectory = "c:\\"; 91 | // 92 | // btnOpenFile 93 | // 94 | this.btnOpenFile.Location = new System.Drawing.Point(282, 5); 95 | this.btnOpenFile.Name = "btnOpenFile"; 96 | this.btnOpenFile.Size = new System.Drawing.Size(30, 23); 97 | this.btnOpenFile.TabIndex = 0; 98 | this.btnOpenFile.Text = "..."; 99 | this.btnOpenFile.UseVisualStyleBackColor = true; 100 | this.btnOpenFile.Click += new System.EventHandler(this.btnOpenFile_Click); 101 | // 102 | // txtFile 103 | // 104 | this.txtFile.Location = new System.Drawing.Point(83, 7); 105 | this.txtFile.Name = "txtFile"; 106 | this.txtFile.Size = new System.Drawing.Size(193, 20); 107 | this.txtFile.TabIndex = 1; 108 | this.toolTip1.SetToolTip(this.txtFile, "Image to load and analyze."); 109 | // 110 | // pictureBox1 111 | // 112 | this.pictureBox1.Location = new System.Drawing.Point(3, 3); 113 | this.pictureBox1.Name = "pictureBox1"; 114 | this.pictureBox1.Size = new System.Drawing.Size(342, 269); 115 | this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; 116 | this.pictureBox1.TabIndex = 2; 117 | this.pictureBox1.TabStop = false; 118 | this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click); 119 | this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint); 120 | // 121 | // panel1 122 | // 123 | this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 124 | | System.Windows.Forms.AnchorStyles.Left) 125 | | System.Windows.Forms.AnchorStyles.Right))); 126 | this.panel1.AutoScroll = true; 127 | this.panel1.Controls.Add(this.pictureBox1); 128 | this.panel1.Location = new System.Drawing.Point(12, 61); 129 | this.panel1.Name = "panel1"; 130 | this.panel1.Size = new System.Drawing.Size(842, 665); 131 | this.panel1.TabIndex = 3; 132 | // 133 | // button1 134 | // 135 | this.button1.Location = new System.Drawing.Point(318, 5); 136 | this.button1.Name = "button1"; 137 | this.button1.Size = new System.Drawing.Size(75, 23); 138 | this.button1.TabIndex = 4; 139 | this.button1.Text = "(Re)Process"; 140 | this.button1.UseVisualStyleBackColor = true; 141 | this.button1.Click += new System.EventHandler(this.button1_Click); 142 | // 143 | // txtPostMergeFilter 144 | // 145 | this.txtPostMergeFilter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 146 | this.txtPostMergeFilter.Increment = new decimal(new int[] { 147 | 5, 148 | 0, 149 | 0, 150 | 0}); 151 | this.txtPostMergeFilter.Location = new System.Drawing.Point(988, 215); 152 | this.txtPostMergeFilter.Maximum = new decimal(new int[] { 153 | 9999, 154 | 0, 155 | 0, 156 | 0}); 157 | this.txtPostMergeFilter.Name = "txtPostMergeFilter"; 158 | this.txtPostMergeFilter.Size = new System.Drawing.Size(54, 20); 159 | this.txtPostMergeFilter.TabIndex = 6; 160 | this.txtPostMergeFilter.Value = new decimal(new int[] { 161 | 150, 162 | 0, 163 | 0, 164 | 0}); 165 | // 166 | // label1 167 | // 168 | this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 169 | this.label1.AutoSize = true; 170 | this.label1.Location = new System.Drawing.Point(861, 217); 171 | this.label1.Name = "label1"; 172 | this.label1.Size = new System.Drawing.Size(112, 13); 173 | this.label1.TabIndex = 7; 174 | this.label1.Text = "Post Merge Filter Size:"; 175 | this.toolTip1.SetToolTip(this.label1, "The size of blobs (width*height) that will get filtered\r\nafter the merge process " + 176 | "finished. This is used\r\nto filter some medium sized blobs that are most\r\nlikely " + 177 | "not letters."); 178 | // 179 | // label2 180 | // 181 | this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 182 | this.label2.AutoSize = true; 183 | this.label2.Location = new System.Drawing.Point(861, 189); 184 | this.label2.Name = "label2"; 185 | this.label2.Size = new System.Drawing.Size(107, 13); 186 | this.label2.TabIndex = 9; 187 | this.label2.Text = "Pre Merge Filter Size:"; 188 | this.toolTip1.SetToolTip(this.label2, "The size of blobs (width*height) that will get filtered\r\nbefore the merge process" + 189 | " take place. This is used\r\nto filter some very small blobs."); 190 | // 191 | // txtPreMergeFilter 192 | // 193 | this.txtPreMergeFilter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 194 | this.txtPreMergeFilter.Increment = new decimal(new int[] { 195 | 5, 196 | 0, 197 | 0, 198 | 0}); 199 | this.txtPreMergeFilter.Location = new System.Drawing.Point(988, 187); 200 | this.txtPreMergeFilter.Maximum = new decimal(new int[] { 201 | 9999, 202 | 0, 203 | 0, 204 | 0}); 205 | this.txtPreMergeFilter.Name = "txtPreMergeFilter"; 206 | this.txtPreMergeFilter.Size = new System.Drawing.Size(54, 20); 207 | this.txtPreMergeFilter.TabIndex = 8; 208 | this.txtPreMergeFilter.Value = new decimal(new int[] { 209 | 10, 210 | 0, 211 | 0, 212 | 0}); 213 | // 214 | // lblSelected 215 | // 216 | this.lblSelected.AutoSize = true; 217 | this.lblSelected.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(177))); 218 | this.lblSelected.Location = new System.Drawing.Point(460, 36); 219 | this.lblSelected.Name = "lblSelected"; 220 | this.lblSelected.Size = new System.Drawing.Size(113, 15); 221 | this.lblSelected.TabIndex = 10; 222 | this.lblSelected.Text = "0 Blobs selected"; 223 | // 224 | // label3 225 | // 226 | this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 227 | this.label3.AutoSize = true; 228 | this.label3.Location = new System.Drawing.Point(861, 135); 229 | this.label3.Name = "label3"; 230 | this.label3.Size = new System.Drawing.Size(124, 13); 231 | this.label3.TabIndex = 14; 232 | this.label3.Text = "Height Merge Sensitivity:"; 233 | this.toolTip1.SetToolTip(this.label3, resources.GetString("label3.ToolTip")); 234 | // 235 | // txtHeightMergeSense 236 | // 237 | this.txtHeightMergeSense.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 238 | this.txtHeightMergeSense.Increment = new decimal(new int[] { 239 | 5, 240 | 0, 241 | 0, 242 | 0}); 243 | this.txtHeightMergeSense.Location = new System.Drawing.Point(988, 133); 244 | this.txtHeightMergeSense.Maximum = new decimal(new int[] { 245 | 9999, 246 | 0, 247 | 0, 248 | 0}); 249 | this.txtHeightMergeSense.Name = "txtHeightMergeSense"; 250 | this.txtHeightMergeSense.Size = new System.Drawing.Size(54, 20); 251 | this.txtHeightMergeSense.TabIndex = 13; 252 | this.txtHeightMergeSense.Value = new decimal(new int[] { 253 | 10, 254 | 0, 255 | 0, 256 | 0}); 257 | // 258 | // label4 259 | // 260 | this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 261 | this.label4.AutoSize = true; 262 | this.label4.Location = new System.Drawing.Point(861, 163); 263 | this.label4.Name = "label4"; 264 | this.label4.Size = new System.Drawing.Size(121, 13); 265 | this.label4.TabIndex = 12; 266 | this.label4.Text = "Width Merge Sensitivity:"; 267 | this.toolTip1.SetToolTip(this.label4, "See tooltip for \"Height Merge Sensitivity\""); 268 | // 269 | // txtWidthMergeSense 270 | // 271 | this.txtWidthMergeSense.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 272 | this.txtWidthMergeSense.Increment = new decimal(new int[] { 273 | 5, 274 | 0, 275 | 0, 276 | 0}); 277 | this.txtWidthMergeSense.Location = new System.Drawing.Point(988, 161); 278 | this.txtWidthMergeSense.Maximum = new decimal(new int[] { 279 | 9999, 280 | 0, 281 | 0, 282 | 0}); 283 | this.txtWidthMergeSense.Name = "txtWidthMergeSense"; 284 | this.txtWidthMergeSense.Size = new System.Drawing.Size(54, 20); 285 | this.txtWidthMergeSense.TabIndex = 11; 286 | this.txtWidthMergeSense.Value = new decimal(new int[] { 287 | 10, 288 | 0, 289 | 0, 290 | 0}); 291 | // 292 | // label5 293 | // 294 | this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 295 | this.label5.AutoSize = true; 296 | this.label5.Location = new System.Drawing.Point(861, 107); 297 | this.label5.Name = "label5"; 298 | this.label5.Size = new System.Drawing.Size(114, 13); 299 | this.label5.TabIndex = 16; 300 | this.label5.Text = "Binarization Thershold:"; 301 | this.toolTip1.SetToolTip(this.label5, "The pixel intensity (between 0-255) that separates\r\nbetween the black and white i" + 302 | "n the binarization process."); 303 | // 304 | // txtBinThershold 305 | // 306 | this.txtBinThershold.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 307 | this.txtBinThershold.Increment = new decimal(new int[] { 308 | 5, 309 | 0, 310 | 0, 311 | 0}); 312 | this.txtBinThershold.Location = new System.Drawing.Point(988, 105); 313 | this.txtBinThershold.Maximum = new decimal(new int[] { 314 | 9999, 315 | 0, 316 | 0, 317 | 0}); 318 | this.txtBinThershold.Name = "txtBinThershold"; 319 | this.txtBinThershold.Size = new System.Drawing.Size(54, 20); 320 | this.txtBinThershold.TabIndex = 15; 321 | this.txtBinThershold.Value = new decimal(new int[] { 322 | 200, 323 | 0, 324 | 0, 325 | 0}); 326 | // 327 | // chkShowBinarize 328 | // 329 | this.chkShowBinarize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 330 | this.chkShowBinarize.AutoSize = true; 331 | this.chkShowBinarize.Location = new System.Drawing.Point(864, 60); 332 | this.chkShowBinarize.Name = "chkShowBinarize"; 333 | this.chkShowBinarize.Size = new System.Drawing.Size(131, 17); 334 | this.chkShowBinarize.TabIndex = 17; 335 | this.chkShowBinarize.Text = "Show Binarized Image"; 336 | this.toolTip1.SetToolTip(this.chkShowBinarize, "The blob recognition is running on a binarized \r\nimage (B&W), check this to see t" + 337 | "he binarized image."); 338 | this.chkShowBinarize.UseVisualStyleBackColor = true; 339 | this.chkShowBinarize.CheckedChanged += new System.EventHandler(this.chkShowBinarize_CheckedChanged); 340 | // 341 | // groupBox1 342 | // 343 | this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 344 | this.groupBox1.Controls.Add(this.label6); 345 | this.groupBox1.Controls.Add(this.txtResizeInterval); 346 | this.groupBox1.Controls.Add(this.btnResRight); 347 | this.groupBox1.Controls.Add(this.btnResLeft); 348 | this.groupBox1.Controls.Add(this.btnResDown); 349 | this.groupBox1.Controls.Add(this.btnResUp); 350 | this.groupBox1.Location = new System.Drawing.Point(864, 283); 351 | this.groupBox1.Name = "groupBox1"; 352 | this.groupBox1.Size = new System.Drawing.Size(150, 114); 353 | this.groupBox1.TabIndex = 18; 354 | this.groupBox1.TabStop = false; 355 | this.groupBox1.Text = "Move Selected Blobs"; 356 | this.toolTip1.SetToolTip(this.groupBox1, "Move the selected blobs.\r\nIn order to change the size of the blob hover the\r\nblob" + 357 | " edge and drag."); 358 | // 359 | // label6 360 | // 361 | this.label6.AutoSize = true; 362 | this.label6.Location = new System.Drawing.Point(6, 21); 363 | this.label6.Name = "label6"; 364 | this.label6.Size = new System.Drawing.Size(45, 13); 365 | this.label6.TabIndex = 5; 366 | this.label6.Text = "Interval:"; 367 | // 368 | // txtResizeInterval 369 | // 370 | this.txtResizeInterval.Location = new System.Drawing.Point(57, 19); 371 | this.txtResizeInterval.Name = "txtResizeInterval"; 372 | this.txtResizeInterval.Size = new System.Drawing.Size(37, 20); 373 | this.txtResizeInterval.TabIndex = 4; 374 | this.txtResizeInterval.Value = new decimal(new int[] { 375 | 2, 376 | 0, 377 | 0, 378 | 0}); 379 | // 380 | // btnResRight 381 | // 382 | this.btnResRight.Location = new System.Drawing.Point(92, 65); 383 | this.btnResRight.Name = "btnResRight"; 384 | this.btnResRight.Size = new System.Drawing.Size(31, 23); 385 | this.btnResRight.TabIndex = 3; 386 | this.btnResRight.Text = ">"; 387 | this.btnResRight.UseVisualStyleBackColor = true; 388 | this.btnResRight.Click += new System.EventHandler(this.btnMoveRight_Click); 389 | // 390 | // btnResLeft 391 | // 392 | this.btnResLeft.Location = new System.Drawing.Point(34, 65); 393 | this.btnResLeft.Name = "btnResLeft"; 394 | this.btnResLeft.Size = new System.Drawing.Size(31, 23); 395 | this.btnResLeft.TabIndex = 2; 396 | this.btnResLeft.Text = "<"; 397 | this.btnResLeft.UseVisualStyleBackColor = true; 398 | this.btnResLeft.Click += new System.EventHandler(this.btnMoveLeft_Click); 399 | // 400 | // btnResDown 401 | // 402 | this.btnResDown.Location = new System.Drawing.Point(63, 84); 403 | this.btnResDown.Name = "btnResDown"; 404 | this.btnResDown.Size = new System.Drawing.Size(31, 23); 405 | this.btnResDown.TabIndex = 1; 406 | this.btnResDown.Text = "v"; 407 | this.btnResDown.UseVisualStyleBackColor = true; 408 | this.btnResDown.Click += new System.EventHandler(this.btnMoveDown_Click); 409 | // 410 | // btnResUp 411 | // 412 | this.btnResUp.Location = new System.Drawing.Point(63, 45); 413 | this.btnResUp.Name = "btnResUp"; 414 | this.btnResUp.Size = new System.Drawing.Size(31, 23); 415 | this.btnResUp.TabIndex = 0; 416 | this.btnResUp.Text = "^"; 417 | this.btnResUp.UseVisualStyleBackColor = true; 418 | this.btnResUp.Click += new System.EventHandler(this.btnMoveUp_Click); 419 | // 420 | // chkShowRows 421 | // 422 | this.chkShowRows.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 423 | this.chkShowRows.AutoSize = true; 424 | this.chkShowRows.Checked = true; 425 | this.chkShowRows.CheckState = System.Windows.Forms.CheckState.Checked; 426 | this.chkShowRows.Location = new System.Drawing.Point(864, 83); 427 | this.chkShowRows.Name = "chkShowRows"; 428 | this.chkShowRows.Size = new System.Drawing.Size(83, 17); 429 | this.chkShowRows.TabIndex = 20; 430 | this.chkShowRows.Text = "Show Rows"; 431 | this.toolTip1.SetToolTip(this.chkShowRows, "The tool tries to automatically group the letters\r\ninto rows, which will be expor" + 432 | "ted together.\r\nIf you don\'t want to see those rows uncheck this checkbox."); 433 | this.chkShowRows.UseVisualStyleBackColor = true; 434 | this.chkShowRows.CheckedChanged += new System.EventHandler(this.chkShowRows_CheckedChanged); 435 | // 436 | // btnExport 437 | // 438 | this.btnExport.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 439 | this.btnExport.Location = new System.Drawing.Point(8, 75); 440 | this.btnExport.Name = "btnExport"; 441 | this.btnExport.Size = new System.Drawing.Size(111, 23); 442 | this.btnExport.TabIndex = 22; 443 | this.btnExport.Text = "Export Blobs"; 444 | this.toolTip1.SetToolTip(this.btnExport, resources.GetString("btnExport.ToolTip")); 445 | this.btnExport.UseVisualStyleBackColor = true; 446 | this.btnExport.Click += new System.EventHandler(this.btnExport_Click); 447 | // 448 | // label7 449 | // 450 | this.label7.AutoSize = true; 451 | this.label7.Location = new System.Drawing.Point(5, 10); 452 | this.label7.Name = "label7"; 453 | this.label7.Size = new System.Drawing.Size(66, 13); 454 | this.label7.TabIndex = 23; 455 | this.label7.Text = "Input Image:"; 456 | // 457 | // label8 458 | // 459 | this.label8.AutoSize = true; 460 | this.label8.Location = new System.Drawing.Point(6, 50); 461 | this.label8.Name = "label8"; 462 | this.label8.Size = new System.Drawing.Size(42, 13); 463 | this.label8.TabIndex = 25; 464 | this.label8.Text = "Output:"; 465 | // 466 | // txtOutput 467 | // 468 | this.txtOutput.Location = new System.Drawing.Point(45, 47); 469 | this.txtOutput.Name = "txtOutput"; 470 | this.txtOutput.Size = new System.Drawing.Size(156, 20); 471 | this.txtOutput.TabIndex = 24; 472 | // 473 | // btnPredict 474 | // 475 | this.btnPredict.Location = new System.Drawing.Point(318, 36); 476 | this.btnPredict.Name = "btnPredict"; 477 | this.btnPredict.Size = new System.Drawing.Size(75, 23); 478 | this.btnPredict.TabIndex = 27; 479 | this.btnPredict.Text = "Load Model"; 480 | this.toolTip1.SetToolTip(this.btnPredict, "Loads model parameters and runs the model\r\non the current image trying to identif" + 481 | "y the lettes."); 482 | this.btnPredict.UseVisualStyleBackColor = true; 483 | this.btnPredict.Click += new System.EventHandler(this.btnPredict_Click); 484 | // 485 | // txtModelParams 486 | // 487 | this.txtModelParams.Location = new System.Drawing.Point(83, 36); 488 | this.txtModelParams.Name = "txtModelParams"; 489 | this.txtModelParams.Size = new System.Drawing.Size(193, 20); 490 | this.txtModelParams.TabIndex = 28; 491 | // 492 | // label9 493 | // 494 | this.label9.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 495 | this.label9.AutoSize = true; 496 | this.label9.Location = new System.Drawing.Point(861, 243); 497 | this.label9.Name = "label9"; 498 | this.label9.Size = new System.Drawing.Size(110, 13); 499 | this.label9.TabIndex = 29; 500 | this.label9.Text = "Extracted Back Color:"; 501 | this.toolTip1.SetToolTip(this.label9, resources.GetString("label9.ToolTip")); 502 | // 503 | // txtExtractedBackColor 504 | // 505 | this.txtExtractedBackColor.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 506 | this.txtExtractedBackColor.Increment = new decimal(new int[] { 507 | 5, 508 | 0, 509 | 0, 510 | 0}); 511 | this.txtExtractedBackColor.Location = new System.Drawing.Point(988, 241); 512 | this.txtExtractedBackColor.Maximum = new decimal(new int[] { 513 | 9999, 514 | 0, 515 | 0, 516 | 0}); 517 | this.txtExtractedBackColor.Name = "txtExtractedBackColor"; 518 | this.txtExtractedBackColor.Size = new System.Drawing.Size(54, 20); 519 | this.txtExtractedBackColor.TabIndex = 30; 520 | // 521 | // label10 522 | // 523 | this.label10.AutoSize = true; 524 | this.label10.Location = new System.Drawing.Point(5, 38); 525 | this.label10.Name = "label10"; 526 | this.label10.Size = new System.Drawing.Size(77, 13); 527 | this.label10.TabIndex = 31; 528 | this.label10.Text = "Model Params:"; 529 | // 530 | // btnOpenModelFile 531 | // 532 | this.btnOpenModelFile.Location = new System.Drawing.Point(282, 34); 533 | this.btnOpenModelFile.Name = "btnOpenModelFile"; 534 | this.btnOpenModelFile.Size = new System.Drawing.Size(30, 23); 535 | this.btnOpenModelFile.TabIndex = 32; 536 | this.btnOpenModelFile.Text = "..."; 537 | this.btnOpenModelFile.UseVisualStyleBackColor = true; 538 | this.btnOpenModelFile.Click += new System.EventHandler(this.btnOpenModelFile_Click); 539 | // 540 | // toolTip1 541 | // 542 | this.toolTip1.AutoPopDelay = 20000; 543 | this.toolTip1.InitialDelay = 500; 544 | this.toolTip1.ReshowDelay = 100; 545 | // 546 | // label12 547 | // 548 | this.label12.AutoSize = true; 549 | this.label12.Location = new System.Drawing.Point(6, 24); 550 | this.label12.Name = "label12"; 551 | this.label12.Size = new System.Drawing.Size(96, 13); 552 | this.label12.TabIndex = 35; 553 | this.label12.Text = "Export Size (W/H):"; 554 | this.toolTip1.SetToolTip(this.label12, "The exported image size (the exported image is\r\nalways a square, so this is the w" + 555 | "idth & height)."); 556 | // 557 | // label11 558 | // 559 | this.label11.AutoSize = true; 560 | this.label11.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(177))); 561 | this.label11.Location = new System.Drawing.Point(863, 34); 562 | this.label11.Name = "label11"; 563 | this.label11.Size = new System.Drawing.Size(154, 13); 564 | this.label11.TabIndex = 34; 565 | this.label11.Text = "Hover controls for tooltips"; 566 | // 567 | // txtExportSize 568 | // 569 | this.txtExportSize.Increment = new decimal(new int[] { 570 | 5, 571 | 0, 572 | 0, 573 | 0}); 574 | this.txtExportSize.Location = new System.Drawing.Point(108, 22); 575 | this.txtExportSize.Maximum = new decimal(new int[] { 576 | 9999, 577 | 0, 578 | 0, 579 | 0}); 580 | this.txtExportSize.Name = "txtExportSize"; 581 | this.txtExportSize.Size = new System.Drawing.Size(54, 20); 582 | this.txtExportSize.TabIndex = 36; 583 | this.txtExportSize.Value = new decimal(new int[] { 584 | 20, 585 | 0, 586 | 0, 587 | 0}); 588 | // 589 | // groupBox2 590 | // 591 | this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 592 | this.groupBox2.Controls.Add(this.label12); 593 | this.groupBox2.Controls.Add(this.btnExport); 594 | this.groupBox2.Controls.Add(this.txtExportSize); 595 | this.groupBox2.Controls.Add(this.txtOutput); 596 | this.groupBox2.Controls.Add(this.label8); 597 | this.groupBox2.Location = new System.Drawing.Point(864, 414); 598 | this.groupBox2.Name = "groupBox2"; 599 | this.groupBox2.Size = new System.Drawing.Size(207, 117); 600 | this.groupBox2.TabIndex = 37; 601 | this.groupBox2.TabStop = false; 602 | this.groupBox2.Text = "Export"; 603 | // 604 | // OCRTool 605 | // 606 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 607 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 608 | this.ClientSize = new System.Drawing.Size(1083, 738); 609 | this.Controls.Add(this.groupBox2); 610 | this.Controls.Add(this.label11); 611 | this.Controls.Add(this.btnOpenModelFile); 612 | this.Controls.Add(this.label10); 613 | this.Controls.Add(this.txtExtractedBackColor); 614 | this.Controls.Add(this.label9); 615 | this.Controls.Add(this.txtModelParams); 616 | this.Controls.Add(this.btnPredict); 617 | this.Controls.Add(this.label7); 618 | this.Controls.Add(this.chkShowRows); 619 | this.Controls.Add(this.groupBox1); 620 | this.Controls.Add(this.chkShowBinarize); 621 | this.Controls.Add(this.label5); 622 | this.Controls.Add(this.txtBinThershold); 623 | this.Controls.Add(this.label3); 624 | this.Controls.Add(this.txtHeightMergeSense); 625 | this.Controls.Add(this.label4); 626 | this.Controls.Add(this.txtWidthMergeSense); 627 | this.Controls.Add(this.lblSelected); 628 | this.Controls.Add(this.label2); 629 | this.Controls.Add(this.txtPreMergeFilter); 630 | this.Controls.Add(this.label1); 631 | this.Controls.Add(this.txtPostMergeFilter); 632 | this.Controls.Add(this.button1); 633 | this.Controls.Add(this.panel1); 634 | this.Controls.Add(this.txtFile); 635 | this.Controls.Add(this.btnOpenFile); 636 | this.Name = "OCRTool"; 637 | this.Text = "OCR Helper Tool"; 638 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 639 | this.panel1.ResumeLayout(false); 640 | this.panel1.PerformLayout(); 641 | ((System.ComponentModel.ISupportInitialize)(this.txtPostMergeFilter)).EndInit(); 642 | ((System.ComponentModel.ISupportInitialize)(this.txtPreMergeFilter)).EndInit(); 643 | ((System.ComponentModel.ISupportInitialize)(this.txtHeightMergeSense)).EndInit(); 644 | ((System.ComponentModel.ISupportInitialize)(this.txtWidthMergeSense)).EndInit(); 645 | ((System.ComponentModel.ISupportInitialize)(this.txtBinThershold)).EndInit(); 646 | this.groupBox1.ResumeLayout(false); 647 | this.groupBox1.PerformLayout(); 648 | ((System.ComponentModel.ISupportInitialize)(this.txtResizeInterval)).EndInit(); 649 | ((System.ComponentModel.ISupportInitialize)(this.txtExtractedBackColor)).EndInit(); 650 | ((System.ComponentModel.ISupportInitialize)(this.txtExportSize)).EndInit(); 651 | this.groupBox2.ResumeLayout(false); 652 | this.groupBox2.PerformLayout(); 653 | this.ResumeLayout(false); 654 | this.PerformLayout(); 655 | 656 | } 657 | 658 | #endregion 659 | 660 | private System.Windows.Forms.OpenFileDialog openFileDialog1; 661 | private System.Windows.Forms.Button btnOpenFile; 662 | private System.Windows.Forms.TextBox txtFile; 663 | private System.Windows.Forms.PictureBox pictureBox1; 664 | private System.Windows.Forms.Panel panel1; 665 | private System.Windows.Forms.Button button1; 666 | private System.Windows.Forms.NumericUpDown txtPostMergeFilter; 667 | private System.Windows.Forms.Label label1; 668 | private System.Windows.Forms.Label label2; 669 | private System.Windows.Forms.NumericUpDown txtPreMergeFilter; 670 | private System.Windows.Forms.Label lblSelected; 671 | private System.Windows.Forms.Label label3; 672 | private System.Windows.Forms.NumericUpDown txtHeightMergeSense; 673 | private System.Windows.Forms.Label label4; 674 | private System.Windows.Forms.NumericUpDown txtWidthMergeSense; 675 | private System.Windows.Forms.Label label5; 676 | private System.Windows.Forms.NumericUpDown txtBinThershold; 677 | private System.Windows.Forms.CheckBox chkShowBinarize; 678 | private System.Windows.Forms.GroupBox groupBox1; 679 | private System.Windows.Forms.Button btnResRight; 680 | private System.Windows.Forms.Button btnResLeft; 681 | private System.Windows.Forms.Button btnResDown; 682 | private System.Windows.Forms.Button btnResUp; 683 | private System.Windows.Forms.NumericUpDown txtResizeInterval; 684 | private System.Windows.Forms.Label label6; 685 | private System.Windows.Forms.CheckBox chkShowRows; 686 | private System.Windows.Forms.Button btnExport; 687 | private System.Windows.Forms.Label label7; 688 | private System.Windows.Forms.Label label8; 689 | private System.Windows.Forms.TextBox txtOutput; 690 | private System.Windows.Forms.Button btnPredict; 691 | private System.Windows.Forms.TextBox txtModelParams; 692 | private System.Windows.Forms.Label label9; 693 | private System.Windows.Forms.NumericUpDown txtExtractedBackColor; 694 | private System.Windows.Forms.Label label10; 695 | private System.Windows.Forms.Button btnOpenModelFile; 696 | private System.Windows.Forms.ToolTip toolTip1; 697 | private System.Windows.Forms.Label label11; 698 | private System.Windows.Forms.NumericUpDown txtExportSize; 699 | private System.Windows.Forms.Label label12; 700 | private System.Windows.Forms.GroupBox groupBox2; 701 | } 702 | } -------------------------------------------------------------------------------- /MachineLearningOCRTool/Views/OCRTool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Drawing.Imaging; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Windows.Forms; 8 | using AForge.Imaging; 9 | using AForge.Imaging.Filters; 10 | using MachineLearningOCRTool.Controls; 11 | using MathNet.Numerics; 12 | using MathNet.Numerics.LinearAlgebra.Complex; 13 | 14 | namespace MachineLearningOCRTool.Views 15 | { 16 | public partial class OCRTool : Form 17 | { 18 | #region Members 19 | 20 | // This list holds the selected blobs 21 | private List m_selectedBlobs; 22 | 23 | private Bitmap m_original; 24 | private Bitmap m_binarized; 25 | 26 | #endregion 27 | 28 | public OCRTool() 29 | { 30 | InitializeComponent(); 31 | m_selectedBlobs = new List(); 32 | 33 | // Use double-buffering for flicker-free updating: 34 | SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw, true); 35 | SetStyle(ControlStyles.SupportsTransparentBackColor, true); 36 | Common.SetDoubleBuffered(pictureBox1); 37 | 38 | if(!string.IsNullOrEmpty(Properties.Settings.Default.InputImage)) 39 | { 40 | txtFile.Text = Properties.Settings.Default.InputImage; 41 | } 42 | 43 | if (!string.IsNullOrEmpty(Properties.Settings.Default.ModelParams)) 44 | { 45 | txtModelParams.Text = Properties.Settings.Default.ModelParams; 46 | } 47 | 48 | if (!string.IsNullOrEmpty(Properties.Settings.Default.OutputFile)) 49 | { 50 | txtOutput.Text = Properties.Settings.Default.OutputFile; 51 | } 52 | 53 | } 54 | 55 | #region Methods 56 | 57 | private void ProcessImage() 58 | { 59 | m_selectedBlobs.Clear(); 60 | pictureBox1.Controls.Clear(); 61 | pictureBox1.Image = null; 62 | 63 | if (m_original != null) 64 | m_original.Dispose(); 65 | if (m_binarized != null) 66 | m_binarized.Dispose(); 67 | 68 | m_original = new Bitmap(txtFile.Text); 69 | 70 | // create grayscale filter (BT709) 71 | Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721); 72 | m_binarized = filter.Apply(m_original); 73 | 74 | // Binarize Picture. 75 | Threshold bin = new Threshold((int)txtBinThershold.Value); 76 | bin.ApplyInPlace(m_binarized); 77 | 78 | // create filter 79 | Invert inv = new Invert(); 80 | inv.ApplyInPlace(m_binarized); 81 | 82 | // create an instance of blob counter algorithm 83 | BlobCounter bc = new BlobCounter(); 84 | bc.ObjectsOrder = ObjectsOrder.XY; 85 | bc.ProcessImage(m_binarized); 86 | Rectangle[] blobsRect = bc.GetObjectsRectangles(); 87 | Dictionary> orderedBlobs = ReorderBlobs(blobsRect); 88 | 89 | foreach (KeyValuePair> orderedBlob in orderedBlobs) 90 | { 91 | orderedBlob.Value.ForEach(r => AddBlobPanel(orderedBlob.Key, r)); 92 | } 93 | 94 | pictureBox1.Image = chkShowBinarize.Checked ? m_binarized : m_original; 95 | 96 | pictureBox1.Invalidate(); 97 | } 98 | 99 | /// 100 | /// This method tries to order the blobs in rows. 101 | /// 102 | private Dictionary> ReorderBlobs(Rectangle[] blobs) 103 | { 104 | Dictionary> result = new Dictionary>(); 105 | if (blobs.Length < 1) 106 | return result; 107 | 108 | // Merge intersecting blobs (we filter some very small blobs first). 109 | List mergedBlobs = 110 | MergeIntersectingBlobs(blobs.Where(r => r.Width * r.Height >= txtPreMergeFilter.Value).ToArray()); 111 | 112 | // Filter for blobs that are larger than 50 "sq pixels" and order by Y. 113 | mergedBlobs = 114 | new List( 115 | mergedBlobs.Where(r => r.Height * r.Width >= txtPostMergeFilter.Value).OrderBy(r => r.Y)); 116 | 117 | // Add the first row and blob. 118 | int currRowInd = 0; 119 | result.Add(currRowInd, new List()); 120 | result[currRowInd].Add(mergedBlobs[0]); 121 | 122 | // Now we loop thru all the blobs and try to guess where a new line begins. 123 | for (int i = 1; i < mergedBlobs.Count; i++) 124 | { 125 | // Since the blobs are ordered by Y, we consider a NEW line if the current blob's Y 126 | // is BELOW the previous blob lower quarter. 127 | // The assumption is that blobs on the same row will have more-or-less same Y, so if 128 | // the Y is below the previous blob lower quarter it's probably a new line. 129 | if (mergedBlobs[i].Y > mergedBlobs[i - 1].Y + 0.75 * mergedBlobs[i - 1].Height) 130 | { 131 | // Add a new row to the dictionary 132 | ++currRowInd; 133 | result.Add(currRowInd, new List()); 134 | } 135 | 136 | // Add blob to the current row. 137 | result[currRowInd].Add(mergedBlobs[i]); 138 | } 139 | 140 | return result; 141 | } 142 | 143 | /// 144 | /// This method looks for blobs that intersect and join them into one blob. 145 | /// 146 | private List MergeIntersectingBlobs(Rectangle[] blobs) 147 | { 148 | // Loop thru all blobs. 149 | int i = 0; 150 | while (i < blobs.Length) 151 | { 152 | // Ignore empty blobs. 153 | if (blobs[i].IsEmpty) 154 | { 155 | ++i; 156 | continue; 157 | } 158 | 159 | // When we check for intersection we want to inflate the current blob, this is 160 | // for special cases where there are very close blobs that do not intersect and we DO want 161 | // them to intersect, for example the letters "i" or j" where the dot above the letter is a 162 | // different not intersecting blob, so by inflating the current blon we would hopefully 163 | // make them intersect. 164 | Rectangle tmp = blobs[i]; 165 | tmp.Inflate((int)txtWidthMergeSense.Value, (int)txtHeightMergeSense.Value); 166 | 167 | // Go check the following blobs (it is order by X) and see if they are intersecting with 168 | // the current i'th blob. 169 | bool merged = false; 170 | for (int j = i + 1; j < blobs.Length; ++j) 171 | { 172 | // Ignore empty blobs. 173 | if (blobs[j].IsEmpty) 174 | { 175 | continue; 176 | } 177 | 178 | // If the j'th blob X is beyond the i'th blob area it means there are no more 179 | // potential blobs that will intersect with the i'th blob, hence we can stop (because blobs are sorted on X). 180 | if (blobs[j].X > tmp.X + tmp.Width) 181 | break; 182 | 183 | // Check if there is intersection. 184 | if (tmp.IntersectsWith(blobs[j])) 185 | { 186 | // Replace the i'th blob with the union with j 187 | // (Note we are using the i'th blob and not the inflated blob (tmp)). 188 | blobs[i] = Rectangle.Union(blobs[i], blobs[j]); 189 | 190 | // Set j'th blob to be empty so we will ignore it from now on. 191 | blobs[j] = new Rectangle(); 192 | 193 | // Stop the current loop. 194 | merged = true; 195 | break; 196 | } 197 | } 198 | 199 | // If we had a merge we don't move to the next Blob as the newly created 200 | // joined blob has to be checked for another newly potential intersections. 201 | if (!merged) 202 | ++i; 203 | } 204 | 205 | // Create the result list with only non-empty rectangles. 206 | List result = new List(blobs.Where(r => !r.IsEmpty)); 207 | return result; 208 | } 209 | 210 | private void AddBlobPanel(int row, Rectangle rectangle) 211 | { 212 | BlobPanel blobPanel = new BlobPanel(); 213 | blobPanel.RowIndex = row; 214 | //blobPanel.Location = new Point(rectangle.X - 2, rectangle.Y - 2); 215 | //blobPanel.Size = new Size(rectangle.Width + 4, rectangle.Height + 4); 216 | rectangle.Inflate(3,3); 217 | blobPanel.Location = new Point(rectangle.X, rectangle.Y); 218 | blobPanel.Size = new Size(rectangle.Width, rectangle.Height); 219 | blobPanel.SelectedChanged += blobPanel_SelectedChanged; 220 | blobPanel.DeleteRequest += blobPanel_DeleteRequest; 221 | 222 | pictureBox1.Controls.Add(blobPanel); 223 | } 224 | 225 | private void UpdateSelectedCount() 226 | { 227 | int count = pictureBox1.Controls.OfType().Count(panel => panel.Selected); 228 | lblSelected.Text = string.Format("{0} Blobs selected", count); 229 | lblSelected.ForeColor = count > 0 ? Color.Red : Color.Black; 230 | } 231 | 232 | private void MoveSelectedBlobs(int dx, int dy) 233 | { 234 | foreach (BlobPanel panel in m_selectedBlobs) 235 | { 236 | panel.Location = new Point(panel.Location.X + dx, panel.Location.Y + dy); 237 | panel.Invalidate(); 238 | } 239 | } 240 | 241 | private void ExportBlobs() 242 | { 243 | if (string.IsNullOrEmpty(txtOutput.Text)) 244 | { 245 | MessageBox.Show("Please enter an output file name."); 246 | return; 247 | } 248 | 249 | if (txtExtractedBackColor.Value == 0) 250 | { 251 | DialogResult dr = MessageBox.Show("Extraction back color is black, do you want to continue with that?", "Extract Back Color", MessageBoxButtons.YesNo); 252 | if (dr == DialogResult.No) 253 | return; 254 | } 255 | 256 | // Check that we have any blobs. 257 | if (!pictureBox1.Controls.OfType().Any()) 258 | { 259 | MessageBox.Show("There are no blobs to export."); 260 | return; 261 | } 262 | 263 | Cursor = Cursors.WaitCursor; 264 | if (File.Exists(txtOutput.Text)) 265 | { 266 | DialogResult dr = MessageBox.Show("There is already file with the same name, overwrite?", "Save", MessageBoxButtons.OKCancel); 267 | if (dr == DialogResult.Cancel) 268 | { 269 | Cursor = Cursors.Default; 270 | return; 271 | } 272 | } 273 | 274 | // Save the output file name. 275 | Properties.Settings.Default.OutputFile = txtOutput.Text; 276 | Properties.Settings.Default.Save(); 277 | 278 | using (StreamWriter sw = new StreamWriter(txtOutput.Text)) 279 | { 280 | // Group by RowIndex and select the group Left, Right, Top, Bottom 281 | var rows = pictureBox1.Controls.OfType().GroupBy(bp => bp.RowIndex); 282 | 283 | foreach (IGrouping row in rows) 284 | { 285 | row.ForEach(bp => ExportBlob(sw, row.Key+1, bp)); 286 | } 287 | 288 | sw.Flush(); 289 | sw.Close(); 290 | } 291 | 292 | Cursor = Cursors.Default; 293 | MessageBox.Show("Finished."); 294 | } 295 | 296 | /// 297 | /// Crop the blob from the image 298 | /// 299 | private Bitmap CropBlob(BlobPanel blob, System.Drawing.Image source, int rotationAngel = 0) 300 | { 301 | // Create the target image, this is a squared image. 302 | int size = Math.Max(blob.Height, blob.Width); 303 | Bitmap newImage = new Bitmap(size, size, PixelFormat.Format24bppRgb); 304 | 305 | // Get the graphics object of the image. 306 | Graphics g = Graphics.FromImage(newImage); 307 | 308 | // Create the background color to use (the image we create is larger than the blob (as we squared it) 309 | // so this would be the color of the excess areas. 310 | Color bColor = Color.FromArgb((int)txtExtractedBackColor.Value, (int)txtExtractedBackColor.Value, (int)txtExtractedBackColor.Value); 311 | 312 | // Fill back color. 313 | g.FillRectangle(new SolidBrush(bColor), 0, 0, size, size); 314 | 315 | // Now we clip the blob from the PictureBox image. 316 | g.DrawImage(source, new Rectangle(0, 0, blob.Width, blob.Height), blob.Left, blob.Top, blob.Width, blob.Height, GraphicsUnit.Pixel); 317 | g.Dispose(); 318 | 319 | if (rotationAngel != 0) 320 | { 321 | RotateBilinear filter = new RotateBilinear(rotationAngel, true); 322 | filter.FillColor = bColor; 323 | // apply the filter 324 | newImage = filter.Apply(newImage); 325 | } 326 | 327 | // Resize the image. 328 | ResizeBilinear resizefilter = new ResizeBilinear((int)txtExportSize.Value, (int)txtExportSize.Value); 329 | newImage = resizefilter.Apply(newImage); 330 | 331 | return newImage; 332 | } 333 | 334 | /// 335 | /// Write the blob image to a text file. 336 | /// 337 | private void ExportBlob(StreamWriter sw, int key, BlobPanel blob) 338 | { 339 | // Get the blob image. 340 | Bitmap newImage = CropBlob(blob, pictureBox1.Image); 341 | WriteImageToFile(sw, key, newImage); 342 | 343 | // Write a rotated version. 344 | newImage = CropBlob(blob, pictureBox1.Image, 10); 345 | WriteImageToFile(sw, key, newImage); 346 | 347 | // Write another rotated version (to the other dir). 348 | newImage = CropBlob(blob, pictureBox1.Image, -10); 349 | WriteImageToFile(sw, key, newImage); 350 | } 351 | 352 | private void WriteImageToFile(StreamWriter sw, int key, Bitmap newImage) 353 | { 354 | // Loop thru all pixels and write them. 355 | for (int i = 0; i < newImage.Height; i++) 356 | { 357 | for (int j = 0; j < newImage.Width; j++) 358 | { 359 | Color pixel = newImage.GetPixel(i, j); 360 | sw.Write(Common.GetColorAverage(pixel) + ","); 361 | } 362 | } 363 | 364 | sw.WriteLine(key); 365 | } 366 | 367 | /// 368 | /// Load the model from the file and predict. 369 | /// 370 | private void LoadModelAndPredict() 371 | { 372 | if (!File.Exists(txtModelParams.Text)) 373 | { 374 | MessageBox.Show("Model file not found."); 375 | return; 376 | } 377 | 378 | // Check if the user forgot to choose the back color. 379 | if (txtExtractedBackColor.Value == 0) 380 | { 381 | DialogResult dr = MessageBox.Show("Extraction back color is black, do you want to continue with prediction?", "Back Color", MessageBoxButtons.YesNo); 382 | if (dr == DialogResult.No) 383 | return; 384 | } 385 | 386 | // Get the model params. 387 | Matrix thetas = GetModelParamsFromFile(); 388 | 389 | // Loop thru all blobs and predict. 390 | foreach (BlobPanel blob in pictureBox1.Controls.OfType()) 391 | { 392 | // Reset the blob's description. 393 | blob.Description = string.Empty; 394 | 395 | // Get the blob pixels. 396 | Vector xs = GetBlobPixels(blob); 397 | 398 | // Get the model value (this is what to be used in the Sigmoid function). 399 | var v = (thetas * xs); 400 | 401 | // This is for finding the maximum value of all letters predictions (1-vs-all), so 402 | // we know what letter to choose. 403 | double[] max = new double[3]; 404 | int[] maxIndex = {-1, -1, -1}; 405 | 406 | // Loop thru the values 407 | for (int i = 0; i < v.Count; i++) 408 | { 409 | // Get the final model prediction (Sigmoid). 410 | v[i] = SpecialFunctions.Logistic(v[i].Real); 411 | 412 | // Check if this prediction is in the "top 3". 413 | for (int j = 0; j < max.Length; j++) 414 | { 415 | if (v[i].Real > max[j]) 416 | { 417 | max[j] = v[i].Real; 418 | maxIndex[j] = i; 419 | 420 | // We want to kepp max array sorted, so once we found a value 421 | // it is bigger than we stop. 422 | break; 423 | } 424 | } 425 | } 426 | 427 | // Put the "top 3" in the description. 428 | blob.Description += Common.Letters[maxIndex[0]] + " - " + max[0].ToString() + "\n"; 429 | blob.Description += Common.Letters[maxIndex[1]] + " - " + max[1].ToString() + "\n"; 430 | blob.Description += Common.Letters[maxIndex[2]] + " - " + max[2].ToString() + "\n"; 431 | 432 | // Save the selected letter in the blob. 433 | blob.Title = Common.Letters[maxIndex[0]]; 434 | } 435 | 436 | pictureBox1.Invalidate(); 437 | } 438 | 439 | private Vector GetBlobPixels(BlobPanel blob) 440 | { 441 | // Get the blob image. 442 | Bitmap newImage = CropBlob(blob, pictureBox1.Image); 443 | 444 | // Create the vector (Add the bias term). 445 | Vector xs = new DenseVector(newImage.Width * newImage.Height + 1); 446 | xs[0] = 1; 447 | 448 | // Loop thru the image pixels and add them to the vector. 449 | for (int i = 0; i < newImage.Height; i++) 450 | { 451 | for (int j = 0; j < newImage.Width; j++) 452 | { 453 | Color pixel = newImage.GetPixel(i, j); 454 | xs[1 + i*newImage.Width + j] = pixel.R; 455 | } 456 | } 457 | 458 | return xs; 459 | } 460 | 461 | /// 462 | /// Reads the model params from a file. 463 | /// 464 | private Matrix GetModelParamsFromFile() 465 | { 466 | // The model thetas (this is an intermidiate dictionary before we convert it to matrix). 467 | Dictionary> allThetas = new Dictionary>(); 468 | 469 | // Open the model file. 470 | using (StreamReader sr = new StreamReader(txtModelParams.Text)) 471 | { 472 | int rowIndex = 0; 473 | 474 | // Read the first line and loop till the end. 475 | string line = sr.ReadLine(); 476 | while (!string.IsNullOrEmpty(line)) 477 | { 478 | // Create a new row in the dictionary. 479 | allThetas.Add(rowIndex, new List()); 480 | 481 | // Split the values. 482 | string[] thetas = line.TrimStart().Split(' '); 483 | 484 | // Loop thru all values and add them. 485 | foreach (string currTheta in thetas) 486 | { 487 | // This Parse is a potential exception if there is not valid number there, ok for now... 488 | double theta = double.Parse(currTheta); 489 | allThetas[rowIndex].Add(theta); 490 | } 491 | 492 | // Get the next line and move to the next row index. 493 | line = sr.ReadLine(); 494 | ++rowIndex; 495 | } 496 | } 497 | 498 | // Create the thetas matrix. 499 | Matrix thetasM = new DenseMatrix(allThetas.Keys.Count, allThetas[0].Count); 500 | 501 | // Loop thru all dictionary vales (ordered by rows) and add it to the matrix. 502 | foreach (int row in allThetas.Keys.OrderBy(key => key)) 503 | { 504 | for (int i = 0; i < allThetas[row].Count; i++) 505 | { 506 | thetasM[row, i] = allThetas[row][i]; 507 | } 508 | } 509 | 510 | return thetasM; 511 | } 512 | 513 | #endregion 514 | 515 | #region Event Handlers 516 | 517 | private void btnOpenFile_Click(object sender, EventArgs e) 518 | { 519 | if (!string.IsNullOrEmpty(txtFile.Text)) 520 | { 521 | openFileDialog1.InitialDirectory = Path.GetDirectoryName(txtFile.Text); 522 | } 523 | 524 | openFileDialog1.Filter = "JPG|*.jpg|BMP|*.bmp"; 525 | DialogResult dr = openFileDialog1.ShowDialog(); 526 | if (dr == DialogResult.OK) 527 | { 528 | txtFile.Text = openFileDialog1.FileName; 529 | Properties.Settings.Default.InputImage = openFileDialog1.FileName; 530 | Properties.Settings.Default.Save(); 531 | } 532 | } 533 | 534 | private void btnOpenModelFile_Click(object sender, EventArgs e) 535 | { 536 | if (!string.IsNullOrEmpty(txtModelParams.Text)) 537 | { 538 | openFileDialog1.InitialDirectory = Path.GetDirectoryName(txtModelParams.Text); 539 | } 540 | 541 | openFileDialog1.Filter = "Text|*.txt"; 542 | DialogResult dr = openFileDialog1.ShowDialog(); 543 | if (dr == DialogResult.OK) 544 | { 545 | txtModelParams.Text = openFileDialog1.FileName; 546 | Properties.Settings.Default.ModelParams = openFileDialog1.FileName; 547 | Properties.Settings.Default.Save(); 548 | } 549 | } 550 | 551 | private void button1_Click(object sender, EventArgs e) 552 | { 553 | ProcessImage(); 554 | } 555 | 556 | private void blobPanel_SelectedChanged(object sender, EventArgs e) 557 | { 558 | BlobPanel panel = sender as BlobPanel; 559 | if (panel == null) return; 560 | 561 | if (panel.Selected) 562 | m_selectedBlobs.Add(panel); 563 | else 564 | m_selectedBlobs.Remove(panel); 565 | 566 | UpdateSelectedCount(); 567 | } 568 | 569 | private void blobPanel_DeleteRequest(object sender, EventArgs e) 570 | { 571 | if (m_selectedBlobs.Count < 1) 572 | return; 573 | 574 | DialogResult dr = MessageBox.Show(string.Format("Delete {0} selected blobs?", m_selectedBlobs.Count), "Delete Confirmation", MessageBoxButtons.YesNo); 575 | if (dr == DialogResult.No) 576 | return; 577 | 578 | foreach (BlobPanel selectedBlob in m_selectedBlobs) 579 | { 580 | pictureBox1.Controls.Remove(selectedBlob); 581 | } 582 | 583 | m_selectedBlobs.Clear(); 584 | UpdateSelectedCount(); 585 | } 586 | 587 | private void pictureBox1_Paint(object sender, PaintEventArgs e) 588 | { 589 | // Group by RowIndex and select the group Left, Right, Top, Bottom 590 | var rows = pictureBox1.Controls.OfType().GroupBy(bp => bp.RowIndex).Select(row => new 591 | { 592 | RowIndex = row.Key, 593 | Left = row.Min(blob => blob.Left), 594 | Right = row.Max(blob => blob.Right), 595 | Top = row.Min(blob => blob.Top), 596 | Bottom = row.Max(blob => blob.Bottom), 597 | Panles = row 598 | }); 599 | 600 | // Draw the row rectangle. 601 | rows.ForEach(row => 602 | { 603 | // Draw the row rectangle if needed. 604 | if (chkShowRows.Checked) 605 | { 606 | e.Graphics.DrawRectangle(new Pen(Color.Green, 1), row.Left - 2, row.Top - 2, 607 | (row.Right - row.Left) + 4, (row.Bottom - row.Top) + 4); 608 | } 609 | 610 | row.Panles.ForEach(panel => 611 | { 612 | if (string.IsNullOrEmpty(panel.Title)) 613 | return; 614 | 615 | e.Graphics.DrawString(panel.Title, Font, new SolidBrush(Color.Red), panel.Left + panel.Width / 2, panel.Top - 15); 616 | }); 617 | }); 618 | } 619 | 620 | private void chkShowBinarize_CheckedChanged(object sender, EventArgs e) 621 | { 622 | pictureBox1.Image = chkShowBinarize.Checked ? m_binarized : m_original; 623 | } 624 | 625 | private void btnMoveUp_Click(object sender, EventArgs e) 626 | { 627 | MoveSelectedBlobs(0, -1 * (int)txtResizeInterval.Value); 628 | } 629 | 630 | private void btnMoveRight_Click(object sender, EventArgs e) 631 | { 632 | MoveSelectedBlobs((int)txtResizeInterval.Value, 0); 633 | } 634 | 635 | private void btnMoveDown_Click(object sender, EventArgs e) 636 | { 637 | MoveSelectedBlobs(0, (int)txtResizeInterval.Value); 638 | } 639 | 640 | private void btnMoveLeft_Click(object sender, EventArgs e) 641 | { 642 | MoveSelectedBlobs(-1 * (int)txtResizeInterval.Value, 0); 643 | } 644 | 645 | private void chkShowRows_CheckedChanged(object sender, EventArgs e) 646 | { 647 | pictureBox1.Invalidate(); 648 | } 649 | 650 | private void btnExport_Click(object sender, EventArgs e) 651 | { 652 | ExportBlobs(); 653 | } 654 | 655 | private void pictureBox1_Click(object sender, EventArgs e) 656 | { 657 | // Here we take a 3x3 average of the picture color. 658 | 659 | int sumColor = 0; 660 | Point mouse = pictureBox1.PointToClient(MousePosition); 661 | for (int i = 0; i < 3; i++) 662 | { 663 | for (int j = 0; j < 3; j++) 664 | { 665 | sumColor += Common.GetColorAverage(((Bitmap)pictureBox1.Image).GetPixel(mouse.X + j, mouse.Y + i)); 666 | } 667 | } 668 | 669 | txtExtractedBackColor.Value = sumColor / 9; 670 | 671 | pictureBox1.Controls.OfType().ForEach(p => p.Selected = false); 672 | m_selectedBlobs.Clear(); 673 | UpdateSelectedCount(); 674 | pictureBox1.Invalidate(); 675 | } 676 | 677 | private void btnPredict_Click(object sender, EventArgs e) 678 | { 679 | LoadModelAndPredict(); 680 | } 681 | 682 | #endregion 683 | } 684 | } 685 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/Views/OCRTool.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 157, 17 125 | 126 | 127 | 157, 17 128 | 129 | 130 | Sometimes you want to merge two near blobs 131 | that do not intersect, in order to do this those 132 | blobs have to be enlarged so they will intersect 133 | and get merged. This value controls the amount 134 | of pixels each blob will get enlarged. 135 | 136 | 137 | Export the blobs into a matrix where each row is 138 | the blob picture and the last column is the blob 139 | row index (this should match a specific letter). 140 | The exported blobs are from the currently 141 | displayed image (i.e grayscale or binarized). 142 | 143 | 144 | Each letter is extracted into a square image, so 145 | often it is needed to extend the letter's blob, this 146 | controls the color that will be used as the background 147 | for the added area. If you click on any place on the 148 | image a sample color will be put here, so the newly 149 | backgournd color will match the existsing picture 150 | background color. 151 | 152 | -------------------------------------------------------------------------------- /MachineLearningOCRTool/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ml-ocr-tool 2 | =========== 3 | 4 | Inspired by Machine Learning course on coursera.org. 5 | A helper tool for generating ocr features for Machine Learning algos... 6 | 7 | More specifically, this tool gets a image with letters, and automatically export them into a matrix 8 | that can be imported into Octave to run some learning algorithm on. 9 | Then this tool can read a Logistic Regression Model parameters, and run it on another image 10 | to try and identify the letters. 11 | 12 | A detailed explanation video on YouTube here: 13 | https://youtu.be/o8DVk8Cl8jY 14 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Machine Learning OCR Tool 2 | =================================== 3 | 4 | Copyright (c) 2013 YuvalW 5 | 6 | 7 | Permission is hereby granted, free of charge, to any person 8 | obtaining a copy of this software and associated documentation 9 | files (the "Software"), to deal in the Software without 10 | restriction, including without limitation the rights to use, 11 | copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following 14 | conditions: 15 | 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | 27 | Other Copyrights 28 | ================ 29 | 30 | Portions of code are inspired by or derived from code 31 | covered by the following copyrights: 32 | 33 | 34 | AForge.NET 35 | ---------- 36 | 37 | AForge.NET Framework is published under LGPL v3 license. 38 | 39 | 40 | 41 | Math.NET Numerics License (MIT/X11) 42 | ----------------------------------- 43 | 44 | Copyright (c) 2002-2013 Math.NET 45 | 46 | Permission is hereby granted, free of charge, to any person 47 | obtaining a copy of this software and associated documentation 48 | files (the "Software"), to deal in the Software without 49 | restriction, including without limitation the rights to use, 50 | copy, modify, merge, publish, distribute, sublicense, and/or sell 51 | copies of the Software, and to permit persons to whom the 52 | Software is furnished to do so, subject to the following 53 | conditions: 54 | 55 | The above copyright notice and this permission notice shall be 56 | included in all copies or substantial portions of the Software. 57 | 58 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 59 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 60 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 61 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 62 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 63 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 64 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 65 | OTHER DEALINGS IN THE SOFTWARE. 66 | -------------------------------------------------------------------------------- /packages/MathNet.Numerics.2.5.0/MathNet.Numerics.2.5.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/packages/MathNet.Numerics.2.5.0/MathNet.Numerics.2.5.0.nupkg -------------------------------------------------------------------------------- /packages/MathNet.Numerics.2.5.0/MathNet.Numerics.2.5.0.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MathNet.Numerics 5 | 2.5.0 6 | Math.NET Numerics 7 | Marcus Cuda, Christoph Ruegg, Jurgen Van Gael 8 | Marcus Cuda, Christoph Ruegg, Jurgen Van Gael 9 | http://mathnetnumerics.codeplex.com/license 10 | http://numerics.mathdotnet.com/ 11 | http://www.mathdotnet.com/images/MathNet128.png 12 | false 13 | Math.NET Numerics is the numerical foundation of the Math.NET project, aiming to provide methods and algorithms for numerical computations in science, engineering and every day use. Numerics is the result of merging dnAnalytics with Math.NET Iridium and is intended to replace both. Also includes a portable build supporting .Net 4 and higher, SL5, WP8 and .NET for Windows Store apps. 14 | Math.NET Numerics, providing methods and algorithms for numerical computations in science, engineering and every day use. Supports .Net 4 and higher, SL5, WP8 and .NET for Windows Store apps. 15 | ### Potentially Breaking Changes: 16 | 17 | Despite semver this release contains two changes that may break code but without triggering a major version number change. The changes fix semantic bugs and a major usability issue without changing the formal API itself. Most users are not expected to be affected negatively. Nevertheless, this is an exceptional case and we try hard to avoid such changes in the future. 18 | 19 | - Statistics: Empty statistics now return NaN instead of either 0 or throwing an exception. *This may break code in case you relied upon the previous unusual and inconsistent behavior.* 20 | 21 | - Linear Algebra: More reasonable ToString behavior for matrices and vectors. *This may break code if you relied upon ToString to export your full data to text form intended to be parsed again later. Note that the classes in the MathNet.Numerics.IO library are more appropriate for storing and loading data.* 22 | 23 | ### Statistics: 24 | 25 | - More consistent behavior for empty and single-element data sets: Min, Max, Mean, Variance, Standard Deviation etc. no longer throw exceptions if the data set is empty but instead return NaN. Variance and Standard Deviation will also return NaN if the set contains only a single entry. Population Variance and Population Standard Deviation will return 0 in this case. 26 | - Reworked order statistics (Quantile, Quartile, Percentile, IQR, Fivenum, etc.), now much easier to use and supporting compatibility with all 9 R-types, Excel and Mathematica. The obsolete Percentile class now leverages the new order statistics, fixing a range check bug as side effect. 27 | - New Hybrid Monte Carlo sampler for multivariate distributions. 28 | - New financial statistics: absolute risk and return measures. 29 | - Explicit statistics for sorted arrays, unsorted arrays and sequences/streams. Faster algorithms on sorted data, also avoids multiple enumerations. 30 | - Some statistics like Quantile or empirical inverse CDF can optionally return a parametric function when multiple evaluations are needed, like for plotting. 31 | 32 | ### Linear Algebra: 33 | 34 | - More reasonable ToString behavior for matrices and vectors: `ToString` methods no longer render the whole structure to a string for large data, among others because they used to wreak havoc in debugging and interactive scenarios like F# FSI. Instead, ToString now only renders an excerpt of the data, together with a line about dimension, type and in case of sparse data a sparseness indicator. The intention is to give a good idea about the data in a visually useful way. How much data is shown can be adjusted in the Control class. See also ToTypeString and ToVector/MatrixString. 35 | - Performance: reworked and tuned common parallelization. Some operations are up to 3 magnitudes faster in some extreme cases. Replaced copy loops with native routines. More algorithms are storage-aware (and should thus perform better especially on sparse data). 36 | - Fixed range checks in the Thin-QR decomposition. 37 | - Fixed bug in Gram Schmidt for solving tall matrices. 38 | - Vectors now implement the BCL IList interfaces (fixed-length) for better integration with existing .Net code. 39 | - Matrix/Vector parsing has been updated to be able to parse the new visual format as well (see ToMatrixString). 40 | - DebuggerDisplay attributes for matrices and vectors. 41 | - Map/IndexedMap combinators with storage-aware and partially parallelized implementations for both dense and sparse data. 42 | - Reworked Matrix/Vector construction from arrays, enumerables, indexed enumerables, nested enumerables or by providing an init function/lambda. Non-obsolete constructors now always use the raw data array directly without copying, while static functions always return a matrix/vector independent of the provided data source. 43 | - F#: Improved extensions for matrix and vector construction: create, zeroCreate, randomCreate, init, ofArray2, ofRows/ofRowsList, ofColumns/ofSolumnsList, ofSeqi/Listi (indexed). Storage-aware for performance. 44 | - F#: Updated map/mapi and other combinators to leverage core implementation, added -nz variants where zero-values may be skipped (relevant mostly for sparse matrices). 45 | - F#: Idiomatic slice setters for sub-matrices and sub-vectors 46 | - F#: More examples for matrix/vector creation and linear regression in the F# Sample-package. 47 | 48 | ### Misc: 49 | 50 | - Control: Simpler usage with new static ConfigureAuto and ConfigureSingleThread methods. Resolved misleading configuration logic and naming around disabling parallelization. 51 | - Control: New settings for linear algebra ToString behavior. 52 | - Fixed range check in the Xor-shift pseudo-RNG. 53 | - Parallelization: Reworked our common logic to avoid expensive lambda calls in inner loops. Tunable. 54 | - F#: Examples (and thus the NuGet Sample package) are now F# scripts prepared for experimenting interactively in FSI, instead of normal F# files. Tries to get the assembly references right for most users, both within the Math.NET Numerics solution and the NuGet package. 55 | - Various minor improvements on consistency, performance, tests, xml docs, obsolete attributes, redundant code, argument checks, resources, cleanup, nuget, etc. 56 | 57 | 58 | math numeric statistics probability integration interpolation linear algebra matrix fft 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /packages/MathNet.Numerics.2.5.0/lib/net40/MathNet.Numerics.IO.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/packages/MathNet.Numerics.2.5.0/lib/net40/MathNet.Numerics.IO.dll -------------------------------------------------------------------------------- /packages/MathNet.Numerics.2.5.0/lib/net40/MathNet.Numerics.IO.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MathNet.Numerics.IO 5 | 6 | 7 | 8 | 9 | Creates a from a delimited text file. If the user does not 10 | specify a delimiter, then any whitespace is used. 11 | 12 | The type of the matrix to return. 13 | 14 | 15 | 16 | Creates a from a delimited text file. If the user does not 17 | specify a delimiter, then any whitespace is used. 18 | 19 | The type of the matrix to return. 20 | The data type of the Matrix. It can be either: double, float, Complex, or Complex32. 21 | 22 | 23 | 24 | Base class to read a single from a file or stream. 25 | 26 | The type of Matrix to return. 27 | The data type of the Matrix. It can be either: double, float, Complex, or Complex32. 28 | 29 | 30 | 31 | Reads a from a file. 32 | 33 | The file to read the matrix from. 34 | A containing the data from the file. is returned if the file is empty. 35 | If is . 36 | If the file doesn't exist. 37 | If a value is not a number or not in a valid format. 38 | If a value represents a number less than or greater than . 39 | 40 | 41 | 42 | Reads a from a . 43 | 44 | The to read the matrix from. 45 | A matrix containing the data from the . is returned if the is empty. 46 | If is . 47 | If a value is not a number or not in a valid format. 48 | If a value represents a number less than or greater than . 49 | 50 | 51 | 52 | Subclasses override this method to do the actual reading. 53 | 54 | The to read the matrix from. 55 | A matrix containing the data from the . is returned if the is empty. 56 | 57 | 58 | 59 | The function that will do the conversion for a given type. 60 | 61 | 62 | 63 | 64 | Initializes static members of the class. 65 | 66 | 67 | 68 | 69 | Converts the string into a Complex32. 70 | 71 | The number to convert. 72 | The converted number. 73 | 74 | 75 | 76 | Converts the string into a Complex. 77 | 78 | The number to convert. 79 | The converted number. 80 | 81 | 82 | 83 | Converts the string into a double. 84 | 85 | The number to convert. 86 | The converted number. 87 | 88 | 89 | 90 | Converts the string into a float. 91 | 92 | The number to convert. 93 | The converted number. 94 | 95 | 96 | 97 | Constructor to create matrix instance. 98 | 99 | 100 | 101 | 102 | The base regular expression. 103 | 104 | 105 | 106 | 107 | The regular expression to use. 108 | 109 | 110 | 111 | 112 | The to use. 113 | 114 | 115 | 116 | 117 | Initializes a new instance of the class using 118 | any whitespace as the delimiter. 119 | 120 | 121 | 122 | 123 | Initializes a new instance of the class. 124 | 125 | The delimiter to use. 126 | 127 | 128 | 129 | Initializes a new instance of the class. 130 | 131 | 132 | The delimiter to use. 133 | 134 | 135 | If is . 136 | 137 | 138 | 139 | 140 | Performs the actual reading. 141 | 142 | The to read the matrix from. 143 | 144 | A matrix containing the data from the . is returned if the is empty. 145 | 146 | 147 | 148 | 149 | Gets or sets the to use when parsing the numbers. 150 | 151 | The culture info. 152 | Defaults to CultureInfo.CurrentCulture. 153 | 154 | 155 | 156 | Gets or sets a value indicating whether the files has a header row. 157 | 158 | 159 | true if this instance has a header row; otherwise, false. 160 | 161 | Defaults to . 162 | 163 | 164 | 165 | Converts a string into the given data type. 166 | 167 | 168 | The number as a string to convert. 169 | 170 | The converted number. 171 | 172 | 173 | 174 | Initializes a new instance of the class using 175 | any whitespace as the delimiter. 176 | 177 | 178 | 179 | 180 | Initializes a new instance of the class. 181 | 182 | The delimiter to use. 183 | 184 | 185 | 186 | Initializes a new instance of the class. 187 | 188 | 189 | The delimiter to use. 190 | 191 | 192 | If is . 193 | 194 | 195 | 196 | 197 | Creates matrices from Matlab files. 198 | 199 | 200 | 201 | 202 | Creates matrices from Matlab files. 203 | 204 | The data type of the Matrix. It can be either: double, float, Complex, or Complex32. 205 | 206 | 207 | 208 | The name of the file to read from. 209 | 210 | 211 | 212 | 213 | The stream to read from if we are not reading from a file directly. 214 | 215 | 216 | 217 | 218 | Initializes a new instance of the class. 219 | 220 | Name of the file to read matrices from. 221 | 222 | 223 | 224 | Initializes a new instance of the class. 225 | 226 | The stream to reader matrices from. 227 | 228 | 229 | 230 | Reads the first matrix from the file or stream. 231 | 232 | 233 | A sparse or dense matrix depending on how the matrix 234 | is defined in the Matlab file. 235 | 236 | 237 | 238 | 239 | Reads the named matrix from the file or stream. 240 | 241 | The name of the matrix to read. 242 | 243 | A sparse or dense matrix depending on how the matrix 244 | is defined in the Matlab file. 245 | is returned if a matrix with the requests name doesn't exist. 246 | 247 | 248 | 249 | 250 | Reads all matrices from the file or stream. 251 | 252 | All matrices from the file or stream. The key to the 253 | is the matrix's name. 254 | 255 | 256 | 257 | Reads the named matrices from the file or stream. 258 | 259 | The names of the matrices to retrieve. 260 | 261 | The named matrices from the file or stream. The key to the 262 | is the matrix's name. 263 | 264 | 265 | 266 | Initializes a new instance of the class. 267 | 268 | Name of the file to read matrices from. 269 | 270 | 271 | 272 | Initializes a new instance of the class. 273 | 274 | The stream to reader matrices from. 275 | 276 | 277 | 278 | Creates a from a delimited text file. If the user does not 279 | specify a delimiter, then any whitespace is used. 280 | 281 | The type of the matrix to return. 282 | 283 | 284 | 285 | Initializes a new instance of the class using 286 | any whitespace as the delimiter. 287 | 288 | 289 | 290 | 291 | Initializes a new instance of the class. 292 | 293 | The delimiter to use. 294 | 295 | 296 | 297 | Initializes a new instance of the class. 298 | 299 | 300 | The delimiter to use. 301 | 302 | 303 | If is . 304 | 305 | 306 | 307 | 308 | Creates matrices from Matlab files. 309 | 310 | 311 | 312 | 313 | Initializes a new instance of the class. 314 | 315 | Name of the file to read matrices from. 316 | 317 | 318 | 319 | Initializes a new instance of the class. 320 | 321 | The stream to reader matrices from. 322 | 323 | 324 | 325 | Creates a from a delimited text file. If the user does not 326 | specify a delimiter, then any whitespace is used. 327 | 328 | The type of the matrix to return. 329 | 330 | 331 | 332 | Initializes a new instance of the class using 333 | any whitespace as the delimiter. 334 | 335 | 336 | 337 | 338 | Initializes a new instance of the class. 339 | 340 | The delimiter to use. 341 | 342 | 343 | 344 | Initializes a new instance of the class. 345 | 346 | 347 | The delimiter to use. 348 | 349 | 350 | If is . 351 | 352 | 353 | 354 | 355 | Creates matrices from Matlab files. 356 | 357 | 358 | 359 | 360 | Initializes a new instance of the class. 361 | 362 | Name of the file to read matrices from. 363 | 364 | 365 | 366 | Initializes a new instance of the class. 367 | 368 | The stream to reader matrices from. 369 | 370 | 371 | 372 | Writes an to delimited text file. If the user does not 373 | specify a delimiter, a tab separator is used. 374 | 375 | 376 | 377 | 378 | Base class to write a single to a file or stream. 379 | 380 | 381 | 382 | 383 | The to use. 384 | 385 | 386 | 387 | 388 | Writes the given to the given file. If the file already exists, 389 | the file will be overwritten. 390 | 391 | The matrix to write. 392 | The file to write the matrix to. 393 | If either or is null. 394 | The data type of the Matrix. It can be either: double, float, Complex, or Complex32. 395 | 396 | 397 | 398 | Writes the given to the given stream. 399 | 400 | The matrix to write. 401 | The to write the matrix to. 402 | If either or is null. 403 | The data type of the Matrix. It can be either: double, float, Complex, or Complex32. 404 | 405 | 406 | 407 | Writes the given to the given . 408 | 409 | The matrix to write. 410 | The to write the matrix to. 411 | If either or is null. 412 | The data type of the Matrix. It can be either: double, float, Complex, or Complex32. 413 | 414 | 415 | 416 | Subclasses must implement this method to do the actually writing. 417 | 418 | The data type of the Matrix. It can be either: double, float, Complex, or Complex32. 419 | The matrix to serialize. 420 | The to write the matrix to. 421 | The number format to use. 422 | The culture to use. 423 | 424 | 425 | 426 | Gets or sets the to use when parsing the numbers. 427 | 428 | The culture info. 429 | Defaults to CultureInfo.CurrentCulture. 430 | This property is only used for matrix writers that write out text files. 431 | 432 | 433 | 434 | Gets or sets he number format to use. 435 | 436 | The number format to use when writing out each element. 437 | This property is only used for matrix writers that write out text files. 438 | 439 | 440 | 441 | The delimiter to use. 442 | 443 | 444 | 445 | 446 | Initializes a new instance of the class. 447 | a comma as the delimiter. 448 | 449 | 450 | 451 | 452 | Initializes a new instance of the class. 453 | using the given delimiter. 454 | 455 | 456 | the delimiter to use. 457 | 458 | 459 | 460 | 461 | Initializes a new instance of the class. 462 | using the given delimiter. 463 | 464 | 465 | the delimiter to use. 466 | 467 | 468 | 469 | 470 | Writes the given to the given . 471 | 472 | The data type of the Matrix. It can be either: double, float, Complex, or Complex32. 473 | The matrix to write. 474 | The to write the matrix to. 475 | The number format to use on each element. 476 | The culture to use. 477 | If either or is null. 478 | 479 | 480 | 481 | Gets or sets the column header values. 482 | 483 | The column header values. 484 | Will write the column headers if the list is not empty or null. 485 | 486 | 487 | 488 | Writes matrices to a Matlab file. 489 | 490 | 491 | 492 | 493 | The file header value 494 | 495 | 496 | 497 | 498 | The length of the header text. 499 | 500 | 501 | 502 | 503 | Have we written the header yet. 504 | 505 | 506 | 507 | 508 | The binary writer to write to. 509 | 510 | 511 | 512 | 513 | Initializes a new instance of the class. 514 | 515 | The name of the Matlab file to save the matrices to. 516 | 517 | 518 | 519 | Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 520 | 521 | 522 | 523 | 524 | Writes the given to the file. 525 | 526 | The matrix to write. 527 | The name of the matrix to store in the file. 528 | If either or is null. 529 | The data type of the Matrix. It can be either: double, float, Complex, or Complex32. 530 | 531 | 532 | 533 | Writes the given to the file. 534 | 535 | The matrices to write. 536 | The names of the matrices to store in the file. 537 | If either or is null. 538 | The data type of the Matrix. It can be either: double, float, Complex, or Complex32. 539 | 540 | 541 | 542 | Closes the stream the being written to. 543 | 544 | Calls . 545 | 546 | 547 | 548 | Writes the matrix tag and name. 549 | 550 | The writer we are using. 551 | The array class we are writing. 552 | if set to true if this a complex matrix. 553 | The name name of the matrix. 554 | The number of rows. 555 | The columns of columns. 556 | The maximum number of non-zero elements. 557 | 558 | 559 | 560 | Compresses the data array. 561 | 562 | The data to compress. 563 | The compressed data. 564 | 565 | 566 | 567 | Gets the dense data array. 568 | 569 | The matrix to get the data from. 570 | The name of the matrix. 571 | The matrix data as an array. 572 | 573 | 574 | 575 | Gets the dense data array. 576 | 577 | The matrix to get the data from. 578 | The name of the matrix. 579 | The matrix data as an array. 580 | 581 | 582 | 583 | Gets the dense data array. 584 | 585 | The matrix to get the data from. 586 | The name of the matrix. 587 | The matrix data as an array. 588 | 589 | 590 | 591 | Gets the dense data array. 592 | 593 | The matrix to get the data from. 594 | The name of the matrix. 595 | The matrix data as an array. 596 | 597 | 598 | 599 | Gets the sparse data array. 600 | 601 | The matrix to get the data from. 602 | The name of the matrix. 603 | The matrix data as an array. 604 | 605 | 606 | 607 | Gets the sparse data array. 608 | 609 | The matrix to get the data from. 610 | The name of the matrix. 611 | The matrix data as an array. 612 | 613 | 614 | 615 | Gets the sparse data array. 616 | 617 | The matrix to get the data from. 618 | The name of the matrix. 619 | The matrix data as an array. 620 | 621 | 622 | 623 | Gets the sparse data array. 624 | 625 | The matrix to get the data from. 626 | The name of the matrix. 627 | The matrix data as an array. 628 | 629 | 630 | 631 | Writes the compressed data. 632 | 633 | The data to write. 634 | 635 | 636 | 637 | Writes the file header. 638 | 639 | 640 | 641 | 642 | Pads the data with the given byte. 643 | 644 | Where to write the pad values. 645 | The number of bytes to pad. 646 | What value to pad with. 647 | 648 | 649 | 650 | Computes the Adler-32 checksum of the given data. 651 | 652 | The data to create the checksum. 653 | The checksum 654 | 655 | 656 | 657 | Enumeration for the Matlab array types 658 | 659 | 660 | 661 | 662 | mxUNKNOWN CLASS 663 | 664 | 665 | 666 | 667 | mxCELL CLASS 668 | 669 | 670 | 671 | 672 | mxSTRUCT CLASS 673 | 674 | 675 | 676 | 677 | mxOBJECT CLASS 678 | 679 | 680 | 681 | 682 | mxCHAR CLASS 683 | 684 | 685 | 686 | 687 | mxSPARSE CLASS 688 | 689 | 690 | 691 | 692 | mxDOUBLE CLASS 693 | 694 | 695 | 696 | 697 | mxSINGLE CLASS 698 | 699 | 700 | 701 | 702 | mxINT8 CLASS 703 | 704 | 705 | 706 | 707 | mxUINT8 CLASS 708 | 709 | 710 | 711 | 712 | mxINT16 CLASS 713 | 714 | 715 | 716 | 717 | mxUINT16 CLASS 718 | 719 | 720 | 721 | 722 | mxINT32 CLASS 723 | 724 | 725 | 726 | 727 | mxUINT32 CLASS 728 | 729 | 730 | 731 | 732 | mxINT64 CLASS 733 | 734 | 735 | 736 | 737 | mxUINT64 CLASS 738 | 739 | 740 | 741 | 742 | mxFUNCTION CLASS 743 | 744 | 745 | 746 | 747 | Matlab Array Flags 748 | 749 | 750 | 751 | 752 | Complex flag 753 | 754 | 755 | 756 | 757 | Global flag 758 | 759 | 760 | 761 | 762 | Logical flag 763 | 764 | 765 | 766 | 767 | Matlab data types 768 | 769 | 770 | 771 | 772 | Unkown type 773 | 774 | 775 | 776 | 777 | miINT8 type 778 | 779 | 780 | 781 | 782 | miUINT8 type 783 | 784 | 785 | 786 | 787 | miINT16 type 788 | 789 | 790 | 791 | 792 | miUINT16 type 793 | 794 | 795 | 796 | 797 | miINT32 type 798 | 799 | 800 | 801 | 802 | miUINT32 type 803 | 804 | 805 | 806 | 807 | miSINGLE type 808 | 809 | 810 | 811 | 812 | miDOUBLE type 813 | 814 | 815 | 816 | 817 | miINT64 type 818 | 819 | 820 | 821 | 822 | miUINT6 4type 823 | 824 | 825 | 826 | 827 | miMATRIX type 828 | 829 | 830 | 831 | 832 | miCOMPRESSED type 833 | 834 | 835 | 836 | 837 | miUTF8 type 838 | 839 | 840 | 841 | 842 | miUTF16 type 843 | 844 | 845 | 846 | 847 | miUTF32 type 848 | 849 | 850 | 851 | 852 | Represents a Matlab file 853 | 854 | The data type of the matrix to return. 855 | 856 | 857 | 858 | Matrices in a matlab file stored as 1-D arrays 859 | 860 | 861 | 862 | 863 | Gets or sets the header text. 864 | 865 | The header text. 866 | 867 | 868 | 869 | Gets or sets the first name of the matrix. 870 | 871 | The first name of the matrix. 872 | 873 | 874 | 875 | Gets the first matrix. 876 | 877 | The first matrix. 878 | 879 | 880 | 881 | Gets the matrices. 882 | 883 | The matrices. 884 | 885 | 886 | 887 | Parse a Matlab file 888 | 889 | The data type of the matrix. 890 | 891 | 892 | 893 | Large Block Size 894 | 895 | 896 | 897 | 898 | Little Endian Indicator 899 | 900 | 901 | 902 | 903 | Small Block Size 904 | 905 | 906 | 907 | 908 | Holds the names of the matrices in the file. 909 | 910 | 911 | 912 | 913 | The stream to read the matlab file from. 914 | 915 | 916 | 917 | 918 | Initializes a new instance of the class. 919 | 920 | Name of the file. 921 | 922 | 923 | 924 | Initializes a new instance of the class. 925 | 926 | The stream to read from. 927 | 928 | 929 | 930 | Initializes a new instance of the class. 931 | 932 | The stream to read from. 933 | The name of the objects to retrieve. 934 | 935 | 936 | 937 | Initializes a new instance of the class. 938 | 939 | Name of the file. 940 | The name of the objects to retrieve. 941 | 942 | 943 | 944 | Copies the names of the objects to retrieve to a local field. 945 | 946 | The name of the objects to retrieve. 947 | 948 | 949 | 950 | Parses the file. 951 | 952 | The parsed Matlab file as a object. 953 | 954 | 955 | 956 | Aligns the data. 957 | 958 | The stream. 959 | The size of the array. 960 | if set to true if reading from a small block. 961 | 962 | 963 | 964 | Decompresses the block. 965 | 966 | The compressed data. 967 | The type data type contained in the block. 968 | The decompressed block. 969 | 970 | 971 | 972 | Adds a matrix from the actual file into our presentation of a matlab file. 973 | 974 | The data of the matrix. 975 | The instance. 976 | 977 | 978 | 979 | Populates a sparse matrix. 980 | 981 | The reader. 982 | if set to true if the Matlab complex flag is set. 983 | The number of rows. 984 | The number of columns. 985 | The size of the block. 986 | A populated sparse matrix. 987 | 988 | 989 | 990 | Populates the double sparse matrix. 991 | 992 | The matrix to populate 993 | The Matlab data type. 994 | The row indices. 995 | The column indices. 996 | The reader to read from. 997 | 998 | 999 | 1000 | Populates the float sparse matrix. 1001 | 1002 | The matrix to populate 1003 | The Matlab data type. 1004 | The row indices. 1005 | The column indices. 1006 | The reader to read from. 1007 | 1008 | 1009 | 1010 | Populates the complex sparse matrix. 1011 | 1012 | The matrix to populate 1013 | The Matlab data type. 1014 | if set to true if the Matlab complex flag is set. 1015 | The row indices. 1016 | The column indices. 1017 | The reader to read from. 1018 | The length of the stored data. 1019 | 1020 | 1021 | 1022 | Populates the complex32 sparse matrix. 1023 | 1024 | The matrix to populate 1025 | The Matlab data type. 1026 | if set to true if the Matlab complex flag is set. 1027 | The row indices. 1028 | The column indices. 1029 | The reader to read from. 1030 | The length of the stored data. 1031 | 1032 | 1033 | 1034 | Populates a dense matrix. 1035 | 1036 | The Matlab data type. 1037 | The reader to read from. 1038 | if set to true if the Matlab complex flag is set. 1039 | The number of rows. 1040 | The number of columns. 1041 | The length of the stored data. 1042 | Returns a populated dense matrix. 1043 | 1044 | 1045 | 1046 | Populates the double dense matrix. 1047 | 1048 | The matrix to populate. 1049 | The Matlab data type. 1050 | The reader to read from. 1051 | The number of rows. 1052 | The number of columns. 1053 | 1054 | 1055 | 1056 | Populates the complex dense matrix. 1057 | 1058 | The matrix to populate. 1059 | The Matlab data type. 1060 | if set to true if the Matlab complex flag is set. 1061 | The reader to read from. 1062 | The number of rows. 1063 | The number of columns. 1064 | The length of the stored data. 1065 | 1066 | 1067 | 1068 | Populates the complex32 dense matrix. 1069 | 1070 | The matrix to populate. 1071 | The Matlab data type. 1072 | if set to true if the Matlab complex flag is set. 1073 | The reader to read from. 1074 | The number of rows. 1075 | The number of columns. 1076 | The length of the stored data. 1077 | 1078 | 1079 | 1080 | Populates the float dense matrix. 1081 | 1082 | The matrix to populate. 1083 | The Matlab data type. 1084 | The reader to read from. 1085 | The number of rows. 1086 | The number of columns. 1087 | 1088 | 1089 | 1090 | Creates a matrix. 1091 | 1092 | if set to true, creates a sparse matrix. 1093 | The number of rows. 1094 | The number of columns. 1095 | A matrix with the specified storage. 1096 | 1097 | 1098 | 1099 | Creates a from a delimited text file. If the user does not 1100 | specify a delimiter, then any whitespace is used. 1101 | 1102 | The type of the matrix to return. 1103 | 1104 | 1105 | 1106 | Initializes a new instance of the class using 1107 | any whitespace as the delimiter. 1108 | 1109 | 1110 | 1111 | 1112 | Initializes a new instance of the class. 1113 | 1114 | The delimiter to use. 1115 | 1116 | 1117 | 1118 | Initializes a new instance of the class. 1119 | 1120 | 1121 | The delimiter to use. 1122 | 1123 | 1124 | If is . 1125 | 1126 | 1127 | 1128 | 1129 | Creates matrices from Matlab files. 1130 | 1131 | 1132 | 1133 | 1134 | Initializes a new instance of the class. 1135 | 1136 | Name of the file to read matrices from. 1137 | 1138 | 1139 | 1140 | Initializes a new instance of the class. 1141 | 1142 | The stream to reader matrices from. 1143 | 1144 | 1145 | 1146 | -------------------------------------------------------------------------------- /packages/MathNet.Numerics.2.5.0/lib/net40/MathNet.Numerics.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/packages/MathNet.Numerics.2.5.0/lib/net40/MathNet.Numerics.dll -------------------------------------------------------------------------------- /packages/MathNet.Numerics.2.5.0/lib/portable-net40+windows8+wp8+sl5/MathNet.Numerics.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValYouW/ml-ocr-tool/9bd6135fb0e1a2a28b1d6bfa89ef978527c13e18/packages/MathNet.Numerics.2.5.0/lib/portable-net40+windows8+wp8+sl5/MathNet.Numerics.dll -------------------------------------------------------------------------------- /packages/MathNet.Numerics.2.5.0/license.txt: -------------------------------------------------------------------------------- 1 | Math.NET Numerics License (MIT/X11) 2 | =================================== 3 | 4 | Copyright (c) 2002-2013 Math.NET 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | 27 | Other Copyrights 28 | ================ 29 | 30 | Portions of code are inspired by or derived from code 31 | covered by the following copyrights: 32 | 33 | ALGLIB 34 | ------ 35 | 36 | Any code from ALGLIB is from version 2.0.1 which is distributed 37 | under the license below. 38 | 39 | Copyright (c) 2007, Sergey Bochkanov (ALGLIB project). 40 | 41 | Redistribution and use in source and binary forms, with or without 42 | modification, are permitted provided that the following conditions are 43 | met: 44 | 45 | - Redistributions of source code must retain the above copyright 46 | notice, this list of conditions and the following disclaimer. 47 | 48 | - Redistributions in binary form must reproduce the above copyright 49 | notice, this list of conditions and the following disclaimer listed 50 | in this license in the documentation and/or other materials 51 | provided with the distribution. 52 | 53 | - Neither the name of the copyright holders nor the names of its 54 | contributors may be used to endorse or promote products derived from 55 | this software without specific prior written permission. 56 | 57 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 58 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 59 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 60 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 61 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 62 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 63 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 64 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 65 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 66 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 67 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68 | 69 | BOOST 70 | ----- 71 | 72 | Boost Software License - Version 1.0 - August 17th, 2003 73 | 74 | Permission is hereby granted, free of charge, to any person or organization 75 | obtaining a copy of the software and accompanying documentation covered by 76 | this license (the "Software") to use, reproduce, display, distribute, 77 | execute, and transmit the Software, and to prepare derivative works of the 78 | Software, and to permit third-parties to whom the Software is furnished to 79 | do so, all subject to the following: 80 | 81 | The copyright notices in the Software and this entire statement, including 82 | the above license grant, this restriction and the following disclaimer, 83 | must be included in all copies of the Software, in whole or in part, and 84 | all derivative works of the Software, unless such copies or derivative 85 | works are solely in the form of machine-executable object code generated by 86 | a source language processor. 87 | 88 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 89 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 90 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 91 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 92 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 93 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 94 | DEALINGS IN THE SOFTWARE. 95 | -------------------------------------------------------------------------------- /packages/MathNet.Numerics.2.5.0/readme.txt: -------------------------------------------------------------------------------- 1 | Math.NET Numerics Release Notes 2 | =============================== 3 | 4 | - **Website: [numerics.mathdotnet.com](http://numerics.mathdotnet.com)** 5 | - GitHub/Mainline: [github.com/mathnet/mathnet-numerics](https://github.com/mathnet/mathnet-numerics) 6 | - CodePlex: [mathnetnumerics.codeplex.com](http://mathnetnumerics.codeplex.com) 7 | - License: MIT/X11 Open Source 8 | 9 | NuGet Packages, available in the [NuGet Gallery](https://nuget.org/profiles/mathnet/): 10 | 11 | - `MathNet.Numerics` - core package, including both .Net 4 and portable builds 12 | - `MathNet.Numerics.FSharp` - optional extensions for a better F# experience 13 | - `MathNet.Numerics.MKL.Win-x86` - optional Linear Algebra MKL native provider 14 | - `MathNet.Numerics.MKL.Win-x64` - optional Linear Algebra MKL native provider 15 | - `MathNet.Numerics.Signed` - strong-named version of the core package (not recommended) 16 | - `MathNet.Numerics.Samples` - code samples in C# 17 | - `MathNet.Numerics.FSharp.Samples` - code samples in F# 18 | 19 | Zip Packages, available on [CodePlex](http://mathnetnumerics.codeplex.com/releases): 20 | 21 | - Binaries - core package and F# extensions, including both .Net 4 and portable builds 22 | - Signed Binaries - strong-named version of the core package (not recommended) 23 | 24 | Over time some members and classes have been replaced with more suitable alternatives. In order to maintain compatibility, such parts are not removed immediately but instead marked with the **Obsolete**-attribute. We strongly recommend to follow the instructions in the attribute text whenever you find any code calling an obsolete member, since we *do* intend to remove them at the next *major* release, v3.0. 25 | 26 | v2.5.0 - April 14, 2013 27 | ----------------------- 28 | 29 | ### *Potentially Breaking Changes:* 30 | 31 | Despite semver this release contains two changes that may break code but without triggering a major version number change. The changes fix semantic bugs and a major usability issue without changing the formal API itself. Most users are not expected to be affected negatively. Nevertheless, this is an exceptional case and we try hard to avoid such changes in the future. 32 | 33 | - Statistics: Empty statistics now return NaN instead of either 0 or throwing an exception. *This may break code in case you relied upon the previous unusual and inconsistent behavior.* 34 | 35 | - Linear Algebra: More reasonable ToString behavior for matrices and vectors. *This may break code if you relied upon ToString to export your full data to text form intended to be parsed again later. Note that the classes in the MathNet.Numerics.IO library are more appropriate for storing and loading data.* 36 | 37 | ### Statistics: 38 | 39 | - More consistent behavior for empty and single-element data sets: Min, Max, Mean, Variance, Standard Deviation etc. no longer throw exceptions if the data set is empty but instead return NaN. Variance and Standard Deviation will also return NaN if the set contains only a single entry. Population Variance and Population Standard Deviation will return 0 in this case. 40 | - Reworked order statistics (Quantile, Quartile, Percentile, IQR, Fivenum, etc.), now much easier to use and supporting compatibility with all 9 R-types, Excel and Mathematica. The obsolete Percentile class now leverages the new order statistics, fixing a range check bug as side effect. 41 | - New Hybrid Monte Carlo sampler for multivariate distributions. 42 | - New financial statistics: absolute risk and return measures. 43 | - Explicit statistics for sorted arrays, unsorted arrays and sequences/streams. Faster algorithms on sorted data, also avoids multiple enumerations. 44 | - Some statistics like Quantile or empirical inverse CDF can optionally return a parametric function when multiple evaluations are needed, like for plotting. 45 | 46 | ### Linear Algebra: 47 | 48 | - More reasonable ToString behavior for matrices and vectors: `ToString` methods no longer render the whole structure to a string for large data, among others because they used to wreak havoc in debugging and interactive scenarios like F# FSI. Instead, ToString now only renders an excerpt of the data, together with a line about dimension, type and in case of sparse data a sparseness indicator. The intention is to give a good idea about the data in a visually useful way. How much data is shown can be adjusted in the Control class. See also ToTypeString and ToVector/MatrixString. 49 | - Performance: reworked and tuned common parallelization. Some operations are up to 3 magnitudes faster in some extreme cases. Replaced copy loops with native routines. More algorithms are storage-aware (and should thus perform better especially on sparse data). 50 | - Fixed range checks in the Thin-QR decomposition. 51 | - Fixed bug in Gram Schmidt for solving tall matrices. 52 | - Vectors now implement the BCL IList interfaces (fixed-length) for better integration with existing .Net code. 53 | - Matrix/Vector parsing has been updated to be able to parse the new visual format as well (see ToMatrixString). 54 | - DebuggerDisplay attributes for matrices and vectors. 55 | - Map/IndexedMap combinators with storage-aware and partially parallelized implementations for both dense and sparse data. 56 | - Reworked Matrix/Vector construction from arrays, enumerables, indexed enumerables, nested enumerables or by providing an init function/lambda. Non-obsolete constructors now always use the raw data array directly without copying, while static functions always return a matrix/vector independent of the provided data source. 57 | - F#: Improved extensions for matrix and vector construction: create, zeroCreate, randomCreate, init, ofArray2, ofRows/ofRowsList, ofColumns/ofSolumnsList, ofSeqi/Listi (indexed). Storage-aware for performance. 58 | - F#: Updated map/mapi and other combinators to leverage core implementation, added -nz variants where zero-values may be skipped (relevant mostly for sparse matrices). 59 | - F#: Idiomatic slice setters for sub-matrices and sub-vectors 60 | - F#: More examples for matrix/vector creation and linear regression in the F# Sample-package. 61 | 62 | ### Misc: 63 | 64 | - Control: Simpler usage with new static ConfigureAuto and ConfigureSingleThread methods. Resolved misleading configuration logic and naming around disabling parallelization. 65 | - Control: New settings for linear algebra ToString behavior. 66 | - Fixed range check in the Xor-shift pseudo-RNG. 67 | - Parallelization: Reworked our common logic to avoid expensive lambda calls in inner loops. Tunable. 68 | - F#: Examples (and thus the NuGet Sample package) are now F# scripts prepared for experimenting interactively in FSI, instead of normal F# files. Tries to get the assembly references right for most users, both within the Math.NET Numerics solution and the NuGet package. 69 | - Various minor improvements on consistency, performance, tests, xml docs, obsolete attributes, redundant code, argument checks, resources, cleanup, nuget, etc. 70 | 71 | 72 | v2.4.0 - February 3, 2013 73 | ------------------------- 74 | 75 | - Drops the dependency on the zlib library. We thus no longer have any dependencies on other packages. 76 | - Adds Modified Bessel & Struve special functions 77 | - Fixes a bug in our iterative kurtosis statistics formula 78 | 79 | ### Linear Algebra: 80 | 81 | - Performance work, this time mostly around accessing matrix rows/columns as vectors. Opting out from targeted patching in our matrix and vector indexers to allow inlining. 82 | - Fixes an issue around Thin-QR solve 83 | - Simplifications around using native linear algebra providers (see Math.NET Numerics With Native Linear Algebra) 84 | 85 | ### F#: 86 | 87 | - Adds the BigRational module from the F# PowerPack, now to be maintained here instead. 88 | - Better support for our Complex types (close to the F# PowerPack Complex type) 89 | 90 | 91 | v2.3.0 - November 25, 2012 92 | -------------------------- 93 | 94 | ### Portable Library Build: 95 | 96 | - Adds support for WP8 (.Net 4.0 and higher, SL5, WP8 and .NET for Windows Store apps) 97 | - New: portable build also for F# extensions (.Net 4.5, SL5 and .NET for Windows Store apps) 98 | - NuGet: portable builds are now included in the main packages, no more need for special portable packages 99 | 100 | ### Linear Algebra: 101 | 102 | - Continued major storage rework, in this release focusing on vectors (previous release was on matrices) 103 | - Thin QR decomposition (in addition to existing full QR) 104 | - Static CreateRandom for all dense matrix and vector types 105 | - F#: slicing support for matrices and vectors 106 | 107 | ### Random and Probability Distributions: 108 | 109 | - Consistent static Sample methods for all continuous and discrete distributions (was previously missing on a few) 110 | - F#: better usability for random numbers and distributions. 111 | 112 | ### Misc: 113 | 114 | - F# extensions are now using F# 3.0 115 | - Updated Intel MKL references for our native linear algebra providers 116 | - Various bug, performance and usability fixes 117 | -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | --------------------------------------------------------------------------------