初試 iOS 11 新框架:Vision Framework 讓文字偵測變得更容易


在今年的 WWDC 中,Apple 釋出了許多新框架(frameworks),Vision Framework 便是其中一個。藉由 Vision Framework ,你不需要高深的知識就可以很容易地在你的 App 中實作出電腦視覺技術(Vision Techniques)!Vision Framework 可以讓你的 App 執行許多強大的功能,例如識別人臉範圍及臉部特徵(微笑、皺眉、左眼眉毛等等)、條碼偵測、分類出圖像中的場景、物件偵測及追蹤以及視距偵測。

或許那些已經使用 Swift 開發程式一段時間的人會想知道既然已經有了Core ImageAVFoundation,為什麼還要推出 Vision 呢?如果我們看一下這張在 WWDC 演講中出現的表格,我們可以看到 Vision 的準確度(Accuracy)是最好的,同時也支援較多的平台。不過 Vision 需要較多的處理時間以及電源消耗。

Difference between AVFoundation and Vision framework

圖片來源: Apple’s WWDC video – Vision Framework: Building on Core ML

在本次的教學中,我們將會利用 Vision Framework 來作出文字偵測的功能,並實作出一個能夠偵測出文字的 App ,不論字體、字型及顏色。如下圖所示,Vision Framework 可以識別出印刷及手寫兩種文字。

Text Recognition Demo App

編者按:根據測試結果,Vision Framework 對中文支援有限。

為了節省你建置 UI 所花的時間好專注在學習 Vision Framework 上,你可以下載 Starter Project 作為開始。

請注意你需要 Xcode 9 (beta 2 或以上版本)來完成本次教學,同時也需要一台 iOS 11 裝置來測試。所有的程式碼皆是以 Swift 4 撰寫。

建立即時影像

當你打開專案時,你可以看到視圖已經為你設定好放在 Storyboard 上了。接著進入 ViewController.swift ,你會發現由一些 outlet 及 function 所構成的程式骨架。我們的第一步就是要建立一個即時影像來偵測文字,在 imageView 底下宣告一個 AVCaptureSession 屬性:

這樣就初始化了一個可以用來作即時(real-time)或非即時(offline)影音擷取的AVCaptureSession 物件。而這個物件在你要對即時影像進行操作時就會用上。接著,我們需要把這個 session 連接到我們的裝置上。首先把下面的函式放入 ViewController.swift 吧。

如果你曾經用過 AVFoundation,你會發覺這個程式碼有點熟悉。如果你沒用過,別擔心。我們逐行的將程式碼說明一遍。

  1. 我們首先修改 AVCaptureSession 的設定。然後我們設定 AVMediaType 為影片,因為我們希望是即時影像,此外它應該要一直持續地運作。
  2. 接著,我們要定義裝置的輸入及輸出。輸入是指相機所看到的,而輸出則是指應該顯示的影像。我們希望影像顯示為 kCVPixelFormatType_32BGRA 格式。你可以從這裡了解更多關於像素格式的類型。最後,我們把輸入及輸出加進到 AVCaptureSession
  3. 最後,我們把含有影像預覽的 sublayer 加進到 imageView 中,然後讓 session 開始運作。

呼叫在 viewWillAppear 方法裡的這個函式:

因為在 viewWillAppear() 中還沒決定 imageView 的範圍,所以覆寫 viewDidLayoutSubviews() 方法來更新圖層的範圍。

在執行之前,要在 Info.plist 加入一個條目來說明為何你需要使用到相機功能。這自 Apple 發佈 iOS 10 後,都是必須添加的步驟。

text-detection-infoplist

現在即時影像應該會如預期般的運作。然而,因為我們還沒實作 Vision Framework,所以還沒有文字偵測功能。而這就是我們接下來要完成的部份。

實作文字偵測

在我們實作文字偵測(Text Detection)之前,我們需要了解 Vision Framework 是如何運作的。基本上,在你的 App 裡實作 Vision 會有三個步驟,分別是:

  • Requests – Requests 是指當你要求 Framework 為你偵測一些東西時。
  • Handlers – Handlers 是指當你想要 Framework 在 Request 產生後執行一些東西或處理這個 Request 時.
  • Observations – Observations 是指你想要用你提供的資料做什麼。

request-observation

現在,讓我們從 Request 開始吧。在初始化的變數 session 底下宣告另一個變數:

我們建立了一個含有一個通用類別 VNRequest 的陣列。接著,讓我們在 ViewController 類別裡建立一個函式來進行文字偵測吧。

在這個函式裡,我們建立一個 VNDetectTextRectanglesRequest 的常數 textRequest。基本上它是 VNRequest 的一個特定型態,只能尋找文字中的矩形。當 Framework 完成了這個 Request,我們希望它呼叫 detectTextHandler 函式。同時我們也想要知道 Framework 辨識出了什麼,這也是為什麼我們設定 reportCharacterBoxes 屬性為 true。最後,我們設定早先建立好的變數requeststextRequest

