此次和你們聊聊文字識別相關的話題。 你們在平時確定對各類掃描類的 APP 不陌生。 拿着手機攝像頭對着任何文字,直接將攝像頭中的文字內容轉換成手機上可編輯的字符串。c++
文字識別,縮寫叫作 OCR,全稱 Optical character recognition,譯爲光學字符識別。 關於他的完整定義能夠在 Wikipedia 上面找到: en.wikipedia.org/wiki/Optica…。git
完整的 OCR 算法,並不簡單。 涉及到圖像識別算法,以及將從圖片中識別出來的文字轉換成咱們程序中可使用的二進制形式。這其中還包括不一樣語言的字符如何識別,怎樣更精準的識別等等。github
設想一下,若是做爲開發者,讓你本身從頭開發這樣一套算法,恐怕要花掉很大力氣。 不過好消息是,咱們生活在這個開源時代,早已經有不少前輩們爲咱們趟好了道路。 這也是咱們今天要聊的主題, Tesseract 就是這樣一個開源庫,給定任意一張圖片,它能夠識別出裏面全部的文字內容,而且 API 接口使用很是簡單。算法
Tesseract 是 Google 發佈的一款 OCR 開源庫,它支持多個變成語言環境,以及運行環境,其中包括咱們這裏將要介紹的 iOS 環境。 今天就用它帶領你們開發一個屬於你本身的 OCR 應用。swift
首先,須要安裝 Tesseract, 最簡單的方式是用過 Cocoapods, 進入你的項目根目錄,輸入:bash
pod init
複製代碼
而後,編輯生成的 Podfile 配置文件:微信
target 'ocrSamples' do
use_frameworks!
pod 'TesseractOCRiOS'
end
複製代碼
將 TesseractOCRiOS
加入配置列表中, 最後輸入:ide
pod install
複製代碼
就完成了 TesseractOCRiOS
的安裝。若是你以前沒有接觸過 Cocoapods 能夠參看咱們以前的文章 swiftcafe.io/2015/02/10/…。學習
安裝完成後, 咱們還須要進行一下簡單的配置, 首先要在 Build Phases -> Link Binary With Libraries 中配置, 項目須要的依賴庫, CoreImage, libstdc++, 以及 TesseractOCRiOS 自身:字體
配置好依賴庫以後, 咱們還須要將文字識別訓練數據添加進來, 訓練數據是什麼呢, TesseractOCRiOS
識別圖片的時候,會依照這個訓練數據的規則來識別文字。好比中文,英文等,都有對應的訓練數據,這能夠理解爲深度學習預先爲咱們訓練好的模型。用它來進行核心的識別算法。
訓練數據是須要按照不一樣語言來區分的,Tesseract 有專門的頁面列出了全部可用的訓練數據:github.com/tesseract-o…。
好比咱們這裏須要識別簡體中文,就能夠下載 chi-sim 這個訓練數據:
而後將訓練數據拖放到工程中:
上圖中的 chi_sim.traineddata 是咱們下載的訓練數據, 這裏面有一點要注意的是, 這個文件必需要在 testdata 這個文件夾中。 而且這個文件夾要以 "Create Folder Reference" 的方式拖放進來:
這種引用方式和另一種 "Create Groups" 的方式有什麼區別呢? 主要區別在於, 使用引用方式拖放進來的目錄, 在最後生成 APP 包的時候, Main Bunlde 中是以 testdata/chi_sim.traineddata 這樣的路徑形式保存咱們訓練數據資源的, 若是使用 "Create Groups" 方式,最終存儲的時候是會忽略文件夾名的,最後存儲在 Main Bundle 中的文件是以 /chi_sim.traineddata 這個路徑存放的。
而 TesseractOCRiOS, 默認狀況下是會在 testdata/chi_sim.traineddata 這個路徑查找訓練數據的, 因此若是使用 "Create Groups" 方式拖入,會形成運行時找不到訓練數據,而報錯。 這點細節須要格外注意。
最後,爲了讓 TesseractOCRiOS 可以正確運行, 咱們還須要關掉 BitCode, 不然會報編譯錯誤,咱們須要在兩處都要關掉它,一個是至工程,另一個是 Pods 模塊, 以下圖:
作完上述的準備工做後, 咱們就能夠開始編碼了, 這裏只給你們展現最精簡的代碼。 首先咱們須要在主界面上顯示兩個控件,一個是咱們預先存儲好的帶有文字的照片, 另一個是用於展現識別結果的文本框:
override func viewDidLoad() {
super.viewDidLoad()
self.imageView = UIImageView(frame: CGRect(x: 0, y: 80, width: self.view.frame.size.width, height: self.view.frame.size.width * 0.7))
self.imageView?.image = UIImage(named: "textimg")
self.view.addSubview(self.imageView!)
self.textView = UITextView(frame: CGRect(x: 0, y: labelResult.frame.origin.y + labelResult.frame.size.height + 20, width: self.view.frame.size.width, height: 200))
self.view.addSubview(self.textView!)
}
複製代碼
這裏面咱們只將兩個控件的初始化關鍵代碼寫出來,其餘不重要的代碼都略去。 而後就能夠調用 TesseractOCRiOS 來進行文字識別了:
func recognizeText(image: UIImage) {
if let tesseract = G8Tesseract(language: "chi_sim") {
tesseract.engineMode = .tesseractOnly
tesseract.pageSegmentationMode = .auto
tesseract.image = image
tesseract.recognize()
self.textView?.text = tesseract.recognizedText
}
}
複製代碼
全部識別相關的代碼就都在這裏了。首先調用 G8Tesseract 進行初始化, 咱們傳入訓練數據的名稱,這裏是 "chi_sim" 表明簡體中文。 engineMode
有三種能夠選擇的模式, tesseractOnly,tesseractCubeCombined 和 cubeOnly。 咱們使用第一種模式,採用訓練數據的方式。 cubeOnly 的意識就是使用更精準的 cube 方式, tesseractCubeCombined 就是兩種模式的結合使用。
cube 模式須要額外的模型數據, 大體樣例是這樣:
上圖是英文的 cube 識別模型。 簡體中文的模型我暫時沒有找到,因此咱們這個實例中只是用到了 tesseractOnly 模式。 而且在沒有 cube 模型數據的狀況下,咱們是不用使用 tesseractCubeCombined 和 cubeOnly 的,不然會由於模型數據不存在而報錯。 你們若是可以找到中文的 cube 模型,也歡迎在留言中反饋,這樣會讓這個文字識別更加精準。
其餘的調用就不須要多講了, 將要識別的 image 對象設置給 Tesseract。 而後調用它的 recognize 方法進行識別, 最後將識別結果 tesseract.recognizedText 設置給 TextView。
最終的運行效果以下:
上面的圖片是我拍的 SwiftCafe 網站上一篇文章的照片, 從識別結果上看,還算比較準確。
你們從上面的代碼中應該也感覺到了, Tesseract 雖然提供了本質上算是比較複雜的文字識別算法, 但它提供給開發者的接口能夠說得上是很是簡單。 OCR 文字識別從總體上來講,也能夠算得上是 AI 的一個應用分支,在這個 AI 大行其道的時代,即使掌握一些應用技術,對咱們開發者來講也能夠很大的拓寬咱們的視野。 發揮你的創意,也許相似 Tesseract 這些組件可以幫助你創造 AI 時代的新銳應用。
固然, Tesseract 目前自身還有一些缺陷,好比它只能識別印刷字體,而不能精準的識別手寫字體。 不過那又怎麼樣呢,原本至關複雜的 OCR 算法,可讓咱們用很是少的代價應用起來,仍是一件對開發者很是幸福的事情。
照例,本文中的示例工程代碼已經放到 Github 中,你們有須要能夠直接下載:github.com/swiftcafex/…。
**若是你以爲這篇文章有幫助,還能夠關注微信公衆號 swift-cafe,會有更多個人原創內容分享給你~ **