在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#图形和图像处理 → C# 实现简单数字验证码解析(Tesseract OCR 解析验证码) 实例代码

C# 实现简单数字验证码解析(Tesseract OCR 解析验证码) 实例代码

C#图形和图像处理

下载此实例
  • 开发语言:C#
  • 实例大小:1.57M
  • 下载次数:170
  • 浏览次数:5551
  • 发布时间:2013-02-18
  • 实例类别:C#图形和图像处理
  • 发 布 人:chaogu
  • 文件格式:.rar
  • 所需积分:2
 相关标签: 验证码 OCR Tesseract

实例介绍

【实例简介】

具体实现思路:以4位数字的验证码为例
 
1、人工将验证码的4位数字每位对应的代码存入数据库中,每位存入0-9对应的代码,每个数可以多存这样可以提高识别率;
 
2、获取验证码以后,对其进行去背景、灰度处理、去噪点处理、分片处理以后生成每位数字对应的代码;
 
3、去背景色,这一步的目的是把验证码和背景颜色区别开来。
4、去噪声:这一步要取出图像上的孤立点。这些孤立点被认为是噪声。
  孤立点的定义:某个点,周围没有与该点等值的点。
  或者某个连接块,该连接块的元素的个数小于某个给定值K, 把元素个数很小的连接块也定义为孤立点,有助于去处噪声。
  去噪声算法:参照去背景算法。
 
5、图像锐化:图像锐化的目的是增强边界。这一步是可选的。看验证码的情况,这一步可以跳过。
 
6、图片有效区域截取:这个操作是将图片除验证码字符以外的边框去掉,只留下验证码字符图片,这样保证分片的准确性。
 
7、图片分片处理,这个处理是将整个图片分割成单个字符图片。
8、拿分片图像生成的代码(eg:000111110011…..)与DB中已有代码相比较,取得相似度最高的即要验证码的字符;
 
 
 
注:如果DB的样本越多,识别的准确率也越高,但是速度会相应变慢
【实例截图】


【核心代码】

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;

namespace GetCodes
{
    using System.Net;
    using System.IO;
    using System.Data.OleDb;
    using DotNet.Framework.Common.Algorithm;
    using System.Collections;

    public partial class GetCode : Form
    {
        OleDbConnection DbConn;
        OleDbCommand DbCmd;

        public GetCode()
        {
            InitializeComponent();
            DbConn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source="   Application.ExecutablePath.Substring(0, Application.ExecutablePath.LastIndexOf("\\"))   @"\code.mdb;");
            DbCmd = new OleDbCommand();

            try
            {
                DbConn.Open();
                DbCmd.Connection = this.DbConn;
            }
            catch (Exception e) { MessageBox.Show(e.ToString()); }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Bitmap bitmap1 = GetSourceCode(textBox1.Text);
            pbSource.Image = bitmap1;

            Bitmap bitmap = (Bitmap)bitmap1.Clone();
            UnCodebase ud = new UnCodebase(bitmap);
            bitmap = ud.GrayByPixels();
            if (cbquzao.Checked)
            {
                ud.ClearNoise(int.Parse(updgary.Value.ToString()), int.Parse(updmaxpoint.Value.ToString()));
                //bitmap = ClearNoise(bitmap, 128, 1);
            }
            bitmap = ud.ReSetBitMap();
            //bitmap = new UnCodebase(bitmap).ClearPicBorder(2);
            pbhuidu.Image = bitmap;

            bitmap = CutMap(bitmap);

            Bitmap[] arrmap = SplitImg(bitmap, 4, 1);

            DisplaySplitImg(arrmap);

            textBox6.Text = DrawCode(arrmap);


        }



        private void DisplaySplitImg(Bitmap[] arrmap)
        {
            for (int i = 0; i < arrmap.Length; i  )
            {
                foreach (Control item in groupbox1.Controls)
                {
                    if (item is PictureBox)
                    {
                        PictureBox p = item as PictureBox;
                        int index = i   1;
                        if (p.Name == "pb"   index)
                        {
                            p.Image = arrmap[i];
                            break;
                        }
                    }
                }
            }
        }

