实例介绍
【实例简介】
具体实现思路:以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(); } } }
网友评论
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)