验证码识别基本原理

验证码识别基础基本原理,

一个同事在闲聊的时候提起验证码这个问题,他说他写个自动登录程序用来自动签到.说在输入验证码的问题上出了点问题,然后我就想试着写个识别验证码的东东,写的不好,请大家多多指教,验证码是我在网上找的一种比较简单的一种,只有26个字母区分大小写,和10个数字组成、字体没有变形、有噪声低等等一些干扰的东西,(如图:           )想想只是实现其基本原理没有就没有搞得太复杂。

经过分析首先我把我要做的分了几个步骤:

第一:把图片灰度处理;(具体为何要先对图片灰度呢,我也不知道,我看好这种操作都现灰度一下,所有我也就先灰度了一下。)

第二:把图片阈值处理,也就是普通所说的二化值处理;(这个操作会使图片中的只存在两种颜色,就是黑和白。)

第三:去边框;(因为这种验证码有边框,所有我就去掉了。)

第四:去除噪点;(噪声点是没有用的孤立的单个像素点,如果不去除的话对验证码的识别能力有影响。)

第五:有效区域分割;(不分割图片图片的话,单个字符的识别能力就会让人很纠结。)

第六:把有效区域存储起来;(存储起来是为了以后在识别验证码的时候进行比对);

以上几个步骤是用来培养验证码的识别能力的;对验证码识别能力的培养是不可缺少的,培养的好的话,识别能力就高

第七步:就是对验证码的识别了,对图片处理重复1到5个步骤,然后把分割的图片和之前存储的图片的信息进行比对如果相同那么就是该字符了,识别成功;嘿嘿。。。。说起来挺简单的,但是我做了整整一天才搞明白,因为我是菜鸟,嘿嘿嘿。。。。。。。

下边我要做的是新建项目(我选择了Winform,),然后添加一个处理图片的类、和存储图片信息对象的类、还有就是一个属性类(这个在分割图片的时候我会用到,当然你也可以用其他的方法),就是这样子:

 

图片处理类里面的代码是这样子写的:

ImageMap.cs文件代码

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Drawing;

using System.IO;

using System.Runtime.Serialization.Formatters.Binary;

using System.Text.RegularExpressions;

namespace VCodeID

{

    public class ImageMap

    {

        /// <summary>

        /// 图片全局容器

        /// </summary>

        public Bitmap bm;

        /// <summary>

        /// 图片分割后的容器

        /// </summary>

        Bitmap[] bs;

        /// <summary>

        /// 验证码特征对象

        /// </summary>

        ABC code = new ABC();

        /// <summary>

        /// 验证码容器

        /// </summary>

        string s = "";

        public ImageMap() { }

        /// <summary>

        /// 设置图片灰度

        /// </summary>

        /// <returns>处理后的图片</returns>

        public Bitmap huidu()

        {

            for (int i = 0; i < bm.Height; i++)

            {

                for (int j = 0; j < bm.Width; j++)

                {

                    int tmpValue = GetGrayNumColor(bm.GetPixel(j, i));

                    bm.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));

                }

            }

