热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c#OCR识别验证码

搜索不少关于验证码的东东,经过实验识别程度不是很理想,但也能识别90%数字验证码,对字母验证码不是很好。1publicpartialclassGetValidCode:

搜索不少关于验证码的东东,经过实验识别程度不是很理想,但也能识别90%数字验证码,对字母验证码不是很好。

  1   public partial class GetValidCode : Form
2 {
3 private ValidImg _mValidImg;
4 private Bitmap _testMap;
5 private Bitmap[] arrmap =null;
6 public GetValidCode()
7 {
8 InitializeComponent();
9 }
10
11 private void GetValidCode_Load(object sender, EventArgs e)
12 {
13 #region 得到验证码图片
14 _mValidImg = new ValidImg();
15 _testMap = _mValidImg.GetValidImg();
16 Bitmap map = new Bitmap(_mValidImg.StrPath);
17 pbImg.Image = map;
18 //arrmap = GetSplitPics(_testMap, 1, 5);
19 //DisplaySplitImg(arrmap);
20 #endregion
21 }
22
23
24 private void btnGetContent_Click(object sender, EventArgs e)
25 {
26 if (true)
27 {
28 #region TestOne
29 _testMap = new Bitmap(_mValidImg.StrPath);
30
31 UnCodebase ud = new UnCodebase(_testMap);
32 _testMap = ud.GrayByPixels();
33 ud.ClearNoise(128, 2);
34 pbImg.Image = _testMap;
35
36 tessnet2.Tesseract ocr = new tessnet2.Tesseract();//声明一个OCR类
37 ocr.SetVariable("tessedit_char_whitelist", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXZY0123456789"); //设置识别变量,当前只能识别数字。
38 ocr.Init(Application.StartupPath + @"\\tmpe", "eng", true); //应用当前语言包。注,Tessnet2是支持多国语的。语言包下载链接:http://code.google.com/p/tesseract-ocr/downloads/list
39
40 List result = ocr.DoOCR(_testMap, Rectangle.Empty);//执行识别操作
41 string code = result[0].Text;
42 txtContent.Text += code;
43
44 #endregion
45 }
46 }
47
48
49 ///
50 /// 得到图片有效区域,使切分图片更加精确
51 ///

52 ///
53 ///
54 private Bitmap CutMap(Bitmap _bitmap)
55 {
56 Rectangle rg = new Rectangle(int.Parse(updX.Value.ToString()), int.Parse(updY.Value.ToString()), _bitmap.Width - int.Parse(updW.Value.ToString()), _bitmap.Height - int.Parse(updH.Value.ToString()));
57 //Rectangle rg = new Rectangle(1, 0, _bitmap.Width - 10, _bitmap.Height );
58 Bitmap bitmap = _bitmap.Clone(rg, _bitmap.PixelFormat);
59 return bitmap;
60
61 }
62
63 ///
64 /// 切分图片
65 ///

66 ///
67 ///
68 ///
69 ///
70 private Bitmap[] SplitImg(Bitmap _bitmap, int row, int col)
71 {
72 int singW = _bitmap.Width / row;
73 int singH = _bitmap.Height / col;
74 Bitmap[] arrmap = new Bitmap[row * col];
75 Rectangle rect;
76 for (int i = 0; i )
77 {
78 for (int j = 0; j )
79 {
80 rect = new Rectangle(j * singW, i * singH, singW, singH);
81 arrmap[i * row + j] = _bitmap.Clone(rect, _bitmap.PixelFormat);
82 }
83 }
84
85 return arrmap;
86 }
87
88 ///
89 /// 展示
90 ///

91 ///
92 private void DisplaySplitImg(Bitmap[] arrmap)
93 {
94 for (int i = 0; i )
95 {
96 ControlCollection cc = this.Controls as ControlCollection;
97 foreach (Control item in cc)
98 {
99 if (item is PictureBox)
100 {
101 PictureBox pb = item as PictureBox;
102 int index=i+1;
103 if (pb.Name=="pb"+index)
104 {
105 pb.Image = arrmap[i];
106 break;
107 }
108 }
109 }
110
111 }
112 }
113
114 private void GetValidCode_FormClosed(object sender, FormClosedEventArgs e)
115 {
116 this.Dispose();
117 if (File.Exists(_mValidImg.StrPath))
118 {
119 File.Delete(_mValidImg.StrPath);
120 }
121 }
122
123 }

 

ValidImg类中定义验证码图片

    public class ValidImg
{
private string _strPath=string.Empty;

public string StrPath
{
get { return _strPath; }
set { _strPath = value; }
}
public ValidImg()
{
Directory.CreateDirectory(
@"tmpImg");
}
public Bitmap GetValidImg()
{
Bitmap _ResultBitMap;
using (Bitmap img = new Bitmap(120, 30))
{
using (Graphics g = Graphics.FromImage(img))
{
string strCode = GetCode(5);

Random r
= new Random();
g.Clear(Color.White);
for (int i = 0; i <25; i++)
{
int x1 = r.Next(0, img.Width);
int x2 = r.Next(0, img.Width);
int y2 = r.Next(0, img.Height);
int y1 = r.Next(0, img.Height);
g.DrawLine(
new Pen(Color.Silver), x1, y1, x2, y2); // 随机产生图片的背景噪线
}
Font font
= new Font("楷体", 18, (System.Drawing.FontStyle.Bold));
LinearGradientBrush brush
= new LinearGradientBrush(new Rectangle(0, 0, img.Width, img.Height), Color.Blue, Color.DarkRed, 3, true);
g.DrawString(strCode, font, brush,
5, 2); //绘制随机字符

g.DrawRectangle(
new Pen(Color.Silver), 0, 0, img.Width - 1, img.Height - 1); //绘制图片的前景噪点

_ResultBitMap
= img;
DateTime dt
= DateTime.Now;

string strImgFileName = dt.ToFileTime().ToString()+ ".jpg";
_strPath
= Path.Combine("tmpImg", strImgFileName);
_ResultBitMap.Save(_strPath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
return _ResultBitMap;
}


private string GetCode(int num)
{
string str = "ABCD1EF2GH3IJ4KL5MN6P7QR8ST9UVWXYZ";
Random r
= new Random();
StringBuilder sb
= new StringBuilder();
for (int i = 0; i )
{
sb.Append(str.Substring(r.Next(0, str.Length), 1));
}
return sb.ToString();
}
}

 


public class ValidImg
{
private string _strPath=string.Empty;

public string StrPath
{
get { return _strPath; }
set { _strPath = value; }
}
public ValidImg()
{
Directory.CreateDirectory(
@"tmpImg");
}
public Bitmap GetValidImg()
{
Bitmap _ResultBitMap;
using (Bitmap img = new Bitmap(120, 30))
{
using (Graphics g = Graphics.FromImage(img))
{
string strCode = GetCode(5);

Random r
= new Random();
g.Clear(Color.White);
for (int i = 0; i <25; i++)
{
int x1 = r.Next(0, img.Width);
int x2 = r.Next(0, img.Width);
int y2 = r.Next(0, img.Height);
int y1 = r.Next(0, img.Height);
g.DrawLine(
new Pen(Color.Silver), x1, y1, x2, y2); // 随机产生图片的背景噪线
}
Font font
= new Font("楷体", 18, (System.Drawing.FontStyle.Bold));
LinearGradientBrush brush
= new LinearGradientBrush(new Rectangle(0, 0, img.Width, img.Height), Color.Blue, Color.DarkRed, 3, true);
g.DrawString(strCode, font, brush,
5, 2); //绘制随机字符

g.DrawRectangle(
new Pen(Color.Silver), 0, 0, img.Width - 1, img.Height - 1); //绘制图片的前景噪点

_ResultBitMap
= img;
DateTime dt
= DateTime.Now;

string strImgFileName = dt.ToFileTime().ToString()+ ".jpg";
_strPath
= Path.Combine("tmpImg", strImgFileName);
_ResultBitMap.Save(_strPath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
return _ResultBitMap;
}


private string GetCode(int num)
{
string str = "ABCD1EF2GH3IJ4KL5MN6P7QR8ST9UVWXYZ";
Random r
= new Random();
StringBuilder sb
= new StringBuilder();
for (int i = 0; i )
{
sb.Append(str.Substring(r.Next(0, str.Length), 1));
}
return sb.ToString();
}
}

虽然不完美,但也是识别验证码的一个思路,希望不要用在做坏事上。


推荐阅读
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • WhenIusepythontoapplythepymysqlmoduletoaddafieldtoatableinthemysqldatabase,itdo ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • 本文详细介绍了使用C#实现Word模版打印的方案。包括添加COM引用、新建Word操作类、开启Word进程、加载模版文件等步骤。通过该方案可以实现C#对Word文档的打印功能。 ... [详细]
  • 在C#/ .NET中,处理基督面前的日期没有内置支持,需要编写自己的代码。本文介绍了在处理此类日期时的最佳方法,并提供了一个示例链接,可以参考编码的解决方案。 ... [详细]
  • C#多线程解决界面卡死问题的完美解决方案
    当界面需要在程序运行中不断更新数据时,使用多线程可以解决界面卡死的问题。一个主线程创建界面,使用一个子线程执行程序并更新主界面,可以避免卡死现象。本文分享了一个例子,供大家参考。 ... [详细]
  • 本文讨论了在ASP中创建RazorFunctions.cshtml文件时出现的问题,即ASP.global_asax不存在于命名空间ASP中。文章提供了解决该问题的代码示例,并详细解释了代码中涉及的关键概念,如HttpContext、Request和RouteData等。通过阅读本文,读者可以了解如何解决该问题并理解相关的ASP概念。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
author-avatar
用户tkeex06qp1
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有