【CANN训练营进阶班应用课笔记】在Atlas 200DK上体验DVPP、AIPP和OM推理

根据进阶班作业贴:https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=182679&fromuid=446160
大作业附加题如下:
开发推理应用,该应用中需要对输入图片或视频进行预处理,再进行模型推理。
根据作业提示,实现的思路如下:
由于YoLoV3的模型推理需要RGB图片,且需要416X416分辨率。
(1)原始图片-》DVPP JPEGD解码-》YUV图片(原始分辨率)-》DVPP resize成416X416的YUV图片(可选)-》送给om模型推理(其中可以在atc转换时AIPP设置 YUV转RGB,以及resize成416X416)-》模型结果图片-》DVPP VPC转换-》输出结果图片
(2)原始视频-》VENC转换-》H264码流文件-》DVPP VDEC转换-》YUV图片(原始分辨率)-》resize成416X416的YUV图片(可选)-》送给om模型推理(其中可以在atc转换时设置 YUV转RGB,以及转416X416的resize)-》模型结果图片-》DVPP VPC转换-》输出结果图片 (如果是多张模型结果图片或许可以拼成输出结果视频)
下面看看如何实战。
一、YoLoV3模型转换
先打开作业提供的YoLoV3模型链接:https://gitee.com/ascend/ModelZoo-TensorFlow/tree/master/TensorFlow/contrib/cv/yolov3/ATC_yolov3_caffe_AE
在200DK上下载caffe模型和aipp的配置文件:
mkdir yolov3
mkdir models



如下所示:

使用页面提供的方式进行模型转换:
atc --model=yolov3.prototxt --weight=yolov3.caffemodel --framework=0 --output=yolov3_framework_caffe_aipp_1_batch_1_input_int8_output_FP32.om --soc_version=Ascend310 --insert_op_conf=aipp_nv12.cfg

转换成功(当然,AIPP未必是我们所想要的配置,需要稍后再细看)
二、YoLoV3模型的msame推理性能测试
验证下页面上提到的msame工具推理:
git clone https://gitee.com/ascend/tools.git

export DDK_PATH=/home/HwHiAiUser/Ascend/ascend-toolkit/latest
export NPU_HOST_LIB=/home/HwHiAiUser/Ascend/ascend-toolkit/latest/acllib/lib64/stub
并验证下这两个环境变量的有效性:

cd $HOME/tools/msame/
chmod +x build.sh

./build.sh g++ $HOME/tools/msame/out

执行推理性能测试:
./msame --model ../../../yolov3/models/yolov3_framework_caffe_aipp_1_batch_1_input_int8_output_FP32.om.om --output ../../../yolov3/msame_infer --outfmt TXT --loop 100


平均推理性能在10ms左右。
这里有推理性能测试的时候产生的文件:

三、尝试动态AIPP的YoLoV3样例
打开samples仓库中YoLoV3的样例页面:https://gitee.com/ascend/samples/tree/master/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_dynamic_AIPP
这个样例使用的模型正好是前面下载的模型。
但是AIPP的配置文件好像文件名不一样,那就下载一下试试:

这个采用的是动态AIPP的方式,所以配置文件好短:

像原来那个配置为:

倒确实是416X416的分辨率。
既然随机选中了动态AIPP的YoLoV3的代码,那么就只好再atc做个模型转换,生成新的om文件:
atc --model=./yolov3.prototxt --weight=./yolov3.caffemodel --framework=0 --output=./yolov3 --soc_version=Ascend310 --insert_op_conf=./aipp_objectdetection.cfg

进入sample样例仓的对应目录:
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_dynamic_AIPP/scripts
编译代码
bash sample_build.sh

切换到 ../model 目录,将前面atc编译好的动态shape的模型拷贝过来:

再回到scripts目录重新编译:bash sample_build.sh

运行样例程序:
bash sample_run.sh

切换到 ../out/output目录

将图片下载下来看看:

顺便把在data目录下的原始图片也下载下来:

在windows上分别打开:

原始图片:

结果文件:

名字带opencv的:

至于后面两个有什么区别?得看看源码才知道。
四、动态AIPP的YoLoV3样例的源码原理解读
这个动态AIPP的代码,列出了2种情形,一个是通过dvpp处理的 推理,包括前处理,om推理和后处理,一个是通过opencv处理的前处理,om处理和后处理。因为这两个场景,om之前的输入(可能)是不一样的。所以 om处理部分就搞了动态aipp。
(object_detect.cpp)
dvpp的那种处理方式,前处理就是dvpp做jpg-》yuv,然后dvpp做resize,然后送om推理
opencv的前处理呢,是 先做色域转换,转rgb,然后resize。然后送om推理。