            return bm;

        }

        /// <summary>

        /// 设置图片灰度

        /// </summary>

        /// <param name="b">要处理成灰度的图片</param>

        /// <returns>处理后的图片</returns>

        public Bitmap huidu(Bitmap b)

        {

            for (int i = 0; i < b.Height; i++)

            {

                for (int j = 0; j < b.Width; j++)

                {

                    int tmpValue = GetGrayNumColor(b.GetPixel(j, i));

                    b.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));

                }

            }

            return b;

        }

        /// <summary>

        /// 根据RGB,计算灰度值

        /// </summary>

        /// <param name="color">Color值</param>

        /// <returns>灰度值,整形</returns>

        private int GetGrayNumColor(System.Drawing.Color posClr)

        {

            return (posClr.R * 19595 + posClr.G * 38469 + posClr.B * 7472) >> 16;

        }

        /// <summary>

        /// 阈值处理

        /// </summary>

        /// <param name="er">阈值</param>

        public Bitmap yuzhi(int er)

        {

            Color ColorOrigin = new Color();//定义一个色彩变量对象

            double Red, Green, Blue, Y; //定义红、绿、蓝三色和亮度

            for (int i = 0; i <= bm.Width - 1; i++)

            {

                for (int j = 0; j <= bm.Height - 1; j++)//循环处理图像中的每一个像素点

                {

                    ColorOrigin = bm.GetPixel(i, j); //获取当前像素点的色彩信息

                    Red = ColorOrigin.R; //获取当前像素点的红色分量

                    Green = ColorOrigin.G; //获取当前像素点的绿色分量

                    Blue = ColorOrigin.B; //获取当前像素点的蓝色分量

                    Y = 0.59 * Red + 0.3 * Green + 0.11 * Blue; //计算当前像素点的亮度

                    if (Y > er) //如果当前像素点的亮度大于指定阈值

                    {

                        Color ColorProcessed = Color.FromArgb(255, 255, 255); //那么定义一个纯白的色彩变量,即各分量均为255

                        bm.SetPixel(i, j, ColorProcessed); //将白色变量赋给当前像素点

                    }

                    if (Y <= er) //如果当前像素点的亮度小于指定阈值

                    {

                        Color ColorProcessed = Color.FromArgb(0, 0, 0); //那么定义一个纯黑的色彩变量,即各分量均为0

                        bm.SetPixel(i, j, ColorProcessed); //将黑色变量赋给当前像素点

                    }

                }

            }

            return bm;

        }

        /// <summary>

        /// 去掉边框

        /// </summary>

        /// <param name="w">边框的像素值</param>

        /// <returns>去掉边框后的图片</returns>

        public Bitmap qubian(int w)

        {

            for (int i = 0; i < bm.Height; i++)

            {

                for (int j = 0; j < bm.Width; j++)

                {

                    if (i < w || j < w || j > bm.Width - 1 - w || i > bm.Height - 1 - w)

                        bm.SetPixel(j, i, Color.FromArgb(255, 255, 255));

                }

            }

            bm.MakeTransparent(Color.White);

            return bm;

        }

        /// <summary>

        /// 去除噪点

        /// </summary>

        /// <returns>去掉噪点后的图片</returns>

        public Bitmap zaodian()

        {

            bm.MakeTransparent(Color.White);

            for (int i = 2; i < bm.Width - 2; i++)

            {

                for (int j = 2; j < bm.Height - 2; j++)

                {

                    if (Color.Black.A == bm.GetPixel(i, j).A)

                    {

                        //选择黑点

                        if (bm.GetPixel(i - 1, j - 1).A.ToString() == "0" && bm.GetPixel(i, j - 1).A.ToString() == "0" && bm.GetPixel(i + 1, j - 1).A.ToString() == "0" && bm.GetPixel(i - 1, j).A.ToString() == "0" && bm.GetPixel(i + 1, j).A.ToString() == "0" && bm.GetPixel(i - 1, j + 1).A.ToString() == "0" && bm.GetPixel(i, j + 1).A.ToString() == "0" && bm.GetPixel(i + 1, j + 1).A.ToString() == "0")

                        {

                            //如果一圈都是白的,就将他设置为白的

                            bm.SetPixel(i, j, Color.White);

                        }

                    }

                }

            }

            //bm.MakeTransparent(Color.White);

            return bm;

        }

        /// <summary>

        /// 图片分割

        /// </summary>

        /// <returns>返回分割后的图片集合</returns>

        public Bitmap[] fengeyouxiaotupian()

        {

            StringBuilder sb = new StringBuilder();

            List<canshu> lsz = new List<canshu>();

            for (int i = 0; i < bm.Width; i++)

            {

                string k = "";

                for (int j = 0; j < bm.Height; j++)

                {

                    k += bm.GetPixel(i, j).A.ToString();

                }

                //是否有黑点

                if (k.Contains("255"))

                {

                    //有黑点

                    sb.Append(1);

                }

                else

                {

                    //无黑点

                    sb.Append(0);

                }

            }

            //开始计算所要截取的坐标

            bool b = true;//是否记录初始值

            int one = 0;//初始横坐标

            int next = 0;//接受横坐标

            for (int i = 0; i < bm.Width; i++)

            {

                if (sb.ToString().Substring(i, 1) == "1")

                {

                    //遇见1

                    if (b)

                    {

                        //第一次可以见到

                        b = false;

                        one = i;//记录初始坐标

                    }

                    if (sb.ToString().Substring(i + 1, 1) == "0")

                    {

                        //已经是1的终点

                        next = i;

                        //开始截取

                        canshu sss = new canshu() { X = one, W = next - one, };

                        lsz.Add(sss);

                    }

                }

                else

                {

                    //遇见0

                    b = true;//初始化开始记录值

                }

            }

            bs = jiequ(bm, lsz.ToArray());

            return bs;

        }

        /// <summary>

        /// 返回分割图片

        /// </summary>

        /// <param name="b">要分割的图片</param>

        /// <param name="s">分割参数</param>

        /// <returns></returns>

        Bitmap[] jiequ(Bitmap b, canshu[] s)

        {

            Bitmap[] bs = new Bitmap[s.Count()];

            for (int q = 0; q < s.Count(); q++)

            {

                Bitmap bb = new Bitmap(s[q].W, b.Height);

                for (int i = s[q].X; i < s[q].X + s[q].W; i++)

                {

                    for (int j = 0; j < b.Height; j++)

                    {

                        bb.SetPixel(i - s[q].X, j, b.GetPixel(i, j));

                    }

                }

                bs[q] = bb;

            }

            return bs;

        }

        /// <summary>

        /// 获取单个验证码特征所对应的验证码

        /// </summary>

        /// <param name="k">验证码特征</param>

        /// <returns>验证码</returns>

        public string Code(string k)

        {

            code = null;

            if (!File.Exists("kxcxc.dat"))

            {

                return null;

            }

            using (FileStream fs = new FileStream("kxcxc.dat", FileMode.Open, FileAccess.Read))

            {

                BinaryFormatter format = new BinaryFormatter();

                code = (ABC)format.Deserialize(fs);

            }

            if (Regex.IsMatch(code.Wa, k, RegexOptions.IgnoreCase)) { return "a"; }

            if (Regex.IsMatch(code.Wb, k, RegexOptions.IgnoreCase)) { return "b"; }

            if (Regex.IsMatch(code.Wc, k, RegexOptions.IgnoreCase)) { return "c"; }

            if (Regex.IsMatch(code.Wd, k, RegexOptions.IgnoreCase)) { return "d"; }

            if (Regex.IsMatch(code.We, k, RegexOptions.IgnoreCase)) { return "e"; }

            if (Regex.IsMatch(code.Wf, k, RegexOptions.IgnoreCase)) { return "f"; }

            if (Regex.IsMatch(code.Wg, k, RegexOptions.IgnoreCase)) { return "g"; }

            if (Regex.IsMatch(code.Wh, k, RegexOptions.IgnoreCase)) { return "h"; }

            if (Regex.IsMatch(code.Wi, k, RegexOptions.IgnoreCase)) { return "i"; }

            if (Regex.IsMatch(code.Wj, k, RegexOptions.IgnoreCase)) { return "j"; }

            if (Regex.IsMatch(code.Wk, k, RegexOptions.IgnoreCase)) { return "k"; }

            if (Regex.IsMatch(code.Wl, k, RegexOptions.IgnoreCase)) { return "l"; }

            if (Regex.IsMatch(code.Wm, k, RegexOptions.IgnoreCase)) { return "m"; }

            if (Regex.IsMatch(code.Wn, k, RegexOptions.IgnoreCase)) { return "n"; }

            if (Regex.IsMatch(code.Wo, k, RegexOptions.IgnoreCase)) { return "o"; }

            if (Regex.IsMatch(code.Wp, k, RegexOptions.IgnoreCase)) { return "p"; }

            if (Regex.IsMatch(code.Wq, k, RegexOptions.IgnoreCase)) { return "q"; }

            if (Regex.IsMatch(code.Wr, k, RegexOptions.IgnoreCase)) { return "r"; }

            if (Regex.IsMatch(code.Ws, k, RegexOptions.IgnoreCase)) { return "s"; }

            if (Regex.IsMatch(code.Wt, k, RegexOptions.IgnoreCase)) { return "t"; }

            if (Regex.IsMatch(code.Wu, k, RegexOptions.IgnoreCase)) { return "u"; }

            if (Regex.IsMatch(code.Wv, k, RegexOptions.IgnoreCase)) { return "v"; }

            if (Regex.IsMatch(code.Ww, k, RegexOptions.IgnoreCase)) { return "w"; }

            if (Regex.IsMatch(code.Wx, k, RegexOptions.IgnoreCase)) { return "x"; }

            if (Regex.IsMatch(code.Wy, k, RegexOptions.IgnoreCase)) { return "y"; }

            if (Regex.IsMatch(code.Wz, k, RegexOptions.IgnoreCase)) { return "z"; }

            if (Regex.IsMatch(code.W0, k, RegexOptions.IgnoreCase)) { return "0"; }

            if (Regex.IsMatch(code.W1, k, RegexOptions.IgnoreCase)) { return "1"; }

            if (Regex.IsMatch(code.W2, k, RegexOptions.IgnoreCase)) { return "2"; }

            if (Regex.IsMatch(code.W3, k, RegexOptions.IgnoreCase)) { return "3"; }

            if (Regex.IsMatch(code.W4, k, RegexOptions.IgnoreCase)) { return "4"; }

            if (Regex.IsMatch(code.W5, k, RegexOptions.IgnoreCase)) { return "5"; }

            if (Regex.IsMatch(code.W6, k, RegexOptions.IgnoreCase)) { return "6"; }

            if (Regex.IsMatch(code.W7, k, RegexOptions.IgnoreCase)) { return "7"; }

            if (Regex.IsMatch(code.W8, k, RegexOptions.IgnoreCase)) { return "8"; }

            if (Regex.IsMatch(code.W9, k, RegexOptions.IgnoreCase)) { return "9"; }

            return null;

        }

        /// <summary>

        /// 获取验证码的特特

        /// </summary>

        /// <param name="danbm"></param>

        /// <returns></returns>

        public string yanzhengmtezheng(Bitmap danbm)

        {

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < danbm.Width; i++)

            {

                for (int j = 0; j < danbm.Height; j++)

                {

                    sb.Append(danbm.GetPixel(i, j).A.ToString() == "255" ? 1 : 0);

                }

            }

            return ZIP(sb.ToString());

        }

        /// <summary>

        /// 压缩特征

        /// </summary>

        /// <param name="sb"></param>

        /// <returns></returns>

        private string ZIP(string sb)

        {

            StringBuilder s = new StringBuilder();

            string[] ss = sb.Replace("01", "0*1").Replace("10", "1*0").Split('*');

            for (int i = 0; i < ss.Count(); i++)

            {

                if (ss[i].Contains("1"))

                {

                    s.Append("1x" + ss[i].Count());

                }

                else

                {

                    s.Append("0x" + ss[i].Count());

                }

            }

            return s.ToString();

        }

        /// <summary>

        /// 获取验证码

        /// </summary>

        /// <returns></returns>

        public string huoquyanzhengma()

        {

          

            for (int i = 0; i < bs.Count(); i++)

            {

                string key = yanzhengmtezheng(bs[i]);

                s += Code(key);

            }

            return s;

        }

    }

}

