WWDC 2019 - 理解 Vision 框架中的圖片技術

WWDC 2019 session 222 Understanding Images in Vision Framework算法

Vision 是 Apple 2017 年和 Core ML 一塊兒推出的、基於 Core ML 封裝的圖像識別庫。根據官方文檔看,Vision 包含就有人臉識別、機器學習圖片分析、條形碼識別、文字識別等基礎功能。數組

本文主要介紹了 Vision 框架在圖像技術方面的一些酷炫功能,並必定程度上闡述了其原理。bash

圖片重點區域 Saliency

Saliency 是什麼?

Saliency 直譯成中文就是:顯著、凸起、特色。那麼在 Vision 框架之中,Saliency 究竟指的是什麼呢?先直接上圖:網絡

當咱們第一次看到左側這張圖片時,視線必定是最早被這三張鳥臉 (海雀臉) 吸引的。若是把注意力集中的地方,用高光在圖片中標註出來,那麼大概就是第二張圖這樣:高光集中於鳥的頭部。session

這些高光部分,也就是人類注意力更容易集中地部分,實際上就是一種 Saliency (即基於注意力的 Saliency),而高光事後的效果圖實際上就是 Saliency 的熱力圖 (The Heatmap)。app

兩種 Saliency

這兩種 Saliency 在算法上就有着比較明顯的不一樣。基於注意力的 Saliency 實際上就是直觀的由人類注意力的集中程度來斷定,而基於物體的 Saliency 目的是識別出焦點物體,而後將焦點物體分割出來。框架

因此效果圖如上,中間的圖是基於注意力的結果,咱們一般關注的是人物、動物的面部,因此只有面部附近會高亮。而右邊的圖將整個鳥都高亮了出來,是基於物體的結果。好比下面這張圖,也是一樣的道理:機器學習

實際上,基於注意力的 Saliency 會更爲複雜。其實咱們也能直觀地感覺到,由於注意力自己就會受到太多人爲的不肯定因素的影響,好比畫面對比度、人物面部、畫面主題、視野範圍、光線強度等。有意思的是,它甚至會被持續的運動狀態所影響,好比下圖中,基於注意力的 Saliency 將人物行進路線前方的部分區域也進行了高亮:ide

具體的 Demo 能夠參見:高亮圖片中使人感興趣的部分性能

The Heat Map: Saliency 熱力圖

熱力圖的概念很容易理解,那麼如何獲取 Saliency 熱力圖呢?Vision API 設計的基本使用邏輯就是 handler 搭配 request。經過建立 handler (VNImageRequestHandler, Vision 圖片處理中最主要的 Handler) 以後調用 perform(_:) 方法,執行相應的 request (VNGenerateAttentionBasedSaliencyImageRequest,從名字就能夠看出,關鍵詞 AttentionBasedSaliency),具體代碼以下:

let handler = VNImageRequestHandler(url: imageURL)
let request: VNImageBasedRequest = VNGenerateAttentionBasedSaliencyImageRequest()
request.revision = VNGenerateAttentionBasedSaliencyImageRequestRevision1

try? handler.perform([request])
guard let result = request.results?.first
let observation = result as? VNSaliencyImageObservation
else { fatalError("missing result") }

let pixelBuffer = observation.pixelBuffer
複製代碼

The Bounding Boxes: Saliency 位置

var boundingBox: CGRect { get }
複製代碼

Bounding boxes 就是探測出來的 Saliency 的位置信息,不過須要注意的是,座標系的原點在圖片左下角。對於基於注意力的 Saliency 來講,只有惟一的 bounding box,而基於物體的 Saliency 則最多有三個 bounding box。

獲取 bounding box 代碼以下:

func addSalientObjects(in observation: VNSaliencyImageObservation,
                        to path: CGMutablePath, 
                        transform: CGAffineTransform)
{
    guard let objects = observation.salientObjects else { return }
    for object in objects {
        // 獲得 bounding box
        path.addRect(object.boundingBox, transform:transform)
    }
}
複製代碼

一些使用案例

獲得圖片 Saliency 以後其實有不少做用,具體舉幾個例子:

  • 用於濾鏡:增長不一樣類型的濾鏡、圖片效果。
  • 用於相冊:增長圖片瀏覽的體驗,將照片自動縮放到最佳位置。
  • 用於識別:與其餘圖像算法一塊兒使用,先經過 bounding box 將物體切割出來,以後進行再識別提升準確率。

圖片分類 Classification

圖片識別、分類是 Vision 的最基礎功能,Vision 框架提供了用於圖片分類的 API,使用起來很是方便,iPhone 相冊中就有大量使用。雖然 coreML 框架也能使用本身訓練圖片分類器,須要大量的數據以及計算資源等,對於普通開發者來講具備比較大的成本。並且 Vision 框架使用了多標籤分類網絡(Multi-label network)能夠在一張圖裏面識別出多個物體。

