之前一直想做一个人脸识别的项目,结果最后被调离那个项目组,最后不了了之。最近在家休息,一哥们就让帮忙采集一些数据,因为有效的数据被图片化了,就需要一些简单的数字识别,然后决定用tesseract-ocr来实现。
tesseract-ocr是一 个OCR引擎,在1985年到1995年由HP实验室开发,现在在Google。tesseract-ocr 3.0发布,支持中文。开源协议Apache License 2.0,在商业项目中还是可以值得一用的。
OK.废话少说。代码贴上了。简单的测试了下,生产环境下自己封装下。OCR这些对资源的消耗特别严重,并且在现实情况下图片有噪点扭曲,失败的概率有点大,所以穷举的时候要注意对象代的管理。不过京东没有扭曲什么的,识别就简单多了。
001 | using System; |
002 | using System.Collections.Generic; |
003 | using System.Text; |
004 | using System.Drawing; |
005 | using System.IO; |
006 | using System.Linq; |
007 | using System.Net; |
008 | using System.Threading; |
009 | |
010 | using tessnet2; |
011 | namespace OCR |
012 | { |
013 | class Program |
014 | { |
015 | |
016 | static void Main( string [] args) |
017 | { |
018 | var imgpath = "http://image.58.com/showphone.aspx?t=v55&v=D438D3A47DA8384485F9AB46324E7BDB0" ; |
019 | var ocr = new Tesseract(); |
020 | var result = new List<Word>(13); |
021 | var sb = new StringBuilder(20); |
022 | var ocrlength = 0; |
023 | var ocrcount = 0; |
024 | ocr.SetVariable( "tessedit_char_whitelist" , "¥-0123456789." ); |
025 | ocr.Init(Path.Combine(Directory.GetCurrentDirectory(), @"Language" ), "eng" , false ); |
026 | |
027 | /*识别58并验证是否电话号码*/ |
028 | Spot.Test(imgpath, ocr, out result); |
029 | ocrlength = result.Single<Word>().Text.Length; |
030 | while (ocrlength != 11) /// 检查是否匹配,实际环境中用正则 |
031 | { |
032 | ocrcount++; |
033 | if (ocrcount % 5 != 0) |
034 | { |
035 | Spot.Test(imgpath, ocr, out result); |
036 | ocrlength = result.Single<Word>().Text.Length; |
037 | while (ocrlength == 11) |
038 | { |
039 | Console.WriteLine( "识别成功" ); |
040 | result.Each<Word>(r => Console.WriteLine(r.Text)); |
041 | Console.ReadLine(); |
042 | return ; |
043 | } |
044 | } |
045 | else |
046 | { |
047 | Console.WriteLine( "为了缓解服务器的压力,稍微休息5秒之后继续识别" ); |
048 | Thread.Sleep(5000); //任务休息5秒 |
049 | GC.Collect(); |
050 | GC.Collect(2); |
051 | } |
052 | sb.Remove(0, sb.Length); |
053 | result.Each<Word>(r => sb.Append(r.Text)); |
054 | Console.WriteLine( "第{0}次错误识别结果是{1}" , ocrcount, sb.ToString()); |
055 | } |
056 | |
057 | |
058 | /* 识别京东价格 |
059 | Spot.Test(imgpath,ocr,out result); |
060 | result.Each<Word>(r => sb.Append(r.Text)); |
061 | Console.WriteLine(sb.Replace('S', '5').Replace('s', '5')); |
062 | Console.ReadLine(); |
063 | */ |
064 | } |
065 | } |
066 | |
067 | |
068 | |
069 | public static class Spot |
070 | { |
071 | /// <summary> |
072 | /// 测试方法,实际环境中注意对象的回收。 |
073 | /// </summary> |
074 | /// <remarks> |
075 | /// Spot.Test("","",""); |
076 | /// </remarks> |
077 | /// <param name="url">图片Url</param> |
078 | /// <param name="ocr">ocr的全局对象</param> |
079 | /// <param name="result">返回识别的结果</param> |
080 | public static void Test( string url,Tesseract ocr, out List<Word> result) |
081 | { |
082 | using (var wc = new WebClient()) |
083 | { |
084 | var img = wc.DownloadData(url); |
085 | using (var bitimage = new Bitmap( new MemoryStream(img), true )) |
086 | { |
087 | result = ocr.DoOCR(bitimage, Rectangle.Empty); |
088 | } |
089 | } |
090 | } |
091 | } |
092 | |
093 | |
094 | /// <summary> |
095 | /// |
096 | /// </summary> |
097 | public static class Linq |
098 | { |
099 | /// <summary> |
100 | /// 扩展 |
101 | /// </summary> |
102 | /// <typeparam name="T"></typeparam> |
103 | /// <param name="col"></param> |
104 | /// <param name="handler"></param> |
105 | public static void Each<T>( this IEnumerable<T> col, Action<T> handler) |
106 | { |
107 | foreach (var item in col) |
108 | handler(item); |
109 | } |
110 | } |
111 | |
112 | } |
运行的结果:
需要玩下的点这里下载项目吧。
OCR小贴士:
什么是OCR,点击这里查看。点击
还存在那些OCR引擎?
答:
主要几个OCR还有Asprise-OCR,不过个人感觉这个识别不大准确,错误率太高。所以放弃了。
微软也有OCR,不过下次再介绍基于微软的Document组件的中文识别吧。tesseract-ocr实际上也是支持中文的。可以自己去看下了解下。
来源:http://www.cnblogs.com/imfunny/archive/2011/11/15/2250032.html