所以,,个人理解,对于离线模型而言,在om遇到 dvpp来的yuv格式,就需要在aipp里面完成 转rgb的动作。但是opencv送来的就不需要。所以这个时候就需要动态aipp。
参看 官网文档:https://support.huaweicloud.com/atctool-cann504alpha5infer/atlasatc_16_0018.html
”如果模型转换时设置了动态AIPP,则使用应用工程进行模型推理时,需要在aclmdlExecute接口之前,调用aclmdlSetInputAIPP接口,设置模型推理的动态AIPP数据“
所以我们分别看一下 dvpp和opencv两种不同的情形下,是怎么调用aclmdlSetInputAIPP接口的:
(model_process.cpp)
其实 CreateInput和CreateInputOpenCV的代码好像是一模一样的。只有SetAIPPTensor和SetAIPPTensorOpenCV的区别。
所以区别最大的应该在这里:
dvpp:

opencv:

目测这个dvpp的那个配置,跟我们前面下载的 aipp_nv12.cfg基本上是一模一样的:

所以,这表明,静态AIPP,是将aipp的config文件处理通过atc,编译到了om模型里面,而动态AIPP,是在调用的时候,通过大量的aclmdSetAIPPxxxxx函数来设置这个值。
五、准备要解析的动物视频MP4
好了,既然已经理解了代码。。。
我们就继续做作业吧。
话说前面两个要求,模型转换成功,和样例成功运行,这个应该是都完成了。

下面就得拿自己的图片或者视频来推理了。
但是有一点需要注意的是:YoLoV3不是啥玩意儿都能识别出来的。根据当时训练模型的数据集的不同,识别的结果也不同。范例使用的是coco数据集。
在目前这个代码中,有个默认的分类:

所以务必我们要找一个有这些图片分类的视频和图片来做推理会比较好。
看分类里面,动物居多。张小白不由自主想起了《动物世界》和《人与自然》。
搜索到了 https://haokan.baidu.com/v?pd=wisenatural&vid=6101357277280504775
然后 通过下载 XX视频的下载方式,将其保存到了手机相册:

然后再传到电脑中:

我们就得到了这个视频。
找一下zebra或者horse吧:0:34~0:36 大约2秒:左右。

先用格式工厂剪辑出这2秒的视频(MP4, H264)。
跟前面的过程一样,这里不详述,贴图简单示意下:
格式工厂打开MP4:

设置输出格式为H264

截取33秒到35秒内的视频,进行转换:

转换完成,结果为226K

生成的结果在D:\FFOutput目录下:

将其使用MobaXterm上传到200DK:

查看上传的文件

发现文件名中间有个空格,不大好使,那就更名一下:

换成了animal.mp4.简单易懂。
六、视频编码VENC将MP4转成H264
切换到venc目录下,将该MP4文件拷贝到data目录下:

修改scripts/samle_run.sh,将MP4文件名写进去:

运行bash sample_run.sh获得转换后的多个H264文件:

去out/output下查看结果:

一共40多个h264文件。
七、视频解码VDEC将H264转成YUV
切换到vdec目录下,将刚才的结果文件拷贝过来:

修改vdec的main.cpp中的 inputWidth和inputHeight为 854,474(可参看前面格式工厂中的分辨率显示)

vdec重新编译:

修改vdec的 sample_run.sh
直接前面45个吧:

vdec执行 bash sample_run.sh

到vdec的out/output查看生成的结果:

八、图片解码JPEGE将YUV转成JPG
将其拷贝到jpege的data目录下:

修改jpege的sample_run.sh

运行:

查看结果文件:

九、OM模型推理生成结果JPG图片
将其拷贝到yoloV3的例程的data目录下:

执行yoloV3推理:


检查输出结果:

十、检查运行结果
使用MobaXterm将结果目录下载到windows本地:

打开本地目录查看推理结果图片:

其中:

这个应该是豹子吧。识别成了熊。。。错了。

这三个斑马的识别成功了。

左一的斑马识别出来了。右边好几个,因为图片不全,就没识别出来。

反正奔跑中的不大好识别。

特别是这种,朝着屏幕跑的,居然认为是只鸟。。。

当然,瞬间又变成了斑马.

它如果跑得飞了起来,就变成了鸟。
总之,应该识别得还行吧。。毕竟图片不是很清晰。才854X474这样的分辨率。
不过这样,作业大体上算是做完了吧。
只是实在没工夫串起这么一大长串的代码了。(原理上,venc->vdec->jpege->yolov3全部串起来。前面输入mp4,后面返回多张图片,这样应该是完美的作业。。)
然而,大家要接受张小白的不完美之处。对吧?
(全文完,谢谢阅读)
- 点赞
- 收藏
- 关注作者
评论(0)