ABC.cs文件代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace VCodeID

{

    [Serializable]

    public class ABC

    {

        string wa;

 

        public string Wa

        {

            get { return wa; }

            set { wa = value; }

        }

        string wb;

 

        public string Wb

        {

            get { return wb; }

            set { wb = value; }

        }

        string wc;

 

        public string Wc

        {

            get { return wc; }

            set { wc = value; }

        }

        string wd;

 

        public string Wd

        {

            get { return wd; }

            set { wd = value; }

        }

        string we;

 

        public string We

        {

            get { return we; }

            set { we = value; }

        }

        string wf;

 

        public string Wf

        {

            get { return wf; }

            set { wf = value; }

        }

        string wg;

 

        public string Wg

        {

            get { return wg; }

            set { wg = value; }

        }

        string wh;

 

        public string Wh

        {

            get { return wh; }

            set { wh = value; }

        }

        string wi;

 

        public string Wi

        {

            get { return wi; }

            set { wi = value; }

        }

        string wj;

 

        public string Wj

        {

            get { return wj; }

            set { wj = value; }

        }

        string wk;

 

        public string Wk

        {

            get { return wk; }

            set { wk = value; }

        }

        string wl;

 

        public string Wl

        {

            get { return wl; }

            set { wl = value; }

        }

        string wm;

 

        public string Wm

        {

            get { return wm; }

            set { wm = value; }

        }

        string wn;

 

        public string Wn

        {

            get { return wn; }

            set { wn = value; }

        }

        string wo;

 

        public string Wo

        {

            get { return wo; }

            set { wo = value; }

        }

        string wp;

 

        public string Wp

        {

            get { return wp; }

            set { wp = value; }

        }

        string wq;

 

        public string Wq

        {

            get { return wq; }

            set { wq = value; }

        }

        string wr;

 

        public string Wr

        {

            get { return wr; }

            set { wr = value; }

        }

        string ws;

 

        public string Ws

        {

            get { return ws; }

            set { ws = value; }

        }

        string wt;

 

        public string Wt

        {

            get { return wt; }

            set { wt = value; }

        }

        string wu;

 

        public string Wu

        {

            get { return wu; }

            set { wu = value; }

        }

        string wv;

 

        public string Wv

        {

            get { return wv; }

            set { wv = value; }

        }

        string ww;

 

        public string Ww

        {

            get { return ww; }

            set { ww = value; }

        }

        string wx;

 

        public string Wx

        {

            get { return wx; }

            set { wx = value; }

        }

        string wy;

 

        public string Wy

        {

            get { return wy; }

            set { wy = value; }

        }

        string wz;

 

        public string Wz

        {

            get { return wz; }

            set { wz = value; }

        }

        string w0;

 

        public string W0

        {

            get { return w0; }

            set { w0 = value; }

        }

        string w1;

 

        public string W1

        {

            get { return w1; }

            set { w1 = value; }

        }

        string w2;

 

        public string W2

        {

            get { return w2; }

            set { w2 = value; }

        }

        string w3;

 

        public string W3

        {

            get { return w3; }

            set { w3 = value; }

        }

        string w4;

 

        public string W4

        {

            get { return w4; }

            set { w4 = value; }

        }

        string w5;

 

        public string W5

        {

            get { return w5; }

            set { w5 = value; }

        }

        string w6;

 

        public string W6

        {

            get { return w6; }

            set { w6 = value; }

        }

        string w7;

 

        public string W7

        {

            get { return w7; }

            set { w7 = value; }

        }

        string w8;

 

        public string W8

        {

            get { return w8; }

            set { w8 = value; }

        }

        string w9;

 

        public string W9

        {

            get { return w9; }

            set { w9 = value; }

        }

    }

}

 