哪些物體能夠被識別? -- Taxonomy

到底哪些 object 能夠被識別?這就要引出 Taxonomy 的概念了。Taxonomy 實際上指的是生物學上的分類系統,不一樣物體根據語義上的含義被分類。在這個樹狀結構中,有超過 1000 個分類,父類更加寬泛,子類更加具體。

也能夠經過下面的語句,查看整個 Taxonomy:

// List full taxonomy with
VNClassifiyImageRequest.knownClassifications(forRevision: VNClassifyImageRequestRevision1 )
複製代碼

在構造這個 Taxonomy 樹狀結構時,每一個分類都必須是能夠經過視覺定義的,必需要避免形容詞、抽象名詞、太寬泛的名詞,以及避免職業名稱。具體使用,也符合 Vision API 統一的使用方法,handler (依然是 VNImageRequestHandler, Vision 圖片處理中最主要的 Handler) 搭配 request (VNClassifyImageRequest,關鍵詞 Classify,分類識別專用):

let handler = VNImageRequestHandler(url: imageUrl)
let request = VNClassifyImageRequest()
try? handler.perform([request])
let observations = request.results as? [VNClassificationObservation]
複製代碼

最終獲得一個 Observation 數組,包含一系列物體識別結果,以及分別對應的信心值(可能性)。注意到信心值總和不爲 1,這就是由於剛纔提到的 Multi-label network 所產生的結果。

// 上圖識別以後的 observations 示例結果
// 從圖中識別出可能有:動物、貓、哺乳動物、衣服、小圓帽、帽子、人、成年人、雪...等一系列結果
[(animal, 0.848), (cat, 0.848), (mammal, 0.848), (clothing, 0.676), (beanie, 0.675), (hat, 0.675), (people, 0.616), (adult, 0.616), (snow, 0.445), (jacket, 0.214), (outdoor, 0.063), (leash, 0.057), (cord, 0.057)......]
複製代碼

結果的進一步篩選: Precision and Recall

獲得識別結果以後,如何 Observation 數組進行進一步分析,來斷定究竟識別結果中哪些是足夠可信的呢?很是符合常識的一個關鍵公式是:Confidence > Threshold。很容易理解,當信心值大於某個閾值時,就能夠判斷圖片中有相應物體。可是最大的問題在於,閾值應該如何肯定,而且閾值並不固定,不一樣的圖片中閾值確定是不一樣的。

接下來,咱們須要先引入兩個指標:Precision 查準率、Recall 召回率。用一張比較經典的圖來解釋一下:

  • Precision 查準率,指的是全部預測中真正預測對的比例。它可以反映出誤報的程度。Precision 率越高,表明預測的越準確,誤報數量越少。
  • Recall 召回率,指的是全部符合要求的結果中,被成功預測出來的比例。它反映的是漏報程度。Recall 率越高,表明預測的越準確,漏報數量越少。

Precision 和 Recall 都能反映分類算法的準確性,但卻有不一樣的傾向性。舉兩個例子,好比 AI 看病時,一般更看重 Recall 召回率,由於咱們更擔憂漏報狀況的發生。而好比在過濾垃圾郵件時,一般更看重 Precision 查準率,畢竟咱們不但願錯誤地把用戶的正常郵件也給錯誤地過濾了。

因此回到最初的問題,咱們如何斷定 Observation 數組中哪些結果是符合 Confidence > Threshold 公式,應該被留下來的呢?咱們能夠直接經過限制 Precision 或者是 Recall 的值來拿到結果。

好比使用 hasMinimumRecall(_:forPrecision:) 限制 recall,precision 爲 0.7 時,最小 recall 爲 0.5:

let searchObservations = observations?.filter { $0.hasMinimumRecall(0.5, forPrecision: 0.7)}
複製代碼

固然,使用 hasMinimumPrecision(_:forRecall:) 限制 precision 也是同理:

let searchObservations = observations?.filter { $0.hasMinimumPrecision(0.5, forRecall: 0.7)}
複製代碼

圖解篩選過程: PR Curve

PR 曲線反映的是同一個分類器下 Precision 和 Recall 的關係,能夠用來衡量分類器性能的優劣。能夠看到 Precision 和 Recall 負相關。

