【 tulaoshi.com - ASP.NET 】
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; 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=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(xlpic16) { 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; } }<