天天看點

阿裡開源MNNKit:基于MNN的移動端深度學習SDK,支援安卓和iOS

2020-01-23 09:07:03

機器之心報道

參與:一鳴、Jamin

近來,有越來越多的深度學習架構開始面向移動端進行發展。近日,阿裡也基于其 MNN 推理引擎開源了最新的 MNNKit 深度學習 SDK,安卓和 iOS 開發者都可以友善地進行調用。

近年來,很多企業都在研發面向移動端的深度學習架構。在國内有 小米的 Mace、騰訊的 FeatherCNN(騰訊 AI)和 ncnn(騰訊優圖)、百度的 Paddle-moblie 等。而阿裡也開發了自己的移動端深度學習架構 MNN。

近日,阿裡開源了基于 MNN 引擎的項目 MNNKit,面向安卓和 iOS,以 SDK 的方式提供 AI 端側推理能力。開發者不需要了解算法細節就可以直接使用。

項目位址:https://github.com/alibaba/MNNKit

目前,MNNKit 已經有人臉檢測、手勢識别、人像分割等,後續可能有更多 API 接入。

MNNKit:基于 MNN 的深度學習工具

MNN 是基于阿裡的 MNN 端上推理引擎所開發的應用解決方案,主要面向安卓和 iOS 系統,幫助将 AI 能力應用在實際的移動端場景中。

MNNKit 架構

MNNKit 提供了一個 SDK 供開發者使用,以下為 SDK 的架構。

阿裡開源MNNKit:基于MNN的移動端深度學習SDK,支援安卓和iOS