Canshu.cs代码是:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace VCodeID

{

    /// <summary>

    /// 分割参数

    /// </summary>

    class canshu

    {

        int x;

 

        public int X

        {

            get { return x; }

            set { x = value; }

        }

        int w;

 

        public int W

        {

            get { return w; }

            set { w = value; }

        }

    }

}

 

Form1.cs代码:

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.IO;

using System.Runtime.Serialization.Formatters.Binary;

 

namespace VCodeID

{

    public partial class Form1 : Form

    {

 

        /// <summary>

        /// 图ª?片?文?件t路¡¤径?集¡¥合?

        /// </summary>

        List<string> imgs = new List<string>();

 

        ImageMap IM = new ImageMap();

 

        int s = 1;

 

        public Form1()

        {

            InitializeComponent();

        }

 

        /// <summary>

        /// 窗ä¡ã体¬?加¨®载?

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void Form1_Load(object sender, EventArgs e)

        {

            imgs = Directory.GetFiles("img/").ToList();

            pictureBox1.Image = new Bitmap(imgs[0]);

            IM.bm = (Bitmap)pictureBox1.Image;

        }

 

       

        /// <summary>

        /// 刷¡é新?图ª?片?

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button1_Click(object sender, EventArgs e)

        {

            if (s >= imgs.Count) s = 0;

            pictureBox1.Image = new Bitmap(imgs[s]);

            s++;

            IM.bm = (Bitmap)pictureBox1.Image;

        }

 

