Tesseract-OCR使用有感


這玩意兒就只有一個Tesseract.dll 就算有其它的加上x64目錄下的另外兩個dll leptonica-1.80.0.dll  tesseract41.dll也不過幾兆而已,但是 但是 但是 加上字庫文件可就大了 幾十兆 。也充分說明了這玩意兒跟我原先說的一樣的主要在於字庫的匹配。如果只識別數字英文這種 那你調用百度的庫反而是個大包袱還必須聯網,近期聽到一段話 世界上本沒有標准件 行業形成了也就有了標准件。資本主義國家形成了標准件 於是我們也就只有在別人的框框里鑽來鑽去 始終跳不出這個圈兒,如果你明白原理的話就知道其實是不需要標准件的,造輪子才有樂趣嘛,哇哈哈哈。

使用過程還是很簡單的。首先使用nu-get安裝Tesseract ,注意搜索的時候標題是tesseract 然后 作者是charles weld 版本是v4.1.1的那個 不要弄錯了,我的項目.NetFramework框架是4.0 安裝完成后會自動為我們添加tesseract的引用。然后網上隨意抄一段函數,功能是給一個圖片調用引擎識別圖片里的文字:

 1 private List<string> GetProductNumberFromImage(string imagePath)
 2 {
 3     List<string> resultList = new List<string>();//chi_sim
 4     //using (var ocr = new TesseractEngine(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tessdata"), "normal", EngineMode.Default))
 5     using (var ocr = new TesseractEngine(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tessdata"), "eng", EngineMode.Default))
 6     {                
 7         //ocr.SetVariable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");//
 8         var pix = PixConverter.ToPix(new Bitmap(imagePath));
 9         using (var page = ocr.Process(pix))
10         {
11             string text = page.GetText();
12             if (!string.IsNullOrEmpty(text))
13             {
14                 resultList.Add(text);
15                
16             }
17         }
18     }
19     return resultList;
20 }

還是那句話 遇事先冷靜想想為什么總是有好處的。demo運行不起的時候 仔細看代碼tessdata的字符 噢 原來如此 嘗試下吧,需要事先下載名為eng.traineddata的語言文件置於你編譯好的執行文件目錄下的tessdata目錄,果然。

還可以使用此語句預定義識別內容

1 ocr.SetVariable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");

在數字和英文的情況下識別率還可以的。中文的話就有些慘了。

 

 於是我們需要進行校正 ,說實話校正的過程比上面麻煩多了 又要敲命令又要咋的 麻煩的一逼,需要用到一堆工具。
這些打成包的工具在此地址下載https://sourceforge.net/projects/vietocr/   

下載好后我們參照這篇文章進行實施https://www.cnblogs.com/wzben/p/5930538.html
大概過程就是用工具敲dos命令生成box文件 其實也就是一個帶方框的字體描述文件 告訴你系統目前是怎樣識別的,然后用一個GUI工具 jTessBoxEditor 在界面上對文本的寬高 框選范圍調整 對應哪個漢字 進行校正。 

當我運行train.bat 運行不起的時候彈出 Windows找不到javaw 的時候咋辦啊 不要去糾字面意思 ,估計是需要安裝jdk吧 嘗試一下安裝jdk8 果然如此。訓練字庫的過程中 報錯了 Failed to load font_properties from font_properties ,找到一篇博文 https://blog.csdn.net/dragoo1/article/details/8439272 大概看了下沒錯就是他了 照着實施 bingo 搞定。

 

能夠進行到這一步說明你還能不厭其煩,還能清晰思考說明你是個合格的程序員。 稍微注意下你會發現問題的關鍵那就是對於漢字的 寬高判別  和部首偏旁偏旁的區域歸並 識別引擎很難判定,該框選的不作為一個字單位處理,不該框選的多框 ,這個對識別率影響很大。就連調用微軟office的MODI漢字識別率也不見得多高。關鍵點就在於每單位字寬高的智能判斷,相信百度那些也只不過針對這些點進行解決了的而已。用的是別人的引擎即使開源的這復雜度 字單位寬高智能判斷我們是改不動的 這里我們只是按部就班的進行模板訓練 以提高識別率。 

經歷一些麻煩的校正和命令操作得到一個normal.traineddata 文件 ,復制到debug下的tessdata目錄。注意字庫載入代碼更改成normal。

1 using (var ocr = new TesseractEngine(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tessdata"), "normal", EngineMode.Default))

實際上基於模板匹配的這種規規矩矩的OCR已經是非常非常基礎的了,畢竟Tesseract-OCR那只有幾兆的體積 連我上面說的文本行檢測 漢字智能切割 這種都沒有 也有可能是我沒找到使用方式 谷歌維護的還支持深度學習應該還是可以的 ,但是目前就我的使用感來說的話一般般只是一個將就用了。 把他吹的多么好又是開源的 因為基本上何耐市面上一個能用的免費的了 其它的已經是垃圾中的垃圾了,其它的商用的別人也不會拿出來給免費用的你說對吧

再次測試稍許提高了識別率,好,zhongguo特色的"差不多任務"差不多先生,成功達成任務目標。交差了事

最后:我們自己訓練了一個庫,然后有從官網下載好的默認的庫。如果上面一折騰不就只能使用我們自己訓練的那幾個字了嗎,豈不是識別率更低 要這樣還不如不訓練呢,對於這一點網上的所有帖子都沒做一個明確的說明 很扯淡。通過下面的初始化方式就能你自己的庫+官方字庫一起使用,normal是你上面訓練出的字庫的名稱,本人親測有效。

1 using (var ocr = new TesseractEngine(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tessdata"), "normal+eng", EngineMode.Default))

最后在生產實測中遇到了不少坎坷 憋出了一身汗,好歹還是解決了,事實證明幸好沒用office的OCR識別 要不然真掛了 黑盒特性太嚴重了。這個雖然也很一般但是好歹還是有些可自定義化的參數選項 有實際測量值的結果供你篩選 。打個比方比如加一個自定義邏輯 識別對象的寬高小於多少 我們認為它是一個噪點 把它忽略。還有在最后的測試中為了讓容錯率大點避免識別失敗 把模板字庫的每個字弄得很胖 結果經常出現識別錯誤比如3識別成9, 最后實踐的經驗證明取一個“合體”的字模可以讓識別率提高 。

幾經調校 加入了更精細化的識別過程控制 還是基本能夠滿足生產環境需求。

以此經驗分享給盆友們願大家少走一些彎路。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM