最近入坑研究ocr,看了比較多關於ocr的資料,對ocr的前世今生也有了乙個比較清晰的了解。所以想寫一篇關於ocr技術的綜述,對ocr相關的知識點都好好總結一遍,以加深個人理解。
如果要給ocr進行分類,我覺得可以分為兩類:手寫體識別和印刷體識別。這兩個可以認為是ocr領域兩個大主題了,當然印刷體識別較手寫體識別要簡單得多,我們也能從直觀上理解,印刷體大多都是規則的字型,因為這些字型都是計算機自己生成再通過列印技術印刷到紙上。在印刷體的識別上有其獨特的干擾:在印刷過程中字型很可能變得斷裂或者墨水粘連,使得ocr識別異常困難。當然這些都可以通過一些影象處理的技術幫他盡可能的還原,進而提高識別率。總的來說,單純的印刷體識別在業界已經能做到很不錯了,但說100%識別是肯定不可能的,但是說識別得不錯那是沒毛病。
印刷體已經識別得不錯了,那麼手寫體呢?手寫體識別一直是ocr界一直想攻克的難關,但是時至今天,感覺這個難關還沒攻破,還有很多學者和公司在研究。為什麼手寫體識別這麼難識別?因為人類手寫的字往往帶有個人特色,每個人寫字的風格基本不一樣,雖然人類可以讀懂你寫的文字,但是機器缺很難。那為什麼機器能讀懂印刷體?因為印刷體是機器造出來的啊,那機器當然能讀懂自己造的字型啦哈哈~其實上面也提到了,印刷體一般都比較規則,字型都基本就那幾十種,機器學習這幾十種字型並不是一件難事,但是手寫體,每個人都有一種字型的話,那機器該學習多少字型啊?這就是難度所在。
如果按識別的內容來分類,也就是按照識別的語言的分類的話,那麼要識別的內容將是人類的所有語言(漢語、英語、德語、法語等)。如果僅按照我們國人的需求,那識別的內容就包括:漢字、英文本母、阿拉伯數字、常用標點符號。根據要識別的內容不同,識別的難度也各不相同。簡單而言,識別數字是最簡單了,畢竟要識別的字元只有0~9,而英文本母識別要識別的字元有26個(如果算上大小寫的話那就52個),而中文識別,要識別的字元高達數千個(二級漢字一共6763個)!因為漢字的字形各不相同,結構非常複雜(比如帶偏旁的漢字)如果要將這些字元都比較準確地識別出來,是一件相當具有挑戰性的事情。但是,並不是所有應用都需要識別如此龐大的漢字集,比如車牌識別,我們的識別目標僅僅是數十個中國各省和直轄市的簡稱,難度就大大減少了。當然,在一些文件自動識別的應用是需要識別整個漢字集的,所以要保證識別的整體的識別還是很困難的。
現在就來整理一下常見的ocr流程,為了方便描述,那就舉文件中的字元識別為例子來展開說明吧。
假如輸入系統的影象是一頁文字,那麼識別時的第一件事情是判斷頁面上的文字朝向,因為我們得到的這頁文件往往都不是很完美的,很可能帶有傾斜或者汙漬,那麼我們要做的第一件事就是進行影象預處理,做角度矯正和去噪。然後我們要對文件版面進行分析,進每一行進行行分割,把每一行的文字切割下來,最後再對每一行文字進行列分割,切割出每個字元,將該字元送入訓練好的ocr識別模型進行字元識別,得到結果。但是模型識別結果往往是不太準確的,我們需要對其進行識別結果的矯正和優化,比如我們可以設計乙個語法檢測器,去檢測字元的組合邏輯是否合理。比如,考慮單詞because,我們設計的識別模型把它識別為8ecause,那麼我們就可以用語法檢測器去糾正這種拼寫錯誤,並用b代替8並完成識別矯正。這樣子,整個ocr流程就走完了。從大的模組總結而言,一套ocr流程可以分為:
從上面的流程圖可以看出,要做字元識別並不是單純乙個ocr模組就能實現的(如果單純的ocr模組,識別率相當低),都要各個模組的組合來保證較高的識別率。上面的流程分的比較粗,每個模組下還是有很多更細節的操作,每個操作都關係著最終識別結果的準確性。做過ocr的童鞋都知道,送入ocr模組的影象越清晰(即預處理做的越好),識別效果往往就越好。那現在對這流程中最為重要的字元識別技術做乙個總結。
現在我們只想單純地想對字元進行識別,那方法會有哪些呢?我列了一下可以採取的策略:
上面提到的ocr方法都有其有點和缺點,也正如此,他們也有各自特別適合的應用場景。
首先說開源ocr引擎tesseract。搞字元識別的童鞋應該都聽說過tesseract這個東西,這是谷歌維護的乙個ocr引擎,它已經有一段相當悠久的歷史了。tesseract現在的版本已經支援識別很多種語言了,當然也包括漢字的識別。畢竟tesseract是外國人搞得乙個東西,所以在漢字識別的精度上還是不能擺上檯面,不過還是自己去改善。但是tesseract在阿拉伯數字和英文本母上的識別還是可以的,如果你要做的應用是要識別英文或者數字,不妨考慮一下使用tesseract,畢竟拿來就能得到不錯的結果。當然啦,要做到你想要的識別率,後期微調或者優化肯定要多下功夫的。
上面提到的都是用的是別人的東西,那我們想從頭自己做,咋辦?
那就自己做吧!先談一談字元模板那匹配法。暴力的字元模板匹配法看起來很蠢,但是在一些應用上可能卻很湊效。比如在對電表數字進行識別時,考慮到電表上的字型較少(可能就只有阿拉伯數字),而且字型很統一,清晰度也很高,所以識別難度不高。針對這種簡單的識別場景,我們首先考慮的識別策略當然是最為簡單和暴力的模板匹配法。我們首先定義出數字模板(0~9),然後用該模板滑動匹配電表上的字元,這種策略雖然簡單但是相當有效。我們不需要左思右想去建模,訓練模型,只需要識別前做好模板庫就可以了。
模板匹配法只限於一些很簡單的場景,但對於稍微複雜的場景,那就不太實用了。那此時我們可以採取ocr的一般方法,即特徵設計、特徵提取、分類得出結果的計算機視覺通用的技巧。在深度學習大放異彩之前,ocr的方法基本都是這種方法,其效果嘛,並不算特別好。在這裡簡單說一下這裡常見的方法。第一步是特徵設計和提取,特徵設計是一件很煩人的事情,做過模式識別相關專案的童鞋也深有體會,我們現在識別的目標是字元,所以我們要為字元設計它獨有的的特徵,來為後面的特徵分類做好準備。字元有啥特徵呢?有結構特徵,即字元的端點、交叉點、圈的個數、橫線豎線條數等等,都是可以利用的字元特徵。比如「品」字,它的特徵就是它有3個圈,6條橫線,6條豎線。除了結構特徵,還有大量人工專門設計的字元特徵,據說都能得到不錯的效果。最後再將這些特徵送入分類器(svm)做分類,得出識別結果。這種方式最大的缺點就是,人們需要花費大量時間做特徵的設計,這是一件相當費工夫的事情。通過人工設計的特徵(例如hog)來訓練字元識別模型,此類單一的特徵在字型變化,模糊或背景干擾時泛化能力迅速下降。而且過度依賴字元切分的結果,在字元扭曲、粘連、雜訊干擾的情況下,切分的錯誤傳播尤其突出。針對傳統ocr解決方案的不足,學界業界紛紛擁抱基於深度學習的ocr。
這些年深度學習的出現,讓ocr技術煥發第二春。現在ocr基本都用卷積神經網路來做了,而且識別率也是驚人的好,人們也不再需要花大量時間去設計字元特徵了。在ocr系統中,人工神經網路主要充當特徵提取器和分類器的功能,輸入是字元影象,輸出是識別結果,一氣呵成。這裡就不再展開說明卷積神經網路了,想要知道的細節的可以看我即將要寫的的一篇部落格《卷積神經網路cnn總結》。當然用深度學習做ocr並不是在每個方面都很優秀,因為神經網路的訓練需要大量的訓練資料,那麼如果我們沒有辦法得到大量訓練資料時,這種方法很可能就不奏效了。其次,神經網路的訓練需要花費大量的時間,並且需要用到的硬體資源一般都比較多,這幾個都是需要考慮的問題。
在接下來的部落格中,我將在工程上一一實現以上說到的幾種ocr的識別方法~~
在一些簡單環境下ocr的準確度已經比較高了(比如電子文件),但是在一些複雜環境下的字元識別,在當今還沒有人敢說自己能做的很好。現在大家都很少會把目光還放在如何對電子文件的文字識別該怎麼進一步提高準確率了,因為他們把目光放在更有挑戰性的領域。ocr傳統方法在應對複雜**場景的文字識別顯得力不從心,越來越多人把精力都放在研究如何把文字在複雜場景讀出來,並且讀得準確作為研究課題,用學界術語來說,就是場景文字識別(文字檢測+文字識別)。
從上圖可以看出,自然場景下的文字識別比簡單場景的文字識別實在困難太多了,現在雖然出了很多成果,但是離理想結果還是差很遠。
當然啦,除上面的場景文字識別外,歷史悠久的手寫體的識別到現在還是一件具有挑戰的課題,在深度學習的浪潮下,手寫體的識別已經前進了一大步,但是尚且沒達到印刷體識別那種可以商用的地步,所以啊,ocr的研究還得不斷地進行下去。
HTML之一字符集
ascii字符集 iso字符集 gbk等等。1 首先,說一說為什麼要設定html檔案的字符集 如果不指定的話,瀏覽器會使用本地作業系統的字符集,那麼,如果你的應用需要支援多國語言的話,就會有問題,比如你的頁面裡有中文字元,終端使用者的本地作業系統的字符集是iso 8859 1,那麼瀏覽器就會用iso...
亂碼之一 字符集編碼錯誤
abcd四人打撲克牌賭博,賭博之前ab私下有約,通過打手勢的方式告知對方自己手裡的關鍵牌,從而達到雙贏的合作.協定 伸出大拇指就表示大王在誰手裡,伸出小拇指就表示小王在誰手裡 現場 當a拿到大王時,伸出大拇指 編碼 加密 b看到a伸出大拇指,根據合約知道a拿有大王 解碼 解密 專案 計算機打撲克 二...
Redis入門之一 字串(string)
redis 中最簡單的資料結構,它既可以儲存文字 比如 hello world 又可以儲存數字 比如整數 10086 和浮點數 3.14 還可以儲存二進位制資料 比如 10010100 redis 為這幾種型別的值分別設定了相應的操作命令,讓使用者可以針對不同的值做不同的處理。為字串鍵設定值 獲取字...