        /// <summary>

        /// 图ª?象¨®灰¨°度¨¨处ä|理¤¨ª

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button2_Click(object sender, EventArgs e)

        {

 

            pictureBox2.Image = IM.huidu();

        }

 

        /// <summary>

        /// 图ª?片?阈D值¦Ì处ä|理¤¨ª

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button3_Click(object sender, EventArgs e)

        {

            pictureBox3.Image = IM.yuzhi(145);

        }

 

        /// <summary>

        /// 去¨£¤边À?框¨°

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button4_Click(object sender, EventArgs e)

        {

            pictureBox4.Image = IM.qubian(2);

        }

 

        /// <summary>

        /// 去¨£¤除y噪?点Ì?

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button5_Click(object sender, EventArgs e)

        {

            pictureBox5.Image = IM.zaodian();

        }

 

        /// <summary>

        /// 图ª?片?分¤?割?

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button6_Click(object sender, EventArgs e)

        {

            #region 初?始º?化¡¥按ã¡ä钮£¤及¡ã输º?入¨?框¨°状Á¡ä态¬?

            button9.BackColor = Color.Red;

            button10.BackColor = Color.Red;

            button11.BackColor = Color.Red;

            button12.BackColor = Color.Red;

            txt1.Text = "";

            txt2.Text = "";

            txt3.Text = "";

            txt4.Text = "";

            #endregion

 

            Bitmap[] bm = IM.fengeyouxiaotupian();

            for (int i = 0; i < bm.Count(); i++)

            {

                if (i.ToString() == "0")

                {

                    pictureBox6.Image = (Image)bm[i];

                    string c = IM.yanzhengmtezheng(new Bitmap(pictureBox6.Image));

                    txt1.Text = IM.Code(c);

                }

                else if (i.ToString() == "1")

                {

                    pictureBox7.Image = (Image)bm[i];

                    string c = IM.yanzhengmtezheng(new Bitmap(pictureBox7.Image));

                    txt2.Text = IM.Code(c);

                }

                else if (i.ToString() == "2")

                {

                    pictureBox8.Image = (Image)bm[i];

                    string c = IM.yanzhengmtezheng(new Bitmap(pictureBox8.Image));

                    txt3.Text = IM.Code(c);

                }

                else if (i.ToString() == "3")

                {

                    pictureBox9.Image = (Image)bm[i];

                    string c = IM.yanzhengmtezheng(new Bitmap(pictureBox9.Image));

                    txt4.Text = IM.Code(c);

                }

            }

        }

 