對於 PR 曲線上每個點,都對應着一個 Precision 和 Recall 的值。咱們能夠經過 PR 曲線來直觀地理解上文中篩選、過濾的這個過程。好比下面咱們分別有三個分類器,分別對應識別"Cat"、"Anvil"以及"CD"時的 PR 曲線。當咱們限制了 (Recall = 0.5, Precision >= 0.4) 時,能夠看到前兩張圖都存在買組條件的點,而第三張圖並不存在,那麼很明顯的 "CD" 就應該被從結果中過濾掉。

圖片類似度 Image Similarity

描述圖片的傳統方式

除了識別圖片的問題以外,咱們常常會面臨的問題就是,如何判斷兩張圖片間的類似程度。那麼首先,咱們該如何描述一張圖片?傳統的方式有下面兩種:

  1. 使用像素點信息進行比較。這樣比較很是不許確,小小的改動就會徹底斷定爲不一樣圖片。

  1. 使用關鍵詞。可是關鍵詞對於一張圖片來講過於籠統,不夠精確。

對於一個圖片的描述,不能僅僅包含對其表面樣式的描述,還必須包含對圖片的內容的進一步敘述。用上述傳統方法咱們很難實現所謂的"進一步描述",可是巧妙的是,當咱們在用分類神經網絡對圖片進行分類時,神經網絡自己就是對圖片的進一步描述。神經網絡的上層網絡(upper layers)正好包含了圖片的關鍵信息(salient information),同時也剛好能摒棄掉了一些冗餘信息。因此,咱們能夠利用這個特色,來對圖片進行描述。

圖片描述向量:FeaturePrint

FeaturePrint 用於描述圖片內容的向量,和傳統的詞向量 (word vector) 相似。它反映的就是神經網絡在作圖片分類時,從圖片中提取出來的信息。經過特定的 Vision API,就能將圖片映射成對應的 FeaturePrint (這也是爲何說它是一種向量)。

須要注意的是,FeaturePrint 與 Taxonomy 並不相關,並非說圖片被分類爲貓,那麼對它的描述就應該是貓。

在獲得了 FeaturePrint 以後,咱們就能夠直接比較圖片間的類似程度。computeDistance(_:to:) 方法能夠直接獲得一個反映圖片類似度的浮點數。好比下圖中,數值越小,圖片在語義 (semantic sense) 上越類似。

具體 Demo 參見:Demo - 使用FeaturePrint比較圖片間類似度

人臉識別技術 Face Technology

接下來說一下人臉識別技術方面的進步。

Face Landmarks: 人臉特徵點識別的進步

人臉特徵點 (Face Landmark) 的識別一直是人臉識別技術的重要部分,Vision 框架在這方面有下面幾個進步:

  1. 識別點位增長,從 65 到 76 個點
  2. 每一個點都提供了信心度 (以前只能提供一個總體的信心度)
  3. 瞳孔識別更加精確

Face Capture Quality: 人臉拍攝質量

Face capture quality 是一個綜合性指標,用於斷定人像效果的好壞,衡量因素包含光線、模糊程度、是否有遮擋、表現力、人物姿態等等。

好比第一張照片就比第二張照片得分高,意味着第一張照片有着更好的拍攝質量。

咱們能夠經過上面的代碼,直接獲得一張圖片的 face capture quality 的數值,進而將類似圖片進行比較,篩選出更加優質的圖片。好比這裏個 Demo:根據 face capture quality 篩選自拍照

注意,face capture quality 不能和一個固定閾值進行比較。不一樣系列的照片中 face capture quality 值分佈區域可能不一樣,若是咱們以一個固定的閾值來過濾(好比上圖中的 0.520),那麼有可能會把左邊所有的照片都過濾掉,哪怕其實左邊的圖片有一些相對拍的好的照片。換句話說,face capture quality 只是一個對同一個被攝物體的相對值,它的絕對數值大小並不能直接反映照片的拍攝效果。

其餘進展 Other Progress

新的識別器

除了這些傳統的識別器,還有一些新的好比人體 (Human Detector) 和貓狗 (Cat and Dog Detectors) 的識別器。

視頻追蹤技術的強化

視頻追蹤技術也獲得了強化,追蹤技術的 Demo 能夠查看: 在視頻中追蹤多個物體。具體強化內容以下:

  1. Bounding box 更加貼合,減小了亂入的背景
  2. 更好處理有遮擋的狀況
  3. 依賴了機器學習算法
  4. 更低的能量損耗

Vision 和 CoreML 更加兼容

Vision 對 CoreML 的支持也獲得了提高。雖然去年就能夠經過 Vision API 運行 CoreML 的模型,可是如今使用起來更方便:

  1. Vision 能自動將輸入的圖片轉成 coreML 的格式,輸出後又自動解析爲合適的 Observation 類型。
  2. Vision 能夠將多個圖片做爲輸入了,不過須要須要設置 mixRatio。
相關文章
相關標籤/搜索