zoukankan      html  css  js  c++  java
  • QQ验证码识别源代码(C#/NET1.1)

    notsamenum++;
    }
    }
    if(notsamenum<4)
    {
    char cj=(char)datachar[ii];
    return cj.ToString();
    }
    }
    return jieguo;
    }
    /// <summary>
    /// 检查特征库中是否已经存在相关记录
    /// </summary>
    bool ischardatain()
    {
    bool jieguo=false;
    for(int ii=0;ii<datanum;ii++)
    {
    //统计一共有多少行的像素有差异,如果在4行以内就认为是存在该记录
    // 这种方法比较原始,但比较适合多线程时的运行,因为程序只进行简单的逻辑比较
    //如果能够收集更多的特征库,识别率可以达到80%以上
    //(此 时可能需要将特征库的容量提高到15W个或以上)
    //当然也可以改进品配算法(如使用关键点品配),以用较少的特征库达到较高的识别率,但
    // 那样有比较大的机会造成识别错误并且多线程时占用较多CPU时间。
    int notsamenum=0;
    if(System.Math.Abs(dataxy[ii,0]-xlpic)>1 || System.Math.Abs(dataxy[ii,1]-ylpic)>1)
    {
    continue;
    }
    for(int jj=0;jj<20;jj++)
    {
    if(datap[ii,jj]!=datapic[jj])
    {
    notsamenum++;
    }
    }
    if(notsamenum<4)
    {
    string asdasd=((char)datachar[ii]).ToString();
    return true;
    }
    }
    return jieguo;
    }
    /// <summary>
    /// 添加到特征库中,并暂时将对应的字符置为空格以待人工识别
    /// </summary>
    void adddatawithnullchar()
    {
    if(this.ischardatain())
    {
    return;
    }
    for(int ii=0;ii<20;ii++)
    {
    datap[datanum,ii]=this.datapic[ii];
    }
    // 暂时将对应的字符置为空格以待人工识别
    datachar[datanum]=32;
    dataxy[datanum,0]=this.xlpic;
    dataxy[datanum,1]=this.ylpic;
    datanum++;
    }
    /// <summary>
    /// 检查验证码图片是否能分成4个部分,如果可以就检查4个字符在特征库中是否已经存在,如果不存在,
    /// 就添加到特征库中,并暂时将对应的字符置为空格以待人工识别
    /// </summary>
    public void writetodata()
    {
    bool[,] picpixel=new bool[49,20];
    for(int ii=0;ii<49;ii++)
    {
    for(int jj=0;jj<20;jj++)
    {
    if(bp.GetPixel(ii,jj).GetBrightness()<0.999)
    {
    picpixel[ii,jj]=true;
    }
    }
    }
    int[] index=new int[8];
    int indexnum=0;
    bool black=false;
    for(int ii=0;ii<49;ii++)
    {
    bool haveblack=false;
    for(int jj=0;jj<20;jj++)
    {
    if(picpixel[ii,jj])
    {
    haveblack=true;
    break;
    }
    }
    if(haveblack && black==false)
    {
    index[indexnum]=ii;
    indexnum++;
    black=true;
    }
    if(!haveblack && black)
    {
    index[indexnum]=ii;
    indexnum++;
    black=false;
    }
    }
    if(indexnum<7)
    {
    return;
    }
    if(indexnum==7)
    {
    index[7]=49;
    }
    //****
    for(int ii=0;ii<4;ii++)
    {
    int x1=index[ii*2];
    int x2=index[ii*2+1];
    int y1=0,y2=19;
    bool mb=false;
    for(int jj=0;jj<20;jj++)
    {
    for(int kk=x1;kk<x2;kk++)
    {
    if(picpixel[kk,jj])
    {
    mb=true;
    break;
    }
    }
    if(mb)
    {
    y1=jj;
    break;
    }
    }
    mb=false;
    for(int jj=19;jj>=0;jj--)
    {
    for(int kk=x1;kk<x2;kk++)
    {
    if(picpixel[kk,jj])
    {
    mb=true;
    break;
    }
    }
    if(mb)
    {
    y2=jj;
    break;
    }
    }
    //** 以上是获取有效区域的范围
    for(int jj=0;jj<20;jj++)
    {
    this.datapic[jj]=0;
    this.datapic[jj]=0;
    }
    this.xlpic=(byte)(x2-x1);
    // 如果字符宽度超过16个像素就不予处理
    if(xlpic>16)
    {
    continue;
    }
    this.ylpic=(byte)(y2-y1+1);
    int ys=-1;
    ushort[] addin=new ushort[]{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
    for(int jj=y1;jj<=y2;jj++)
    {
    ys++;
    int xs=-1;
    for(int kk=x1;kk<x2;kk++)
    {
    xs++;
    if(picpixel[kk,jj])
    {
    this.datapic[ys]=(ushort)(this.datapic[ys]+addin[xs]);
    }
    }
    }
    this.adddatawithnullchar();
    }
    //****
    }
    /// <summary>
    /// 识别图片
    /// </summary>
    /// <returns>返回识别结果(如果返回的字符串长度小于4就说明识别失败)</returns>
    public string ocrpic()
    {
    string jieguo="";
    bool[,] picpixel=new bool[49,20];
    for(int ii=0;ii<49;ii++)
    {
    for(int jj=0;jj<20;jj++)
    {
    if(bp.GetPixel(ii,jj).GetBrightness()<0.999)
    {
    picpixel[ii,jj]=true;
    }
    }
    }
    int[] index=new int[8];
    int indexnum=0;
    bool black=false;
    for(int ii=0;ii<49;ii++)
    {
    bool haveblack=false;
    for(int jj=0;jj<20;jj++)
    {
    if(picpixel[ii,jj])
    {
    haveblack=true;
    break;
    }
    }
    if(haveblack && black==false)
    {
    index[indexnum]=ii;
    indexnum++;
    black=true;
    }
    if(!haveblack && black)
    {
    index[indexnum]=ii;
    indexnum++;
    black=false;
    }
    }
    if(indexnum<7)
    {
    return jieguo;
    }
    if(indexnum==7)
    {
    index[7]=49;
    }
    //****
    for(int ii=0;ii<4;ii++)
    {
    int x1=index[ii*2];
    int x2=index[ii*2+1];
    int y1=0,y2=19;
    bool mb=false;
    for(int jj=0;jj<20;jj++)
    {
    for(int kk=x1;kk<x2;kk++)
    {
    if(picpixel[kk,jj])
    {
    mb=true;
    break;
    }
    }
    if(mb)
    {
    y1=jj;
    break;
    }
    }
    mb=false;
    for(int jj=19;jj>=0;jj--)
    {
    for(int kk=x1;kk<x2;kk++)
    {
    if(picpixel[kk,jj])
    {
    mb=true;
    break;
    }
    }
    if(mb)
    {
    y2=jj;
    break;
    }
    }
    //** 以上是获取有效区域的范围
    for(int jj=0;jj<20;jj++)
    {
    this.datapic[jj]=0;
    this.datapic[jj]=0;
    }
    this.xlpic=(byte)(x2-x1);
    // 如果字符宽度超过16个像素就不予处理
    if(xlpic>16)
    {
    continue;
    }
    this.ylpic=(byte)(y2-y1+1);
    int ys=-1;
    ushort[] addin=new ushort[]{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
    for(int jj=y1;jj<=y2;jj++)
    {
    ys++;
    int xs=-1;
    for(int kk=x1;kk<x2;kk++)
    {
    xs++;
    if(picpixel[kk,jj])
    {
    this.datapic[ys]=(ushort)(this.datapic[ys]+addin[xs]);
    }
    }
    }
    jieguo=jieguo+this.getchar();
    }
    return jieguo;
    }
    }
    }
  • 相关阅读:
    关于虚拟机断电导致的 generating /run/initramfs/rdsosreport.txt 问题优秀解决方案
    centos7 yum 阿里源
    startup.bat脚本启动tomcat时,cmd命令窗口闪现问题及Neither the JAVA_HOME nor the JRE_HOME environment variable is defined 错误解决
    Linux 中 Fish Shell
    卸载mysql
    /bin/bash^M: 坏的解释器: 没有那个文件或目录
    elementUI 文本鼠标移入显示太长
    el-upload 手动上传文件
    vue-element-admin 打包测试环境报错
    vue 分页跳转页面详情,返回记住当前点击第几页
  • 原文地址:https://www.cnblogs.com/top5/p/1665324.html
Copyright © 2011-2022 走看看