        /// <summary>

        /// 保À¡ê存ä?图ª?片?信?息¡é

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button7_Click(object sender, EventArgs e)

        {

 

        }

 

        /// <summary>

        /// 1

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button9_Click(object sender, EventArgs e)

        {

            string code = txt1.Text.Trim();

            if (code.Length < 1) { MessageBox.Show("请?输º?入¨?"); return; }

            string c = IM.yanzhengmtezheng(new Bitmap(pictureBox6.Image));//验¨¦证¡è码?特¬?征¡Â

            AddCode(code, c);

            button9.BackColor = Color.Green;

 

        }

 

        /// <summary>

        /// 2

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button10_Click(object sender, EventArgs e)

        {

            string code = txt2.Text.Trim();

            if (code.Length < 1) { MessageBox.Show("请?输º?入¨?"); return; }

            string c = IM.yanzhengmtezheng(new Bitmap(pictureBox7.Image));//验¨¦证¡è码?特¬?征¡Â

            AddCode(code, c);

            button10.BackColor = Color.Green;

        }

 

        /// <summary>

        /// 3

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button11_Click(object sender, EventArgs e)

        {

            string code = txt3.Text.Trim();

            if (code.Length < 1) { MessageBox.Show("请?输º?入¨?"); return; }

            string c = IM.yanzhengmtezheng(new Bitmap(pictureBox8.Image));//验¨¦证¡è码?特¬?征¡Â

            AddCode(code, c);

            button11.BackColor = Color.Green;

        }

 