        private string DrawCode(Bitmap[] arrmap)
        {
            groupBox2.Controls.Clear();
            //groupBox2.Refresh();
            StringBuilder code = new StringBuilder();
            Panel p;
            string spchar = "=======";
            for (int i = 0; i < arrmap.Length; i  )
            {
                p = new Panel();
                p.BackColor = Color.White;
                p.Width = 100;
                p.Height = 100;
                p.Location = new Point(i * p.Width   10, 40);

                groupBox2.Controls.Add(p);
                if (i == arrmap.Length - 1)
                {
                    spchar = string.Empty;
                }
                code.Append(GetCodebybitmap(arrmap[i], p)   spchar);
            }
            return code.ToString();
        }

        /// <summary>
        /// 获取数字对应的二值化代码
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        private string GetCodebybitmap(Bitmap _bitmap, Panel p)
        {
            StringBuilder code = new StringBuilder();
            Graphics g = p.CreateGraphics();
            for (int i = 0; i < _bitmap.Width; i  )
            {
                for (int j = 0; j < _bitmap.Height; j  )
                {
                    int r = _bitmap.GetPixel(i, j).R;
                    if (r < 100)//常用的是灰度128
                    {
                        code.Append("1");
                        g.DrawString("-", new Font("宋体", 12), new SolidBrush(Color.Blue), new Rectangle(i * 5, j * 5, 12, 12));
                    }
                    else
                    {
                        code.Append("0");
                    }
                }
            }

            return code.ToString();

        }

        /// <summary>
        /// 切分图片
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <returns></returns>
        private Bitmap[] SplitImg(Bitmap _bitmap, int row, int col)
        {
            int singW = _bitmap.Width / row;
            int singH = _bitmap.Height / col;
            Bitmap[] arrmap = new Bitmap[row * col];
            Rectangle rect;
            for (int i = 0; i < col; i  )
            {
                for (int j = 0; j < row; j  )
                {
                    rect = new Rectangle(j * singW, i * singH, singW, singH);
                    arrmap[i * row   j] = _bitmap.Clone(rect, _bitmap.PixelFormat);
                }
            }

            return arrmap;
        }

        /// <summary>
        /// 得到图片有效区域,使切分图片更加精确
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        private Bitmap CutMap(Bitmap _bitmap)
        {
            Rectangle rg = new Rectangle(int.Parse(updX.Value.ToString()), int.Parse(updY.Value.ToString()), _bitmap.Width - int.Parse(updW.Value.ToString()), _bitmap.Height - int.Parse(updH.Value.ToString()));
            //Rectangle rg = new Rectangle(1, 0, _bitmap.Width - 10, _bitmap.Height );
            Bitmap bitmap = _bitmap.Clone(rg, _bitmap.PixelFormat);
            return bitmap;

        }

        private Bitmap GetSourceCode(string url)
        {
            WebRequest request = WebRequest.Create(url);
            WebResponse response = request.GetResponse();
            Stream st = response.GetResponseStream();
            Bitmap bitmap = (Bitmap)Bitmap.FromStream(st);
            //bitmap.Save(System.Windows.Forms.Application.StartupPath   @"\tmp.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
            //bitmap = (Bitmap)Bitmap.FromFile(System.Windows.Forms.Application.StartupPath   @"\tmp.bmp");
            return bitmap;
        }



        private void button2_Click(object sender, EventArgs e)
        {
            try
            {                           
                string[] arrv = textBox6.Text.Split(new string[] { "=======" }, StringSplitOptions.RemoveEmptyEntries);

                string sql = "insert into Codes(Keynum,CodeValue) values({0},'{1}')";

               
                if (!string.IsNullOrEmpty(txt1.Text))
                {
                    sql = "insert into Codes(Keynum,CodeValue) values({0},'{1}')";
                    sql = string.Format(sql, txt1.Text, arrv[0]);
                    DbCmd.CommandText = sql;
                    DbCmd.ExecuteNonQuery();
                }

                if (!string.IsNullOrEmpty(txt2.Text))
                {
                    sql = "insert into Codes(Keynum,CodeValue) values({0},'{1}')";
                    sql = string.Format(sql, txt2.Text, arrv[1]);
                    DbCmd.CommandText = sql;
                    DbCmd.ExecuteNonQuery();
                }

                if (!string.IsNullOrEmpty(txt3.Text))
                {
                    sql = "insert into Codes(Keynum,CodeValue) values({0},'{1}')";
                    sql = string.Format(sql, txt3.Text, arrv[2]);
                    DbCmd.CommandText = sql;
                    DbCmd.ExecuteNonQuery();
                }

                if (!string.IsNullOrEmpty(txt4.Text))
                {
                    sql = "insert into Codes(Keynum,CodeValue) values({0},'{1}')";
                    sql = string.Format(sql, txt4.Text, arrv[3]);
                    DbCmd.CommandText = sql;
                    DbCmd.ExecuteNonQuery();
                }

                txt1.Text = txt2.Text = txt3.Text = txt4.Text = string.Empty;
                //MessageBox.Show("入库成功");
                button1_Click(null, null);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            textBox6.Text = "";
            StringBuilder sb = new StringBuilder();
            button1_Click(null, null);
            string[] arrv = textBox6.Text.Split(new string[] { "=======" }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < arrv.Length; i  )
            {
                sb.Append(new Compar(arrv[i]).GetCode());
            }
            txtcode.Text = sb.ToString();
        }

        private void updW_ValueChanged(object sender, EventArgs e)
        {
            if (updW.Value < updX.Value)
            {
                MessageBox.Show("图片左边沿到第一个字的宽度不能小于X的值");
                updW.Value  ;
                return;
            }
        }
    }

