区域对比验证码识别,超级简单的Region对比识别验证码

来源:互联网 发布:剑网3萝莉捏脸数据 编辑:程序博客网 时间:2024/05/02 01:40

 在验证识别常用技巧之外,我们可以采用区域对比的方法进行验证码识别,对相对简单的验证码有效,如果由噪点的话可以现去噪点,然后再执行如下函数

 

在验证识别常用技巧之外,我们可以采用区域对比的方法进行验证码识别,对相对简单的验证码有效,如果由噪点的话可以现去噪点,然后再执行如下函数

在一些验证码相对简单的站点中,就是对于特定的字符,在生成时,其字符的Region应该是一样的,如图片

中的6总是这个字体这个字号......我们只须把验证码图片从左向右一列一列扫描,分隔出每个字符的RGN,然后和chars.bmp中的每个字符的RGN对比,就知道是哪个数字了。
   关键代码如下:

namespace WindowsApplication1{    public partial class Form1 : Form    {        IniFile config = null;        //查看两个颜色是不是一样,注意这里有一定误差也算相同        public bool IsSameColor(Color c1, Color c2)        {            if (Math.Abs(c1.R - c2.R) < 10                && Math.Abs(c1.G - c2.G) < 10                && Math.Abs(c1.B - c2.B) < 10)            {                return true;            }            else            {                return false;            }        }        //计算一个Region中,像素的个数        public int RegionPointCount(Region r,int width,int height)        {             int count = 0;            for(int h = 0; h<width; ++h)            {                for(int v = 0; v< height; ++v)                {                    if(r.IsVisible(h,v))                    {                        ++count;                    }                }            }            return count;        }                //初始化每个字符的Region        public void InitPictureCharInfo()        {            Bitmap bmp = (Bitmap)Bitmap.FromFile("chars.bmp");            List<BitmapCharInfo> bcil = charRgnList;            Region rgn = new Region();            rgn.MakeEmpty();            if (bmp.Height > 0 && bmp.Width > 0)            {                Color bkColor = bmp.GetPixel(0, 0);                bool bInWorking = false;                int nNextStartPos = 0;                for (int h = 0; h < bmp.Width; ++h)                {                    bool bFindColor = false;                    for (int v = 0; v < bmp.Height; ++v)                    {                        if (!IsSameColor(bkColor, bmp.GetPixel(h, v)))                        {                            rgn.Union(new Rectangle(h, v, 1, 1));                            bFindColor = true;                        }                    }                    if (bInWorking)                    {                        if (!bFindColor)                        {                            bInWorking = false;                            rgn.Translate(-nNextStartPos, 0);                            BitmapCharInfo bci = new BitmapCharInfo(rgn, h - nNextStartPos, bmp.Height);                            bci.orgPos = nNextStartPos;                            bcil.Add(bci);                            rgn = new Region();                            rgn.MakeEmpty();                        }                    }                    else                    {                        if (bFindColor)                        {                            bInWorking = true;                            nNextStartPos = h;                        }                    }                }                chars.AddRange("0123456789".ToCharArray());            }        }        //扫描并识别验证码        public void ScanValidCode()        {            Bitmap bmp = this.bmpValidCode;            List<BitmapCharInfo> bcil = new List<BitmapCharInfo>();            Region rgn = new Region();            rgn.MakeEmpty();            if (bmp.Height > 0 && bmp.Width > 0)            {                Color bkColor = bmp.GetPixel(0, 0);                bool bInWorking = false;                int nNextStartPos = 0;                for (int h = 0; h < bmp.Width; ++h)                {                    bool bFindColor = false;                    for (int v = 0; v < bmp.Height; ++v)                    {                        if (!IsSameColor(bkColor, bmp.GetPixel(h, v)))                        {                            rgn.Union(new Rectangle(h, v, 1, 1));                            bFindColor = true;                        }                    }                    if (bInWorking)                    {                        if (!bFindColor)                        {                            bInWorking = false;                            rgn.Translate(-nNextStartPos, 0);                            BitmapCharInfo bci = new BitmapCharInfo(rgn, h - nNextStartPos, bmp.Height);                            bci.orgPos = nNextStartPos;                            bcil.Add(bci);                            rgn = new Region();                            rgn.MakeEmpty();                        }                    }                    else                    {                        if (bFindColor)                        {                            bInWorking = true;                            nNextStartPos = h;                        }                    }                }                List<char> chs = new List<char>();                Graphics gh = Graphics.FromImage(bmp);                foreach (BitmapCharInfo bci in bcil)                {                    int minPos = -1;                    int minLng = -1;                    for (int i = 0; i < charRgnList.Count; ++i)                    {                        Region r = bci.rgn.Clone();                        r.Union(charRgnList[i].rgn);                        r.Exclude(bci.rgn);                        int lng = RegionPointCount(r, bci.width, bci.height);                        if (minLng == -1)                        {                            minLng = lng;                            minPos = i;                        }                        else                        {                            if (lng < minLng)                            {                                minLng = lng;                                minPos = i;                            }                        }                    }                    if (minPos != -1)                    {                        chs.Add(chars[minPos]);                    }                }                string str = new string(chs.ToArray(), 0, chs.Count);                //MessageBox.Show(str);                this.currScanValidCode = str;            }        }        public void GetValidCodePicture(CookieContainer cc, WebProxy wp )        {             //this.pbValidCode.ImageLocation = this.pbValidCode.ImageLocation;            Exception exp = null;            for (int i = 0; i < 3; ++i)            {                try                {                    Stream s = GetDataNonProxy(this.tbValidPicUrl.Text, cc,wp);                    Bitmap bmp = (Bitmap)Bitmap.FromStream(s);                    s.Close();                    bmpValidCode = bmp;                    return;                }                catch (Exception ex)                {                    exp = ex;                }            }                    MessageBox.Show("猎取图片失败:" + exp == null?"unkown":exp.Message);        }        Bitmap bmpValidCode = null;        private void btnLoadPic_Click(object sender, EventArgs e)        {            this.GetValidCodePicture(null,null);            currValidCode = this.currScanValidCode;            this.UpdateDate(false);        }        List<BitmapCharInfo> charRgnList = new List<BitmapCharInfo>();        List<char> chars = new List<char>();        private void btnInit_Click(object sender, EventArgs e)        {            InitPictureCharInfo();        }        private void btnScanValidCode_Click(object sender, EventArgs e)        {            ScanValidCode();            this.currValidCode = this.currScanValidCode;            this.UpdateDate(false);        }                string currScanValidCode;                                      private void Form1_Load(object sender, EventArgs e)        {            this.UpdateDate(true);            InitPictureCharInfo();            config = new IniFile(Application.ExecutablePath + ".ini");            lastPwdPosInDict = config.GetInt("Process", "PwdPostion", 0);            InitPwdDict();            UpdateProcessText();        }    }    public class BitmapCharInfo     {        public BitmapCharInfo()        {            this.rgn = new Region();            this.rgn.MakeEmpty();        }        public BitmapCharInfo(Region r, int w, int h)        {            this.rgn = r;            this.width = w;            this.height = h;        }        public Region rgn;        public int width = 0;        public int height = 0;        public int orgPos = 0;    }}


 识别效率提高的,但是局限性太高了。现在这类我网站也少得多了,现在放出来。希望抛砖引玉引出图形的高级算法来。