從圖中可以看出,MNNKit 可以分為三層結構,從底向上分别為:

  1. MNN 引擎層,是 MNN (https://github.com/alibaba/MNN) 庫在 Android/iOS 上編譯好的包的二進制 Release 版本,提供端側運作環境。
  2. Core 基礎層,這主要抽象和封裝與 MNN c++接口調用粒度基本一緻的上層 API,iOS 通過 OC 接口提供,Android 通過 Java 接口提供(TODO)。這一層同時也為上層 SDK 提供一些公共服務類或結構定義。
  3. 業務 Kit 層,包括了人臉檢測、手勢識别封裝的 API。據項目介紹,之後的業務 Kit 層會不斷擴充。

内部原理

因為 MNNKit 主要提供阿裡的端側 AI 能力,是以封裝了很多相關應用的 API。調用如下:

阿裡開源MNNKit:基于MNN的移動端深度學習SDK,支援安卓和iOS

例如,當使用者需要調用 API 的時候,需要首先建立執行個體,然後将圖像、視訊或其他結構化資料輸入,進行 AI 模型的推理工作。工作完成後釋放執行個體即可。

目前 MNNKit 已支援的 API 有:

  • 人臉檢測 API
  • 手勢識别 API
  • 人像分割 API

以人臉檢測為例,檢測内容主要分為三大闆塊:

  • 人臉基本資訊
  • 人臉位置的矩形坐标
  • 106 個關鍵點坐标(區分被遮擋的和未被遮擋的)
  • 置信度
阿裡開源MNNKit:基于MNN的移動端深度學習SDK,支援安卓和iOS

106 個關鍵點的分布(來自官方開源 github)

阿裡開源MNNKit:基于MNN的移動端深度學習SDK,支援安卓和iOS

人臉各區域關鍵點分布對應表

  • 歐拉角度
阿裡開源MNNKit:基于MNN的移動端深度學習SDK,支援安卓和iOS

搖頭(Yaw)、點頭(Pitch)、歪頭(Roll)三個角度值

  • 人臉動作(包含 5 個人臉的動作)
  • 眨眼
  • 張嘴
  • 搖頭
  • 點頭
  • 揚眉

處理過程

我們知道了人臉檢測需要檢測的資料後,接下來看看處理過程:

阿裡開源MNNKit:基于MNN的移動端深度學習SDK,支援安卓和iOS

如圖所示,該流程是 iOS 和安卓裝置後置攝像頭正向拍攝後,在移動端上的整體處理過程。

首先,系統從攝像頭擷取資料,作為 SDK 的輸入。接着,SDK 會進行如下操作:

  1. 在 MNN 引擎執行推理之前,對原始的輸入進行預處理,保證輸入資料中的人臉為正向
  2. 使用 AI 模型進行推理;
  3. 推理後,産生基于輸入圖像(預處理之後的)坐标系的關鍵點結果;。
  4. 把關鍵點坐标變換到和螢幕渲染坐标系相同的方向,友善渲染。

程應用中,最後的結果關鍵點要顯示在使用者螢幕上,前端會使用一個用來渲染的"畫布"。畫布的坐标系被稱為渲染坐标系,

在 SDK 檢測的最後一步,我們将關鍵點變換到和渲染坐标系相同的方向,然後等比例映射關鍵點坐标到渲染坐标系的坐标即可。映射後可以直接渲染到畫布上

代碼示例

MNNKit 提供了包括人臉檢測、手勢識别等方面的示例代碼。接下來我們以人臉檢測為例,看看怎樣可以在安卓或 iOS 中調用 API 進行推理工作。

安卓代碼

前文提到,調用 API 需要首先建立一個執行個體,以下為異步建立 FaceDetector 執行個體,主線程中回調的代碼。

publicstaticvoidcreateInstanceAsync(Contextcontext,FaceDetectorCreateConfigcreateConfig,InstanceCreatedListener<FaceDetector>listener)
           

在這裡,人臉檢測 API 會進行檢測和跟蹤兩個動作。檢測會遭到人臉位置和關鍵點,而跟蹤是在人臉移動時重新定位關鍵點的位置。

在視訊模式下,系統預設每 20 幀檢測一次,其餘幀隻跟蹤。圖檔模式下則每一次調用都檢測。

建立執行個體後,可以将資料輸入模型進行推理。MNNKit 現在已支援多種資料格式輸入。在視訊流檢測場景中,我們可以使用攝像頭的回調資料作為接口的輸入。輸入資料的代碼如下:

publicsynchronizedFaceDetectionReport[]inference(byte[]data,intwidth,intheight,MNNCVImageFormatformat,longdetectConfig,intinAngle,intoutAngle,MNNFlipTypeoutputFlip)
           

使用輸入資料為 bitmap 的推理代碼如下:

publicsynchronizedFaceDetectionReport[]inference(Bitmapbitmap,longdetectConfig,intinAngle,intoutAngle,MNNFlipTypeoutputFlip)
           

當 FaceDetector 執行個體用完之後,我們需要手動釋放執行個體,否則會産生 native 的記憶體洩露。

publicsynchronizedvoidrelease()
           

iOS 代碼

和安卓代碼類似,首先需要建立人臉檢測執行個體:

+(void)createInstanceAsync:(MNNFaceDetectorCreateConfig*)configCallback:(void(^)(NSError*error,MNNFaceDetector*faceDetector))blockCallbackQueue:(dispatch_queue_t)callbackQueue;
           

預設主線程回調:

+(void)createInstanceAsync:(MNNFaceDetectorCreateConfig*)configCallback:(void(^)(NSError*error,MNNFaceDetector*faceDetector))block;
           

PixelBuffer 輸入進行推理的代碼如下:

-(NSArray<MNNFaceDetectionReport*>*)inference:(CVPixelBufferRef)pixelBufferConfig:(MNNFaceDetectConfig)detectConfigAngle:(float)inAngleOutAngle:(float)outAngleFlipType:(MNNFlipType)flipTypeerror:(NSError*__autoreleasing*)error;
           

UIImage 輸入進行推理的代碼如下:

-(NSArray<MNNFaceDetectionReport*>*)inferenceImage:(UIImage*)imageConfig:(MNNFaceDetectConfig)detectConfigAngle:(float)inAngleOutAngle:(float)outAngleFlipType:(MNNFlipType)flipTypeerror:(NSError*__autoreleasing*)error;
           

使用通用 buffer 數組輸入的代碼如下:

-(NSArray<MNNFaceDetectionReport*>*)inference:(unsignedchar*)dataWidth:(float)wHeight:(float)hFormat:(MNNCVImageFormat)formatConfig:(MNNFaceDetectConfig)detectConfigAngle:(float)inAngleOutAngle:(float)outAngleFlipType:(MNNFlipType)flipTypeerror:(NSError*__autoreleasing*)error;
           

執行個體生命周期結束後,會自動觸發相關記憶體的釋放,無需調用方手動釋放。

據悉,MNNKit 是 MNN 團隊在阿裡系應用大規模業務實踐後的成熟解決方案,曆經雙十一等項目考驗,在不依賴于後端的情況下進行高性能推理,使用起來穩定友善。

繼續閱讀