    public class SingleCodes
    {
        private DataSet ds;
        OleDbConnection DbConn;
        OleDbCommand DbCmd;

        private void GetDS()
        {

            DbConn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source="   Application.ExecutablePath.Substring(0, Application.ExecutablePath.LastIndexOf("\\"))   @"\code.mdb;");
            DbCmd = new OleDbCommand();

            try
            {
                ds = new DataSet();
                DbConn.Open();
                DbCmd.Connection = this.DbConn;
                DbCmd.CommandText = "select * from Codes";
                OleDbDataAdapter adapter = new OleDbDataAdapter(DbCmd);
                adapter.Fill(ds);

            }
            catch (Exception e) { MessageBox.Show(e.ToString()); }
        }
        private SingleCodes()
        {
            GetDS();
        }
        public static SingleCodes Instance
        {
            get
            {
                return innerclass.instance;
            }
        }

        public DataTable DataTable
        {
            get
            {
                if (ds == null) GetDS();
                return ds.Tables[0];
            }
        }

        class innerclass
        {
            static innerclass() { }
            public static readonly SingleCodes instance = new SingleCodes();
        }
    }

    public class Compar
    {
        private string code01;
        SortedList sl;
        public Compar(string code01)
        {
            this.code01 = code01;
            sl = new SortedList();
        }

        public string GetCode()
        {
            LevenshteinDistance ld = new LevenshteinDistance();
            DataTable dt = SingleCodes.Instance.DataTable;
            string value = string.Empty;
            for (int i = 0; i < dt.Rows.Count; i  )
            {
                value = dt.Rows[i][2].ToString();
                decimal parent = ld.LevenshteinDistancePercent(value, code01);
                if (parent > 0.85m)
                {
                    if (!sl.ContainsKey(parent))
                    {
                        sl.Add(parent, dt.Rows[i][1]);
                    }
                }
            }

            return sl.GetByIndex(sl.Count - 1).ToString();
        }
    }
}

实例下载地址

C# 实现简单数字验证码解析(Tesseract OCR 解析验证码) 实例代码

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 xqbcy 发表于: 2015-11-06 10:19 18
我来说两句...

支持(0) 盖楼(回复)

第 2 楼 冯留杰 发表于: 2015-12-04 11:24 05
我来说两句...

支持(0) 盖楼(回复)

第 3 楼 收个四位数识别器 发表于: 2016-07-19 08:00 19
有现成的吗?

支持(0) 盖楼(回复)

第 4 楼 收个四位数识别器 发表于: 2016-07-19 08:00 31
有现成的吗?

支持(0) 盖楼(回复)

第 5 楼 刘宇 发表于: 2016-12-29 15:29 07
弄得是什么乱七八糟的

支持(0) 盖楼(回复)

第 6 楼 刘宇 发表于: 2016-12-29 15:29 11
弄得是什么乱七八糟的

支持(0) 盖楼(回复)

第 7 楼 刘宇 发表于: 2016-12-29 15:29 27
弄得是什么乱七八糟的能不能免费

支持(0) 盖楼(回复)

第 8 楼 刘宇 发表于: 2016-12-29 15:29 45
赶紧倒闭吧

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有8条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警