之前一直想做一個人臉識別的項目,結果最後被調離那個項目組,最後不了了之。最近在家休息,一哥們就讓幫忙採集一些數據,因爲有效的數據被圖片化了,就需要一些簡單的數字識別,然後決定用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