• 超级简单的Region对比识别验证码


      在一些验证码相对简单的站点中,停一下,什么是简单?以我现在的图形算法修为,就是对于特定的字符,在生成时,其字符的Region应该是一样的,如chars.bmp(chars.bmp)图片中的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(00);
                    
    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, 11));
                                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(00);
                    
    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, 11));
                                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;

        }

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

  • 相关阅读:
    PHP文件打开、关闭、写入的判断与执行
    统计文件大小,以GB、MB、KB、B输出
    超强功能file_put_contents()函数(集成了fopen、fwrite、fclose)
    fputcsv命令,写csv文件,遇到的小问题(多维数组连接符)
    Rename 更改文件、文件夹名称
    PHP学习——定界符格式引起的错误
    SPOJ 1873 Accumulate Cargo
    POJ 3657 Haybale Guessing
    HDU 1512 Monkey King
    POJ 1741 Tree
  • 原文地址:https://www.cnblogs.com/evlon/p/707053.html
Copyright © 2020-2023  润新知