最近越来越多的深度学习框架开始面向移动端开发。近日,阿里还开源了最新的基于其MNN推理引擎的MNNKit深度学习SDK,方便Android和iOS开发者调用。近年来,很多公司都在开发面向移动端的深度学习框架。在国内有小米的Mace,腾讯的FeatherCNN(腾讯AI)和ncnn(腾讯优图),百度的Paddle-moblie等,阿里也开发了自己的移动端深度学习框架MNN。近期,阿里巴巴开源了基于MNN引擎的项目MNNKit,适用于Android和iOS,以SDK的形式提供AI端到端推理能力。开发者无需了解算法细节即可直接使用。项目地址:https://github.com/alibaba/MNNKit目前MNNKit已经具备了人脸检测、手势识别、人像分割等功能,未来可能会有更多的API接入。MNNKit:基于MNN的深度学习工具MNN是基于阿里MNN推理引擎开发的终端应用解决方案,主要面向Android和iOS系统,帮助AI能力在实际移动场景中的应用。MNNKit架构MNNKit提供了SDK供开发者使用,以下是SDK架构。从图中可以看出,MNNKit可以分为三层,从下到上分别是:MNN引擎层,是MNN(https://github.com/alibaba/MNN)库编译在Android上的封装/iOS的二进制Release版本,提供端到端的操作环境。核心基础层,主要对上层API进行抽象和封装,调用粒度与MNNc++接口相同。iOS通过OC接口提供,Android通过Java接口(TODO)提供。这一层也为上层SDK提供了一些公共服务类或者结构体定义。业务Kit层包括人脸检测和手势识别封装的API。根据项目介绍,后续业务Kit层将不断扩展。内部原理由于MNNKit主要提供阿里端到端的AI能力,因此封装了很多相关应用的API。调用方式如下:比如当用户需要调用某个API时,需要先创建一个实例,然后输入图片、视频或其他结构化数据,进行AI模型的推理工作。工作完成后释放实例即可。MNNKit目前支持的API有:人脸检测API手势识别API人像分割API以人脸检测为例,检测内容主要分为三部分:人脸基本信息、人脸位置直角坐标、106个关键点坐标(区分遮挡和未遮挡)106个关键点的置信度分布(来自官方开源github)人脸各区域关键点分布对应表欧拉角摇头(Yaw)、点头(Pitch)、倾斜头(roll)三个角度值人脸运动(包括5个人脸运动)眨眼、张嘴、摇头、点头、扬眉处理过程我们知道了人脸检测需要检测的数据之后,我们来看一下处理过程:如图所示,流程为iOS和Android设备后置摄像头向前拍摄后移动端的整体处理流程。首先,系统从摄像头获取数据作为SDK的输入。接下来SDK会进行如下操作:在MNN引擎进行推理之前,对原始输入进行预处理,确保输入数据中的人脸为正脸,并使用AI模型进行推理;推理后,根据输入(预处理后坐标系的关键点结果;.将关键点坐标变换到与屏幕渲染坐标系相同的方向,以方便渲染。在程序应用中,关键点最终的结果应该显示在用户的屏幕上,前端会使用一个“画布”进行渲染,画布的坐标系称为渲染坐标系,在SDK检测的最后一步,我们对key进行变换指向与渲染坐标系相同的方向,然后将关键点坐标按比例映射到渲染坐标系的坐标上,映射后可以直接渲染到canvas上代码示例MNNKit提供示例代码包括人脸检测,手势recognition等。下面我们以人脸检测为例,看看如何调用Android或者iOS中的API进行推理。上面Android代码中提到,调用API需要先创建一个实例。下面是在主线程中异步创建FaceDetector实例和回调代码。publicstaticvoidcreateInstanceAsync(Contextcontext,FaceDetectorCreateConfigcreateConfig,InstanceCreatedListenerlistener)这里,人脸检测API会检测和跟踪两个动作。检测受面部位置和关键点的影响,而跟踪是通过在面部移动时重新定位关键点位置来完成的。视频模式下,系统默认每20帧检测一次,其余帧只进行跟踪。在图像模式下,每次调用时都会检测到它。创建实例后,可以将数据输入模型进行推理。MNNKit现在支持多种数据格式输入。在视频流检测场景中,我们可以使用摄像头的回调数据作为接口的输入。输入数据代码如下:publicsynchronizedFaceDetectionReport[]inference(byte[]data,intwidth,intheight,MNNCVImageFormatformat,longdetectConfig,intinAngle,intoutAngle,MNNFlipTypeoutputFlip)输入数据为位图的推理代码如下:publicsynchronizedFaceDetectionReport[]inference(Bitmapbitmap,longdetectConfig,intinAngle,intoutAngle,MNNFlipTypeoutputFlip)当FaceDetector实例用完后,我们需要手动释放实例,否则会出现nativememoryleaks。publicsynchronizedvoidrelease()iOS代码和Android代码类似,首先需要创建一个人脸检测实例:+(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*)inference:(CVPixelBufferRef)pixelBufferConfig:(MNNFaceDetectConfig)detectConfigAngle:(float)inAngleOutAngle:(float)outAngleFlipType:(MNNFlipType)flipType错误:(NSError*__autoreleasing;UI*Imager)输入推断的代码如下:-(NSArray*)inferenceImage:(UIImage*)imageConfig:(MNNFaceDetectConfig)detectConfigAngle:(float)inAngleOutAngle:(float)outAngleFlipType:(MNNFlipType)flipType错误:(NSError*__autoreleasing*)error;使用通用缓冲区数组输入的代码如下:-(NSArray*)inference:(unsignedchar*)dataWidth:(float)wHeight:(float)hFormat:(MNNCVImageFormat)formatConfig:(MNNFaceDetectConfig)detectConfigAngle:(float)inAngleOutAngle:(float)outAngle翻转类型:(MNNFlipType)翻转类型错误:(NSError*__autoreleasing*)error;实例生命周期结束后,会自动触发释放相关内存,无需调用方手动释放成熟的解决方案,经过双十一等项目测试,在不依赖的情况下进行高性能推理后台稳定,使用方便。