昇腾NPU人脸仿射变换性能优化
人脸仿射变换是人脸识别过程中常见人脸对齐的一处理手段。本文介绍利用Atlas的内置的算子实现在芯片上完成人脸仿射变换的计算过程。
在人脸识别过程中,典型的流程先是对用一个目标检测模型检测画面是否包含人脸,如果是则把人脸从画面中扣出,由于在现实中捕获到的画面,人脸的姿态并不一定是正对镜头,所以需要做人脸对齐,把俯视、仰视等姿态矫正为正视的形态。
仿射变换是人脸对齐的一种方法,基本原理就是对在二维的平面里面做平移、变换、旋转等操作。由于我们客户通过模型获得到人脸的特征关键点,通过平移转换关键点就可以获得到对齐的人脸。
仿射变换的计算公式为
但是这里就不展开公式的说明,如果想深入了解,推荐阅读这篇文章 https://www.cnblogs.com/shine-lee/p/10950963.html
在实际项目中,我们只需要了解已知道人脸的关键点,通过这个公式达成人脸对齐的结果。
案例分享
以下图为例子,
画面中的人物侧身,第一步通过模型把人脸目标检测出来
找出画面中人脸的关键点,如下图
通过5个关键点的位置,我们计算平移参数,然后通过仿射变换公式计算图片最终得到转换后的坐标
在常见的GPU方案中,这个计算过程通常都是由CPU完成的。一张JPEG的图片需要先使用OpenCV解码成Bitmap位图,解码完成的Bitmap在Host保存一个副本,另外一份送入到GPU做模型推理,检测到人脸获取人脸区域框坐标以及关键坐标点返回到Host
Host通过对图片裁切,做仿射变换最后得到矫正的图片再送入GPU做下一步操作,整个如下图
虽然仿射变换的计算资源消耗非常小,但是这个方案图片的搬移拷贝是一个相对耗时的操作,并且由于在CPU侧解码数据膨胀数倍再搬移到GPU,做完仿射变换后又做一次搬移,这部分会消耗非常多的资源。
对于这种场景昇腾NPU有什么更好的方案呢?
在昇腾NPU方案中,我们可以利用NPU上的媒体处理硬件模块DVPP,以及内置的SpatialTransformer算子结合把整个流程都在芯片内完成。
第一步需要先用昇腾ATC工具把内置的SpatialTransformer算子转换成OM文件,最后通过单算子调用的方式来完成人脸仿射变换。整体的流程如下
Host端把待处理的图片送入到NPU上,调用DVPP模型对图片解码,解码完成后送入人脸检测模型做推理得到人脸的矩形框坐标以及关键点坐标。Host侧获取推理结果,计算出人脸需要偏移的参数,Host调用DVPP图片裁切Crop的接口裁切图片,然后做为输入参数单算子调用SpatialTransformer
下面是详细的操作步骤
- 使用ATC把内置算子SpatialTransformer转换成OM
SpatialTransformer的参数参考
https://support.huaweicloud.cn/oplist-cann503alpha2infer/operatorlist_0056.html
算子SpatialTransformer需要输入两个参数
- 参数x代表输入的图片,NCHW数据排布,数据类型是fp16或者fp32
- 参数theta 代表的人脸的6个变换的参数θ
- 输出参数y代表的是NCHW的张量
对于参数x,由于经过DVPP解码后的图片是YUV420SP的格式,在单算子调用时候需要AIPP做色域转换和归一化处理
参数theta可以通过算子的属性描述,theta_1_1,theta_1_2,theta_1_3,theta_2_1,theta_2_2,theta_2_3 一共6个 ,如果6个算子全部在属性里面设置那么,参数theta就不需要填写,这个方法的缺点是6个参数都是固定的不可以修改。
那么参数theta如何使用?实际它是描述参数的shape,格式是[n,size]
这个n代表的是batch size, size代表参数的大小。举个例子,[1,2]标示batch size是1 ,2标示有2个theta参数的数组。
再举个例子,如theta_1_2=1,theta_2_1=2,theta_2_2=3,theta_2_3=4 注意观察到这里4个参数通过算子的属性设置好了,但是有两个theta_1_1和theta_1_3没有设置,那么我们输入参数theta的shape 是[1,2] 其中2标示有2个参数,最后输入的数值如果是input theta=[9,8],9对应theta_1_1, 8对应theta_1_3 则最终的theta是: 9,1,8,2,3,4
同理,如果6个theta都是动态需要参数输入,则参数theta 标示[1,6],我们在入参的数值只需要输入一个6个长度的数组
下面是SpatialTransformer单算子调用的参考文件,输入的是48x48的图片以及 数组长度为6的theta参数
使用ATC转换令转换单算子
特别需要注意的是:目前SpatialTransformer对应CANN的最低版本要求是CANN 5.0.3 低于此版本的无法运行
- 单算子调用
单算子调用的代码比较多,无法这里列出,需要参考
https://support.huaweicloud.cn/aclcppdevg-cann503alpha2infer/atlasdevelopment_01_0103.html
最后,一些工程实现的细节
由于画面中检测出来的人脸框大小不固定,然后我们在单算子转换时候却是固定shape输入,比较简单的办法是设计多个不同参数的输入,比如40x40 48x48等待每个不同尺寸重新生成一个单算子模型
- 点赞
- 收藏
- 关注作者
评论(0)