Browse Source

commit: import projet

HOME 4 years ago
parent
commit
8dccb1c914

+ 22 - 0
Ocr.sln

@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.25302.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OcrPrepWinform", "OcrPrepWinform\OcrPrepWinform.csproj", "{707CD816-68C7-43E3-86FE-9120281F7D0A}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{707CD816-68C7-43E3-86FE-9120281F7D0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{707CD816-68C7-43E3-86FE-9120281F7D0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{707CD816-68C7-43E3-86FE-9120281F7D0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{707CD816-68C7-43E3-86FE-9120281F7D0A}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 6 - 0
OcrPrepWinform/App.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
+    </startup>
+</configuration>

+ 21 - 0
OcrPrepWinform/BaseForm.cs

@@ -0,0 +1,21 @@
+using System.Windows.Forms;
+
+namespace OcrPrepWinform
+{
+    internal class MyClass
+    {
+    }
+
+    public class BaseForm : Form
+    {
+        public BaseForm()
+        {
+            Init();
+        }
+
+        private void Init()
+        {
+            Text = Application.ProductName;
+        }
+    }
+}

+ 209 - 0
OcrPrepWinform/ImageProcessor.cs

@@ -0,0 +1,209 @@
+using System.Drawing;
+using System.Drawing.Imaging;
+
+namespace OcrPrepWinform
+{
+    internal static class ImageProcessor
+    {
+        /// <summary>
+        /// 得到灰度图像前景背景的临界值 最大类间方差法,yuanbao,2007.08
+        /// </summary>
+        /// <returns>前景背景的临界值</returns>
+        public static int GetDgGrayValue(this Bitmap bmpobj)
+        {
+            var pixelNum = new int[256];           //图象直方图,共256个点
+            int n, n1, n2;
+            int total;                              //total为总和,累计值
+            double m1, m2, sum, csum, fmax, sb;     //sb为类间方差,fmax存储最大方差值
+            int k, t, q;
+            var threshValue = 1;                      // 阈值
+            var step = 1;
+            //生成直方图
+            for (var i = 0; i < bmpobj.Width; i++)
+            {
+                for (var j = 0; j < bmpobj.Height; j++)
+                {
+                    //返回各个点的颜色,以RGB表示
+                    pixelNum[bmpobj.GetPixel(i, j).R]++;            //相应的直方图加1
+                }
+            }
+            //直方图平滑化
+            for (k = 0; k <= 255; k++)
+            {
+                total = 0;
+                for (t = -2; t <= 2; t++)              //与附近2个灰度做平滑化,t值应取较小的值
+                {
+                    q = k + t;
+                    if (q < 0)                     //越界处理
+                        q = 0;
+                    if (q > 255)
+                        q = 255;
+                    total = total + pixelNum[q];    //total为总和,累计值
+                }
+                pixelNum[k] = (int)(total / 5.0 + 0.5);    //平滑化,左边2个+中间1个+右边2个灰度,共5个,所以总和除以5,后面加0.5是用修正值
+            }
+            //求阈值
+            sum = csum = 0.0;
+            n = 0;
+            //计算总的图象的点数和质量矩,为后面的计算做准备
+            for (k = 0; k <= 255; k++)
+            {
+                sum += k * (double)pixelNum[k];     //x*f(x)质量矩,也就是每个灰度的值乘以其点数(归一化后为概率),sum为其总和
+                n += pixelNum[k];                       //n为图象总的点数,归一化后就是累积概率
+            }
+
+            fmax = -1.0;                          //类间方差sb不可能为负,所以fmax初始值为-1不影响计算的进行
+            n1 = 0;
+            for (k = 0; k < 256; k++)                  //对每个灰度(从0到255)计算一次分割后的类间方差sb
+            {
+                n1 += pixelNum[k];                //n1为在当前阈值遍前景图象的点数
+                if (n1 == 0) { continue; }            //没有分出前景后景
+                n2 = n - n1;                        //n2为背景图象的点数
+                if (n2 == 0) { break; }               //n2为0表示全部都是后景图象,与n1=0情况类似,之后的遍历不可能使前景点数增加,所以此时可以退出循环
+                csum += (double)k * pixelNum[k];    //前景的“灰度的值*其点数”的总和
+                m1 = csum / n1;                     //m1为前景的平均灰度
+                m2 = (sum - csum) / n2;               //m2为背景的平均灰度
+                sb = n1 * (double)n2 * (m1 - m2) * (m1 - m2);   //sb为类间方差
+                if (sb > fmax)                  //如果算出的类间方差大于前一次算出的类间方差
+                {
+                    fmax = sb;                    //fmax始终为最大类间方差(otsu)
+                    threshValue = k;              //取最大类间方差时对应的灰度的k就是最佳阈值
+                }
+            }
+            return threshValue;
+        }
+
+        /// <summary>
+        ///  去掉杂点(适合杂点/杂线粗为1)
+        /// </summary>
+        /// <param name="dgGrayValue">背前景灰色界限</param>
+        public static void ClearNoise(this Bitmap bmpobj, int dgGrayValue, int MaxNearPoints)
+        {
+            Color piexl;
+            var nearDots = 0;
+            int XSpan, YSpan, tmpX, tmpY;
+            //逐点判断
+            for (var i = 0; i < bmpobj.Width; i++)
+                for (var j = 0; j < bmpobj.Height; j++)
+                {
+                    piexl = bmpobj.GetPixel(i, j);
+                    if (piexl.R < dgGrayValue)
+                    {
+                        nearDots = 0;
+                        //判断周围8个点是否全为空
+                        if (i == 0 || i == bmpobj.Width - 1 || j == 0 || j == bmpobj.Height - 1)  //边框全去掉
+                        {
+                            bmpobj.SetPixel(i, j, Color.FromArgb(255, 255, 255));
+                        }
+                        else
+                        {
+                            if (bmpobj.GetPixel(i - 1, j - 1).R < dgGrayValue) nearDots++;
+                            if (bmpobj.GetPixel(i, j - 1).R < dgGrayValue) nearDots++;
+                            if (bmpobj.GetPixel(i + 1, j - 1).R < dgGrayValue) nearDots++;
+                            if (bmpobj.GetPixel(i - 1, j).R < dgGrayValue) nearDots++;
+                            if (bmpobj.GetPixel(i + 1, j).R < dgGrayValue) nearDots++;
+                            if (bmpobj.GetPixel(i - 1, j + 1).R < dgGrayValue) nearDots++;
+                            if (bmpobj.GetPixel(i, j + 1).R < dgGrayValue) nearDots++;
+                            if (bmpobj.GetPixel(i + 1, j + 1).R < dgGrayValue) nearDots++;
+                        }
+
+                        if (nearDots < MaxNearPoints)
+                            bmpobj.SetPixel(i, j, Color.FromArgb(255, 255, 255));   //去掉单点 && 粗细小3邻边点
+                    }
+                    else  //背景
+                        bmpobj.SetPixel(i, j, Color.FromArgb(255, 255, 255));
+                }
+        }
+
+        /// <summary>
+        /// 3×3中值滤波除杂,yuanbao,2007.10
+        /// </summary>
+        public static Bitmap ClearNoise(this Bitmap bmpobj, int dgGrayValue)
+        {
+            int x, y;
+            var p = new byte[9]; //最小处理窗口3*3
+            byte s;
+            //byte[] lpTemp=new BYTE[nByteWidth*nHeight];
+            int i, j;
+
+            //--!!!!!!!!!!!!!!下面开始窗口为3×3中值滤波!!!!!!!!!!!!!!!!
+            for (y = 1; y < bmpobj.Height - 1; y++) //--第一行和最后一行无法取窗口
+            {
+                for (x = 1; x < bmpobj.Width - 1; x++)
+                {
+                    //取9个点的值
+                    p[0] = bmpobj.GetPixel(x - 1, y - 1).R;
+                    p[1] = bmpobj.GetPixel(x, y - 1).R;
+                    p[2] = bmpobj.GetPixel(x + 1, y - 1).R;
+                    p[3] = bmpobj.GetPixel(x - 1, y).R;
+                    p[4] = bmpobj.GetPixel(x, y).R;
+                    p[5] = bmpobj.GetPixel(x + 1, y).R;
+                    p[6] = bmpobj.GetPixel(x - 1, y + 1).R;
+                    p[7] = bmpobj.GetPixel(x, y + 1).R;
+                    p[8] = bmpobj.GetPixel(x + 1, y + 1).R;
+                    //计算中值
+                    for (j = 0; j < 5; j++)
+                    {
+                        for (i = j + 1; i < 9; i++)
+                        {
+                            if (p[j] > p[i])
+                            {
+                                s = p[j];
+                                p[j] = p[i];
+                                p[i] = s;
+                            }
+                        }
+                    }
+                    //      if (bmpobj.GetPixel(x, y).R < dgGrayValue)
+                    bmpobj.SetPixel(x, y, Color.FromArgb(p[4], p[4], p[4]));    //给有效值付中值
+                }
+            }
+
+            return bmpobj;
+        }
+
+        public static Bitmap ToRgb24(this Bitmap bmo)
+        {
+            var bm2 = new Bitmap(bmo.Width, bmo.Height, PixelFormat.Format24bppRgb);
+            using (var g = Graphics.FromImage(bm2))
+            {
+                g.DrawImage(bmo, 0, 0);
+            }
+            return bm2;
+        }
+
+        public static Bitmap DotRemove(this Bitmap bm, int around = 2, Color? bg = null)
+        {
+            var b = bg ?? Color.FromArgb(255, 255, 255, 255);
+            for (var i = 0; i < bm.Width; i++)
+            {
+                for (var j = 0; j < bm.Height; j++)
+                {
+                    if (bm.GetPixel(i, j) == b) continue;
+
+                    var ar = 0;
+
+                    // LT T RT
+                    if (i > 0 && j > 0) if (bm.GetPixel(i - 1, j - 1) != b) ar++;
+                    if (j > 0) if (bm.GetPixel(i, j - 1) != b) ar++;
+                    if (j < bm.Height - 1) if (bm.GetPixel(i, j + 1) != b) ar++;
+
+                    // L R
+                    if (i > 0) if (bm.GetPixel(i - 1, j) != b) ar++;
+                    if (i < bm.Width - 1) if (bm.GetPixel(i + 1, j) != b) ar++;
+
+                    // LB B RB
+                    if (i > 0 && j < bm.Height - 1) if (bm.GetPixel(i - 1, j + 1) != b) ar++;
+                    if (j < bm.Height - 1) if (bm.GetPixel(i, j + 1) != b) ar++;
+                    if (i < bm.Width - 1 && j < bm.Height - 1) if (bm.GetPixel(i + 1, j + 1) != b) ar++;
+
+
+                    if (ar <= around)
+                        bm.SetPixel(i, j, b);
+                }
+            }
+
+            return bm;
+        }
+    }
+}

+ 203 - 0
OcrPrepWinform/MainForm.Designer.cs

@@ -0,0 +1,203 @@
+namespace OcrPrepWinform
+{
+    partial class MainForm
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.txtDownlaodUrl = new System.Windows.Forms.TextBox();
+            this.btnDownloadImg = new System.Windows.Forms.Button();
+            this.picOringal = new System.Windows.Forms.PictureBox();
+            this.picPreProcessed = new System.Windows.Forms.PictureBox();
+            this.btnPreProcess = new System.Windows.Forms.Button();
+            this.btnOcr = new System.Windows.Forms.Button();
+            this.txtResult = new System.Windows.Forms.TextBox();
+            this.chkAutoPreprocess = new System.Windows.Forms.CheckBox();
+            this.chkAutoOcr = new System.Windows.Forms.CheckBox();
+            this.txtWhiteList = new System.Windows.Forms.TextBox();
+            this.chkIs = new System.Windows.Forms.CheckBox();
+            ((System.ComponentModel.ISupportInitialize)(this.picOringal)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.picPreProcessed)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // txtDownlaodUrl
+            // 
+            this.txtDownlaodUrl.Location = new System.Drawing.Point(82, 9);
+            this.txtDownlaodUrl.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.txtDownlaodUrl.Name = "txtDownlaodUrl";
+            this.txtDownlaodUrl.Size = new System.Drawing.Size(352, 21);
+            this.txtDownlaodUrl.TabIndex = 0;
+            // 
+            // btnDownloadImg
+            // 
+            this.btnDownloadImg.Location = new System.Drawing.Point(9, 11);
+            this.btnDownloadImg.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.btnDownloadImg.Name = "btnDownloadImg";
+            this.btnDownloadImg.Size = new System.Drawing.Size(69, 20);
+            this.btnDownloadImg.TabIndex = 1;
+            this.btnDownloadImg.Text = "下载图片";
+            this.btnDownloadImg.UseVisualStyleBackColor = true;
+            this.btnDownloadImg.Click += new System.EventHandler(this.btnDownloadImg_Click);
+            // 
+            // picOringal
+            // 
+            this.picOringal.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+            this.picOringal.Location = new System.Drawing.Point(82, 33);
+            this.picOringal.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.picOringal.Name = "picOringal";
+            this.picOringal.Size = new System.Drawing.Size(116, 50);
+            this.picOringal.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
+            this.picOringal.TabIndex = 2;
+            this.picOringal.TabStop = false;
+            // 
+            // picPreProcessed
+            // 
+            this.picPreProcessed.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+            this.picPreProcessed.Location = new System.Drawing.Point(202, 33);
+            this.picPreProcessed.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.picPreProcessed.Name = "picPreProcessed";
+            this.picPreProcessed.Size = new System.Drawing.Size(112, 50);
+            this.picPreProcessed.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
+            this.picPreProcessed.TabIndex = 2;
+            this.picPreProcessed.TabStop = false;
+            // 
+            // btnPreProcess
+            // 
+            this.btnPreProcess.Location = new System.Drawing.Point(9, 33);
+            this.btnPreProcess.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.btnPreProcess.Name = "btnPreProcess";
+            this.btnPreProcess.Size = new System.Drawing.Size(69, 20);
+            this.btnPreProcess.TabIndex = 1;
+            this.btnPreProcess.Text = "预处理";
+            this.btnPreProcess.UseVisualStyleBackColor = true;
+            this.btnPreProcess.Click += new System.EventHandler(this.btnPreProcess_Click);
+            // 
+            // btnOcr
+            // 
+            this.btnOcr.Location = new System.Drawing.Point(9, 55);
+            this.btnOcr.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.btnOcr.Name = "btnOcr";
+            this.btnOcr.Size = new System.Drawing.Size(69, 20);
+            this.btnOcr.TabIndex = 1;
+            this.btnOcr.Text = "识别";
+            this.btnOcr.UseVisualStyleBackColor = true;
+            this.btnOcr.Click += new System.EventHandler(this.btnOcr_Click);
+            // 
+            // txtResult
+            // 
+            this.txtResult.Font = new System.Drawing.Font("Fixedsys Excelsior 3.01", 32.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.txtResult.Location = new System.Drawing.Point(317, 33);
+            this.txtResult.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.txtResult.Name = "txtResult";
+            this.txtResult.ReadOnly = true;
+            this.txtResult.Size = new System.Drawing.Size(117, 50);
+            this.txtResult.TabIndex = 3;
+            this.txtResult.Text = "????";
+            // 
+            // chkAutoPreprocess
+            // 
+            this.chkAutoPreprocess.AutoSize = true;
+            this.chkAutoPreprocess.Location = new System.Drawing.Point(64, 38);
+            this.chkAutoPreprocess.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.chkAutoPreprocess.Name = "chkAutoPreprocess";
+            this.chkAutoPreprocess.Size = new System.Drawing.Size(15, 14);
+            this.chkAutoPreprocess.TabIndex = 4;
+            this.chkAutoPreprocess.UseVisualStyleBackColor = true;
+            // 
+            // chkAutoOcr
+            // 
+            this.chkAutoOcr.AutoSize = true;
+            this.chkAutoOcr.Location = new System.Drawing.Point(64, 60);
+            this.chkAutoOcr.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.chkAutoOcr.Name = "chkAutoOcr";
+            this.chkAutoOcr.Size = new System.Drawing.Size(15, 14);
+            this.chkAutoOcr.TabIndex = 5;
+            this.chkAutoOcr.UseVisualStyleBackColor = true;
+            // 
+            // txtWhiteList
+            // 
+            this.txtWhiteList.Location = new System.Drawing.Point(82, 86);
+            this.txtWhiteList.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.txtWhiteList.Name = "txtWhiteList";
+            this.txtWhiteList.Size = new System.Drawing.Size(231, 21);
+            this.txtWhiteList.TabIndex = 6;
+            this.txtWhiteList.Text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+            // 
+            // chkIs
+            // 
+            this.chkIs.AutoSize = true;
+            this.chkIs.Location = new System.Drawing.Point(317, 88);
+            this.chkIs.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.chkIs.Name = "chkIs";
+            this.chkIs.Size = new System.Drawing.Size(120, 16);
+            this.chkIs.TabIndex = 7;
+            this.chkIs.Text = "interword_spaces";
+            this.chkIs.UseVisualStyleBackColor = true;
+            // 
+            // MainForm
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(460, 110);
+            this.Controls.Add(this.chkIs);
+            this.Controls.Add(this.txtWhiteList);
+            this.Controls.Add(this.chkAutoOcr);
+            this.Controls.Add(this.chkAutoPreprocess);
+            this.Controls.Add(this.txtResult);
+            this.Controls.Add(this.picPreProcessed);
+            this.Controls.Add(this.picOringal);
+            this.Controls.Add(this.btnOcr);
+            this.Controls.Add(this.btnPreProcess);
+            this.Controls.Add(this.btnDownloadImg);
+            this.Controls.Add(this.txtDownlaodUrl);
+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+            this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
+            this.MaximizeBox = false;
+            this.MinimizeBox = false;
+            this.Name = "MainForm";
+            ((System.ComponentModel.ISupportInitialize)(this.picOringal)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.picPreProcessed)).EndInit();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.TextBox txtDownlaodUrl;
+        private System.Windows.Forms.Button btnDownloadImg;
+        private System.Windows.Forms.PictureBox picOringal;
+        private System.Windows.Forms.PictureBox picPreProcessed;
+        private System.Windows.Forms.Button btnPreProcess;
+        private System.Windows.Forms.Button btnOcr;
+        private System.Windows.Forms.TextBox txtResult;
+        private System.Windows.Forms.CheckBox chkAutoPreprocess;
+        private System.Windows.Forms.CheckBox chkAutoOcr;
+        private System.Windows.Forms.TextBox txtWhiteList;
+        private System.Windows.Forms.CheckBox chkIs;
+    }
+}
+

+ 58 - 0
OcrPrepWinform/MainForm.cs

@@ -0,0 +1,58 @@
+using AForge.Imaging.Filters;
+using System.Drawing;
+using System.Windows.Forms;
+using Tesseract;
+
+namespace OcrPrepWinform
+{
+    public partial class MainForm : BaseForm
+    {
+        public MainForm()
+        {
+            InitializeComponent();
+        }
+
+        private void btnDownloadImg_Click(object sender, System.EventArgs e)
+        {
+            picOringal.Load(txtDownlaodUrl.Text);
+            picPreProcessed.Image = picOringal.Image;
+            if (chkAutoPreprocess.Checked) PreProcess();
+            if (chkAutoOcr.Checked) Ocr();
+        }
+        private void PreProcess()
+        {
+            using (var bm2 = Grayscale.CommonAlgorithms.Y.Apply(((Bitmap)picPreProcessed.Image).ToRgb24()).ToRgb24())
+            {
+                var gr = bm2.GetDgGrayValue();
+                bm2.ClearNoise(gr, 1);
+                bm2.DotRemove(1);
+                bm2.DotRemove(1);
+                Application.DoEvents();
+                picPreProcessed.Image = bm2.ToRgb24();
+            }
+        }
+        private void Ocr()
+        {
+            using (var tess = new TesseractEngine(@"..\tessdata", "eng"))
+            {
+                tess.SetVariable("tessedit_char_whitelist", txtWhiteList.Text);
+                tess.SetVariable("preserve_interword_spaces", chkIs.Checked ? 1 : 0);
+                var result = tess.Process((Bitmap)picPreProcessed.Image, PageSegMode.SingleLine);
+                txtResult.Text = result.GetText().Trim();
+            }
+        }
+
+        private void btnPreProcess_Click(object sender, System.EventArgs e)
+        {
+            PreProcess();
+        }
+
+
+        private void btnOcr_Click(object sender, System.EventArgs e)
+        {
+            Ocr();
+        }
+
+
+    }
+}

+ 120 - 0
OcrPrepWinform/MainForm.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 99 - 0
OcrPrepWinform/OcrPrepWinform.csproj

@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{707CD816-68C7-43E3-86FE-9120281F7D0A}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>OcrPrepWinform</RootNamespace>
+    <AssemblyName>OcrPrepWinform</AssemblyName>
+    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="AForge, Version=2.2.5.0, Culture=neutral, PublicKeyToken=c1db6ff4eaa06aeb, processorArchitecture=MSIL">
+      <HintPath>..\packages\AForge.2.2.5\lib\AForge.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="AForge.Imaging, Version=2.2.5.0, Culture=neutral, PublicKeyToken=ba8ddea9676ca48b, processorArchitecture=MSIL">
+      <HintPath>..\packages\AForge.Imaging.2.2.5\lib\AForge.Imaging.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="AForge.Math, Version=2.2.5.0, Culture=neutral, PublicKeyToken=abba2e25397ee8c9, processorArchitecture=MSIL">
+      <HintPath>..\packages\AForge.Math.2.2.5\lib\AForge.Math.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+    <Reference Include="Tesseract, Version=3.3.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\Tesseract.3.3.0\lib\net45\Tesseract.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BaseForm.cs" />
+    <Compile Include="ImageProcessor.cs" />
+    <Compile Include="MainForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="MainForm.Designer.cs">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="MainForm.resx">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Import Project="..\packages\Tesseract.3.3.0\build\Tesseract.targets" Condition="Exists('..\packages\Tesseract.3.3.0\build\Tesseract.targets')" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\Tesseract.3.3.0\build\Tesseract.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Tesseract.3.3.0\build\Tesseract.targets'))" />
+  </Target>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 22 - 0
OcrPrepWinform/Program.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace OcrPrepWinform
+{
+    static class Program
+    {
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.Run(new MainForm());
+        }
+    }
+}

+ 36 - 0
OcrPrepWinform/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OcrPrepWinform")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("OcrPrepWinform")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("707cd816-68c7-43e3-86fe-9120281f7d0a")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 7 - 0
OcrPrepWinform/packages.config

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="AForge" version="2.2.5" targetFramework="net452" />
+  <package id="AForge.Imaging" version="2.2.5" targetFramework="net452" />
+  <package id="AForge.Math" version="2.2.5" targetFramework="net452" />
+  <package id="Tesseract" version="3.3.0" targetFramework="net452" />
+</packages>