        /// <summary>

        /// 4

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button12_Click(object sender, EventArgs e)

        {

            string code = txt4.Text.Trim();

            if (code.Length < 1) { MessageBox.Show("请?输º?入¨?"); return; }

            string c = IM.yanzhengmtezheng(new Bitmap(pictureBox9.Image));//验¨¦证¡è码?特¬?征¡Â

            AddCode(code, c);

            button12.BackColor = Color.Green;

        }

 

        /// <summary>

        /// 添¬¨ª加¨®验¨¦证¡è码?特¬?征¡Â

        /// </summary>

        /// <param name="code"></param>

        private void AddCode(string code, string codetz)

        {

            ABC kxc = new ABC() { W0 = "", W1 = "", W2 = "", W3 = "", W4 = "", W5 = "", W6 = "", W7 = "", W8 = "", W9 = "", Wa = "", Wb = "", Wc = "", Wd = "", We = "", Wf = "", Wg = "", Wh = "", Wi = "", Wj = "", Wk = "", Wl = "", Wm = "", Wn = "", Wo = "", Wp = "", Wq = "", Wr = "", Ws = "", Wt = "", Wu = "", Wv = "", Ww = "", Wx = "", Wy = "", Wz = "" };

 

            //如¨?果?文?件t不?存ä?在¨²则¨°床ä2此ä?文?件t

            if (!File.Exists("kxcxc.dat"))

            {

                using (FileStream fs = new FileStream("kxcxc.dat", FileMode.Create, FileAccess.Write))

                {

                    BinaryFormatter format = new BinaryFormatter();

                    format.Serialize(fs, kxc);

                }

            }

 

            //添¬¨ª加¨®验¨¦证¡è码?特¬?征¡Â;ê?

            using (FileStream fs = new FileStream("kxcxc.dat", FileMode.Open, FileAccess.Read))

            {

                BinaryFormatter format = new BinaryFormatter();

                kxc = (ABC)format.Deserialize(fs);

            }

 

            switch (code)

            {

                #region MyRegion

 

                case "a":

                    kxc.Wa = kxc.Wa + codetz;

                    break;

                case "b":

                    kxc.Wb = kxc.Wb + codetz;

                    break;

                case "c":

                    kxc.Wc = kxc.Wc + codetz;

                    break;

                case "d":

                    kxc.Wd = kxc.Wd + codetz;

                    break;

                case "e":

                    kxc.We = kxc.We + codetz;

                    break;

                case "f":

                    kxc.Wf = kxc.Wf + codetz;

                    break;

                case "g":

                    kxc.Wg = kxc.Wg + codetz;

                    break;

                case "h":

                    kxc.Wh = kxc.Wh + codetz;

                    break;

                case "i":

                    kxc.Wi = kxc.Wi + codetz;

                    break;

                case "j":

                    kxc.Wj = kxc.Wi + codetz;

                    break;

                case "k":

                    kxc.Wk = kxc.Wk + codetz;

                    break;

                case "l":

                    kxc.Wl = kxc.Wl + codetz;

                    break;

                case "m":

                    kxc.Wm = kxc.Wm + codetz;

                    break;

                case "n":

                    kxc.Wn = kxc.Wn + codetz;

                    break;

                case "o":

                    kxc.Wo = kxc.Wo + codetz;

                    break;

                case "p":

                    kxc.Wp = kxc.Wp + codetz;

                    break;

                case "q":

                    kxc.Wq = kxc.Wq + codetz;

                    break;

                case "r":

                    kxc.Wr = kxc.Wr + codetz;

                    break;

                case "s":

                    kxc.Ws = kxc.Ws + codetz;

                    break;

                case "t":

                    kxc.Wt = kxc.Wt + codetz;

                    break;

                case "u":

                    kxc.Wu = kxc.Wu + codetz;

                    break;

                case "v":

                    kxc.Wv = kxc.Wv + codetz;

                    break;

                case "w":

                    kxc.Ww = kxc.Ww + codetz;

                    break;

                case "x":

                    kxc.Wx = kxc.Wx + codetz;

                    break;

                case "y":

                    kxc.Wy = kxc.Wy + codetz;

                    break;

                case "z":

                    kxc.Wz = kxc.Wz + codetz;

                    break;

                case "0":

                    kxc.W0 = kxc.W0 + codetz;

                    break;

                case "1":

                    kxc.W1 = kxc.W1 + codetz;

                    break;

                case "2":

                    kxc.W2 = kxc.W2 + codetz;

                    break;

                case "3":

                    kxc.W3 = kxc.W3 + codetz;

                    break;

                case "4":

                    kxc.W4 = kxc.W4 + codetz;

                    break;

                case "5":

                    kxc.W5 = kxc.W5 + codetz;

                    break;

                case "6":

                    kxc.W6 = kxc.W6 + codetz;

                    break;

                case "7":

                    kxc.W7 = kxc.W7 + codetz;

                    break;

                case "8":

                    kxc.W8 = kxc.W8 + codetz;

                    break;

                case "9":

                    kxc.W9 = kxc.W9 + codetz;

                    break;

                default:

                    MessageBox.Show("有®D错䨪");

                    break;

                #endregion

            }

 

            //保À¡ê存ä?特¬?征¡Â

 

            using (FileStream fs = new FileStream("kxcxc.dat", FileMode.Create, FileAccess.Write))

            {

                BinaryFormatter format = new BinaryFormatter();

                format.Serialize(fs, kxc);

            }

        }

 

        /// <summary>

        /// 识º?别Àe验¨¦证¡è码?

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button8_Click(object sender, EventArgs e)

        {

            ImageMap I = new ImageMap();

            I.bm = new Bitmap(pictureBox1.Image);

            I.huidu();

            I.yuzhi(145);

            I.qubian(2);

            I.zaodian();

            I.fengeyouxiaotupian();

            textBox1.Text = I.huoquyanzhengma();

        }

    }

}

 

操作界面:

 

培养验证码的识别能力是一个体力活,做过的都知道,我培养了近2000多张识别能力还是很低,也许是我在处理图片的时候处理的不是太好,

(

如果你想用这个套方案去识别一些复杂一点的验证码,这是肯定不行的,

)

我是菜鸟,还请高手留下宝贵意见,

源码下载地址:http://download.csdn.net/detail/u014265946/7078911

Web工具箱

原文地址:https://www.cnblogs.com/simoncai/p/3012523.html