現在,你應該會得到一些錯誤訊息。這是因為我們還沒定義應該用來處理 Request 的函式。為了解決這些錯誤,建立一個函式像:

在上面的程式碼,我們首先定義一個含有所有 VNDetectTextRectanglesRequest 結果的常數 observations。接著,我們定義另一個常數 result,它將遍歷所有 Request 的結果然後轉換為 VNTextObservation 型態。

現在,更新 viewWillAppear() 方法:

如果你現在執行你的 App,你不會看到任何的不同。這是因為雖然我們告訴 VNDetectTextRectanglesRequest 要回報字母方框,但是沒有告訴它該如何回報。這將是我們接下來要完成的部份。

繪製方框

在我們的 App 中,我們會讓 Framework 繪製兩個方框:一個所偵測的每個字母,另一個則是整個單字。讓我們就從製作繪製每個單字的方框開始吧!

我們一開始先在函式裡定義一個常數 boxes,他是由 Request 所找到的所有 characterBoxes 的組合。然後,我們定義一些在視圖上的座標點來幫助我們定位方框。最後,我們建立一個有給定範圍約束的 CALayer 並將它應用在我們的 imageView 上。接下來,就讓我們來為每個字母建立方框吧。

跟我們前面所撰寫的程式碼相似,我們使用 VNRectangleObservation 來定義約束條件,讓我們更容易地勾勒出方框。現在,我們已經設置好所有的函式了。最後一步便是要連接所有的東西。

串接程式

有兩個主要的部分需要連接。第一個是處理 Request 的函式。我們先來完成個這個吧。像這樣更新 detectTextHandler 方法:

我們從讓程式碼非同步執行開始。首先,我們移除 imageView 最底層的圖層(如果你有注意到,我們先前添加了許多圖層到 imageView 中。)接下來,我們從 VNTextObservation 的結果裡確認是否有區域範圍存在。現在,我們呼叫沿著範圍(或者說單字)繪製方框的函式。然後我們確認是否有字符方框在這個範圍裡。如果有,我們呼叫方法來沿著字母繪上方框。

現在,連接所有東西的最後一個步驟就是以即時影像來執行我們的 Vision Framework 程式碼。我們需要做的是攝製影像並將其轉換為 CMSampleBuffer。在 ViewController.swift 的擴展(Extension)中插入下面的程式碼:

在那邊打住一下。這是我們程式碼的最後部分了。這個擴展調用了 AVCaptureVideoDataOutputSampleBufferDelegate 協定。基本上這個函式所做的就是它確認 CMSampleBuffer 是否存在以及提供一個 AVCaptureOutput。接著,我們建立一個 VNImageOption 型態的字典(Dictionary)變數 requestOptionsVNImageOption 是一個結構(struct)類型,它可以從相機中保持著資料及屬性。最後我們建立一個 VNImageRequestHandler 物件並執行我們早先建立的文字 Request。

Build 及 Run 你的 App,看看你得到什麼!

text-detection-example

小結

Well,接下來是個大工程呢!試著用不同字型、大小、字體、粗細等等來測試 App 吧。看看是否你可以擴展這個 App 。你可以在下面的回應中貼上你如何擴展這個專案。你也可以結合 Vision Framework 及 Core ML。想要更多關於 Core ML 的資訊,可以參閱我先前撰寫的 Core ML 介紹教學。

你可以參考放在 GitHub 上的 完整專案

更多關於 Vision Framework 的細節可以參考 Vision Framework 官方文件。你也可以參考 WWDC 關於 Vision Framework 的演講:

Vision Framework: Building on Core ML

Advances in Core Image: Filters, Metal, Vision, and More

譯者簡介:楊敦凱-目前於科技公司擔任 iOS Developer,工作之餘開發自有 iOS App同時關注網路上有趣的新玩意、話題及科技資訊。平時的興趣則是與自身專業無關的歷史、地理、棒球。來信請寄到:[email protected]

原文Using Vision Framework for Text Detection in iOS 11


Sai Kambampati 是程式開發員,生活於美國加州薩克拉門托,於2017獲得Apple's WWDC獎學金。精於 Swift及Python語言,渴望自家開發人工智能產品。閒時喜歡觀看Netflix、做健身或是遛漣圖書館中。請到推特追蹤 @Sai_K1065 。

blog comments powered by Disqus
訂閲電子報

訂閲電子報

AppCoda致力於發佈優質iOS程式教學,你不必每天上站,輸入你的電子郵件地址訂閱網站的最新教學文章。每當有新文章發佈,我們會使用電子郵件通知你。

已收你的指示。請你檢查你的電郵,我們已寄出一封認證信,點擊信中鏈結才算完成訂閱。

Shares
Share This