基本信息
源码名称:C# 实现简单数字验证码解析(Tesseract OCR 解析验证码) 实例代码
源码大小:1.57M
文件格式:.rar
开发语言:C#
更新时间:2013-02-18
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
具体实现思路:以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(); } } }