QQ验证码识别源代码(C#/NET1.1)

QQ验证码识别源代码(C#/NET1.1)

using System;

namespace QQ
{
///

1<summary>   
2/// yzm 的摘要说明。   
3/// </summary>

public class yzm
{
public yzm(public System.Drawing.Bitmap pic)
{
this.bp = pic;
}
///

1<summary>   
2/// 将一个int值存入到4个字节的字节数组(从高地址开始转换,最高地址的值以无符号整型参与"与运算")   
3/// </summary>

///

1<param name="thevalue"/>

要处理的int值
///

1<param name="thebuff"/>

存放信息的字符数组
public static void getbytesfromint(int thevalue, byte[] thebuff)
{
long v1=0; long v2=0; long v3=0; long v4=0;
uint b1=(uint)4278190080; uint b2=(uint)16711680; uint b3=(uint)65280; uint b4=(uint)255;
v1=thevalue & b1;
v2=thevalue & b2;
v3=thevalue & b3;
v4=thevalue & b4;
thebuff[0]=(byte)(v1>>24);
thebuff[1]=(byte)(v2>>16);
thebuff[2]=(byte)(v3>>8);
thebuff[3]=(byte)v4;
}
///

1<summary>   
2/// 将一个ushort值存入到2个字节的字节数组(从高地址开始转换,最高地址的值以无符号整型参与"与运算")   
3/// </summary>

///

1<param name="thevalue"/>

要处理的ushort值
///

1<param name="thebuff"/>

存放信息的字符数组
public static void getbytesfromushort(ushort thevalue, byte[] thebuff)
{
ushort v1=0; ushort v2=0;
ushort b1=(ushort)65280; ushort b2=(ushort)255;
v1=(ushort)(thevalue & b1);
v2=(ushort)(thevalue & b2);
thebuff[0]=(byte)(v1>>8);
thebuff[1]=(byte)(v2);
}
///

1<summary>   
2/// 将4个字节的字节数组转换成一个int值   
3/// </summary>

///

1<param name="thebuff"/>

字符数组
///

1<returns></returns>

public static int getintfrombyte(byte[] thebuff)
{
int jieguo=0;
long mid=0;
long m1=0; long m2=0; long m3=0; long m4=0;
m1=(thebuff[0]<<24);
m2=(thebuff[1]<<16);
m3=(thebuff[2]<<8);
m4=thebuff[3];
mid=m1+m2+m3+m4;
jieguo=(int)mid;
return jieguo;
}
///

1<summary>   
2/// 将2个字节的字节数组转换成一个ushort值   
3/// </summary>

///

1<param name="thebuff"/>

字符数组
///

1<returns></returns>

public static ushort getushortfrombyte(byte[] thebuff)
{
int jieguo1=0;
jieguo1=(thebuff[0]<<8)+thebuff[1];
ushort jieguo=(ushort)jieguo1;
return jieguo;
}
///

1<summary>   
2/// 将内存中的数据写入硬盘(保存特征库)   
3/// </summary>

///

1<param name="thefile"/>

保存的位置
public static void writetofile(string thefile)
{
System.IO.FileStream fs = new System.IO.FileStream(thefile,System.IO.FileMode.OpenOrCreate,System.IO.FileAccess.ReadWrite);
byte[] buff0=new byte[4];
getbytesfromint(datanum,buff0);
fs.Write(buff0,0,4);
for(int ii=0;ii

  1<datanum;ii++) <summary="" buff="new" byte[2];="" byte[]="" for(int="" fs.close();="" fs.write(buff,0,2);="" fs.writebyte(datachar[ii]);="" fs.writebyte(dataxy[ii,0]);="" fs.writebyte(dataxy[ii,1]);="" getbytesfromushort(datap[ii,jj],buff);="" jj="0;jj&lt;20;jj++)" {="" }="">   
  2/// 从文件中读取信息,并保存在内存中相应的位置   
  3///    
  4/// <param name="thefile"/>特征库文件   
  5public static void readfromfile(string thefile)   
  6{   
  7int allnum=0;   
  8byte[] buff=new byte[4];   
  9System.IO.FileStream fs = new System.IO.FileStream(thefile,System.IO.FileMode.Open,System.IO.FileAccess.Read);   
 10fs.Read(buff,0,4);   
 11allnum=getintfrombyte(buff);   
 12byte[] buff0=new byte[2];   
 13for(int ii=0;ii<allnum;ii++) <summary="" datachar[ii]="buff0[0];" datanum="allnum;" datap[ii,jj]="getushortfrombyte(buff0);" dataxy[ii,0]="buff0[0];" dataxy[ii,1]="buff0[0];" for(int="" fs.close();="" fs.read(buff0,0,1);="" fs.read(buff0,0,2);="" jj="0;jj&lt;20;jj++)" {="" }="">   
 14/// 验证码图片   
 15///    
 16public System.Drawing.Bitmap bp =new System.Drawing.Bitmap(49,20);   
 17/// <summary>   
 18/// 特征库的长度   
 19/// </summary>   
 20public static int datanum=0;   
 21/// <summary>   
 22/// 特征库数据   
 23/// </summary>   
 24public static ushort[,] datap=new ushort[100000,20];   
 25/// <summary>   
 26/// 长度与高度   
 27/// </summary>   
 28public static byte[,] dataxy=new byte[100000,2];   
 29/// <summary>   
 30/// 对应的字符   
 31/// </summary>   
 32public static byte[] datachar=new byte[100000];   
 33/// <summary>   
 34/// 等待处理的数据   
 35/// </summary>   
 36public ushort[] datapic=new ushort[20];   
 37/// <summary>   
 38/// 有效长度   
 39/// </summary>   
 40public byte xlpic=0;   
 41/// <summary>   
 42/// 有效宽度   
 43/// </summary>   
 44public byte ylpic=0;   
 45/// <summary>   
 46/// 检索特征库中存在的记录   
 47/// </summary>   
 48public string getchar()   
 49{   
 50//如果查找不到,就返回空串   
 51string jieguo="";   
 52for(int ii=0;ii<datanum;ii++) <summary="" char="" cj="(char)datachar[ii];" cj.tostring();="" continue;="" dataxy[ii,1]!="ylpic)" for(int="" if(datap[ii,jj]!="datapic[jj])" if(dataxy[ii,0]!="xlpic" if(notsamenum<4)="" int="" jieguo;="" jj="0;jj&lt;20;jj++)" notsamenum="0;" notsamenum++;="" return="" {="" ||="" }="" 如果能够收集更多的特征库,识别率可以达到80%以上="" 当然也可以改进品配算法(如使用关键点品配),以用较少的特征库达到较高的识别率,但="" 统计一共有多少行的像素有差异,如果在4行以内就认为是存在该记录="" 这种方法比较原始,但比较适合多线程时的运行,因为程序只进行简单的逻辑比较="" 那样有比较大的机会造成识别错误并且多线程时占用较多cpu时间。="" (此时可能需要将特征库的容量提高到15w个或以上)="">   
 53/// 检查特征库中是否已经存在相关记录   
 54///    
 55bool ischardatain()   
 56{   
 57bool jieguo=false;   
 58for(int ii=0;ii<datanum;ii++) if(system.math.abs(dataxy[ii,0]-xlpic)="" int="" notsamenum="0;" {="" 如果能够收集更多的特征库,识别率可以达到80%以上="" 当然也可以改进品配算法(如使用关键点品配),以用较少的特征库达到较高的识别率,但="" 统计一共有多少行的像素有差异,如果在4行以内就认为是存在该记录="" 这种方法比较原始,但比较适合多线程时的运行,因为程序只进行简单的逻辑比较="" 那样有比较大的机会造成识别错误并且多线程时占用较多cpu时间。="" (此时可能需要将特征库的容量提高到15w个或以上)="">1 || System.Math.Abs(dataxy[ii,1]-ylpic)&gt;1)   
 59{   
 60continue;   
 61}   
 62for(int jj=0;jj&lt;20;jj++)   
 63{   
 64if(datap[ii,jj]!=datapic[jj])   
 65{   
 66notsamenum++;   
 67}   
 68}   
 69if(notsamenum&lt;4)   
 70{   
 71string asdasd=((char)datachar[ii]).ToString();   
 72return true;   
 73}   
 74}   
 75return jieguo;   
 76}   
 77/// <summary>   
 78/// 添加到特征库中,并暂时将对应的字符置为空格以待人工识别   
 79/// </summary>   
 80void adddatawithnullchar()   
 81{   
 82if(this.ischardatain())   
 83{   
 84return;   
 85}   
 86for(int ii=0;ii&lt;20;ii++)   
 87{   
 88datap[datanum,ii]=this.datapic[ii];   
 89}   
 90//暂时将对应的字符置为空格以待人工识别   
 91datachar[datanum]=32;   
 92dataxy[datanum,0]=this.xlpic;   
 93dataxy[datanum,1]=this.ylpic;   
 94datanum++;   
 95}   
 96/// <summary>   
 97/// 检查验证码图片是否能分成4个部分,如果可以就检查4个字符在特征库中是否已经存在,如果不存在,   
 98/// 就添加到特征库中,并暂时将对应的字符置为空格以待人工识别   
 99/// </summary>   
100public void writetodata()   
101{   
102bool[,] picpixel=new bool[49,20];   
103for(int ii=0;ii&lt;49;ii++)   
104{   
105for(int jj=0;jj&lt;20;jj++)   
106{   
107if(bp.GetPixel(ii,jj).GetBrightness()&lt;0.999)   
108{   
109picpixel[ii,jj]=true;   
110}   
111}   
112}   
113int[] index=new int[8];   
114int indexnum=0;   
115bool black=false;   
116for(int ii=0;ii&lt;49;ii++)   
117{   
118bool haveblack=false;   
119for(int jj=0;jj&lt;20;jj++)   
120{   
121if(picpixel[ii,jj])   
122{   
123haveblack=true;   
124break;   
125}   
126}   
127if(haveblack &amp;&amp; black==false)   
128{   
129index[indexnum]=ii;   
130indexnum++;   
131black=true;   
132}   
133if(!haveblack &amp;&amp; black)   
134{   
135index[indexnum]=ii;   
136indexnum++;   
137black=false;   
138}   
139}   
140if(indexnum&lt;7)   
141{   
142return;   
143}   
144if(indexnum==7)   
145{   
146index[7]=49;   
147}   
148//****   
149for(int ii=0;ii&lt;4;ii++)   
150{   
151int x1=index[ii*2];   
152int x2=index[ii*2+1];   
153int y1=0,y2=19;   
154bool mb=false;   
155for(int jj=0;jj&lt;20;jj++)   
156{   
157for(int kk=x1;kk<x2;kk++) break;="" for(int="" if(mb)="" if(picpixel[kk,jj])="" jj="19;jj" mb="false;" y1="jj;" {="" }="">=0;jj--)   
158{   
159for(int kk=x1;kk<x2;kk++) **以上是获取有效区域的范围="" break;="" for(int="" if(mb)="" if(picpixel[kk,jj])="" if(xlpic="" jj="0;jj&lt;20;jj++)" mb="true;" this.datapic[jj]="0;" this.xlpic="(byte)(x2-x1);" y2="jj;" {="" }="" 如果字符宽度超过16个像素就不予处理="">16)   
160{   
161continue;   
162}   
163this.ylpic=(byte)(y2-y1+1);   
164int ys=-1;   
165ushort[] addin=new ushort[]{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};   
166for(int jj=y1;jj&lt;=y2;jj++)   
167{   
168ys++;   
169int xs=-1;   
170for(int kk=x1;kk<x2;kk++) ****="" <summary="" if(picpixel[kk,jj])="" this.adddatawithnullchar();="" this.datapic[ys]="(ushort)(this.datapic[ys]+addin[xs]);" xs++;="" {="" }="">   
171/// 识别图片   
172///    
173/// <returns>返回识别结果(如果返回的字符串长度小于4就说明识别失败)</returns>   
174public string ocrpic()   
175{   
176string jieguo="";   
177bool[,] picpixel=new bool[49,20];   
178for(int ii=0;ii&lt;49;ii++)   
179{   
180for(int jj=0;jj&lt;20;jj++)   
181{   
182if(bp.GetPixel(ii,jj).GetBrightness()&lt;0.999)   
183{   
184picpixel[ii,jj]=true;   
185}   
186}   
187}   
188int[] index=new int[8];   
189int indexnum=0;   
190bool black=false;   
191for(int ii=0;ii&lt;49;ii++)   
192{   
193bool haveblack=false;   
194for(int jj=0;jj&lt;20;jj++)   
195{   
196if(picpixel[ii,jj])   
197{   
198haveblack=true;   
199break;   
200}   
201}   
202if(haveblack &amp;&amp; black==false)   
203{   
204index[indexnum]=ii;   
205indexnum++;   
206black=true;   
207}   
208if(!haveblack &amp;&amp; black)   
209{   
210index[indexnum]=ii;   
211indexnum++;   
212black=false;   
213}   
214}   
215if(indexnum&lt;7)   
216{   
217return jieguo;   
218}   
219if(indexnum==7)   
220{   
221index[7]=49;   
222}   
223//****   
224for(int ii=0;ii&lt;4;ii++)   
225{   
226int x1=index[ii*2];   
227int x2=index[ii*2+1];   
228int y1=0,y2=19;   
229bool mb=false;   
230for(int jj=0;jj&lt;20;jj++)   
231{   
232for(int kk=x1;kk<x2;kk++) break;="" for(int="" if(mb)="" if(picpixel[kk,jj])="" jj="19;jj" mb="false;" y1="jj;" {="" }="">=0;jj--)   
233{   
234for(int kk=x1;kk<x2;kk++) **以上是获取有效区域的范围="" break;="" for(int="" if(mb)="" if(picpixel[kk,jj])="" if(xlpic="" jj="0;jj&lt;20;jj++)" mb="true;" this.datapic[jj]="0;" this.xlpic="(byte)(x2-x1);" y2="jj;" {="" }="" 如果字符宽度超过16个像素就不予处理="">16)   
235{   
236continue;   
237}   
238this.ylpic=(byte)(y2-y1+1);   
239int ys=-1;   
240ushort[] addin=new ushort[]{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};   
241for(int jj=y1;jj&lt;=y2;jj++)   
242{   
243ys++;   
244int xs=-1;   
245for(int kk=x1;kk&lt;x2;kk++)   
246{   
247xs++;   
248if(picpixel[kk,jj])   
249{   
250this.datapic[ys]=(ushort)(this.datapic[ys]+addin[xs]);   
251}   
252}   
253}   
254jieguo=jieguo+this.getchar();   
255}   
256return jieguo;   
257}   
258}   
259}   
260---  
261![](http://www.playicq.com/images/box.gif)  
262---</x2;kk++)></x2;kk++)></x2;kk++)></x2;kk++)></x2;kk++)></datanum;ii++)></datanum;ii++)></allnum;ii++)></datanum;ii++)>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus