ModelArts训练出模型后,是可以部署为云端的在线服务,还有一种很常见的部署,那就是要部署到端侧,贴近场景进行推理应用。 当然这里有一个前提是模型需要转换为适合于端侧部署的模型,目前是手工操作的。 一旦有了适合于端侧部署的模型,ModelBox开发套件就可以大展身手了,从有了模型,到成功部署、将端侧应用跑起来和用起来,整个流程比较行云流水,提高了不少的效率。 以下是体验试用的一个小汇总,体验还在继续进行中.... ------------ 试用一个月,完了要还回去,不知道这个开发套件需要多少钱,反正拿到了开发套件是挺开心的。 拿到之后,就参照[《上手指南》](https://developer.huaweicloud.com/develop/aigallery/article/detail?id=0163b46b-34fa-468d-b243-2ef067170d4a)开始动手了。 把东西拿出来摆放整齐后是这个样子:  安装一半后是这个样子:  板子上电带系统启动后是这个样子:  首先是操作系统的制作,没有系统板子上电后只是一个绿灯常亮。系统启动镜像要写到tf卡里(Micro SD),刚好家里有一个读卡器可以写。镜像读写工具 balenaEtcher 下载很慢,我是个急性子,等不及就放弃了。想在Linux下面解压后再想办法写入,不需要下载什么工具。于是把我一直吃灰的Ubuntu20.04打开,果然有超预期表现:右键就有“用磁盘映像写入器打开”(注意图中20220707的镜像制作的有些问题,无线网卡驱动没有加载上,最后还是用老的镜像)  将镜像写入到32G的TF卡中:  写完了:  系统成功启动后,下一步就是要登陆上开发版。按照指南,有两种方式。 1. 开发板连接显示器和键盘鼠标,安装Ubuntu桌面,直接在开发板上进行开发; 2. 使用远程连接工具(如VS Code中的Remote-SSH)从PC端登录开发板进行开发。 相对于去找网线配置网络,我更愿意去把键盘和鼠标找出来,然后将hdmi连上我的荣耀智慧屏作为显示器。  这不就可以登陆上系统了吗?然后用 nmcli 命令连上无线网。这样板子连上网之后,后面就好办了。 也把桌面 mate 安装上了,大约1300个包,要下载700兆(解压后3.6G)。所以事先把系统源替换到华为云镜像,比较尴尬的是华为云镜像ubuntu arm版本比较老,所以替换为阿里云。 安装好后重启就可以进入桌面了,这个55寸荣耀智慧屏是最开始推出时就买来的,很优惠,不到两千块钱。虽然现在系统使用有点卡,但是解码播放4K视频从来不卡。进入桌面后它自动适配的分辨率就是4K。  看一下系统信息:  进入桌面后,操作上感觉比较卡,而且频繁的进入桌面后不久就自动重启。原因可能有分辨率过高,一些系统进程( `unattended-upgrade` )占用太多CPU,开发版内存比较小(只有4G),做了一些调整降低为1K分辨率和关闭自动升级。只是后来是用ssh登录,也就没再去使用桌面了。 接下来就是按照指南,在HiLens管理控制台专业版进行`设备注册`、`下载固件(Device_Agent)和证书`,`传送到开发板进行安装`。还有一步`激活设备`在指南里没有写,用十元优惠券激活一个月。 以上都是一些开发环境的准备工作,再接下来就是下载sdk,进入真正的开发了。 ------------ 这一部分用SDK做了2个案例: 1. 在视频文件/视频流上添加文字 试用首先考虑的效率问题,不考虑安全问题,所以直接用root用户操作。 后面会用到一些库,所以先apt安装`dos2unix`,pip3安装`numpy opencv-python` 将SDK `modelbox-rk-aarch64-1.0.9.6.tar.gz` 解压后,内容如下 ```html root@rock-3a:~/sdk# tree -L 2 --dirsfirst |-- modelbox-rk-aarch64 | |-- bin/ | |-- doc/ | |-- etc/ | |-- flowunit/ | |-- include/ | |-- lib/ | |-- solution/ | |-- template/ | |-- www/ | |-- Third_Party_Open_Source_Software_Notice | |-- modelbox-1.0.0-py3-none-any.whl | `-- version |-- create.py |-- env_set.sh |-- mb-pkg-tool |-- obsutil `-- solution.py ``` 使用 `create.py` 创建hello_world工程后,目录是这样的 ```html `-- hello_world |-- CMake | |-- FindFFMPEG.cmake | `-- Function.cmake |-- bin | |-- main.sh | `-- mock_task.toml |-- data/ |-- dependence | |-- modelbox_requirements.txt | `-- readme.txt |-- etc | `-- flowunit/ |-- flowunit_cpp | `-- CMakeLists.txt |-- graph | |-- hello_world.toml | `-- modelbox.conf |-- hilens_data_dir/ |-- model/ |-- CMakeLists.txt |-- build_project.sh `-- rpm_copyothers.sh ``` 在工程中创建一个叫做draw_text的 `python flowunit` 后,在etc/flowunit下新增了draw_text目录,是这样的: ```html |-- etc | `-- flowunit | |-- cpp | |-- draw_text | | |-- draw_text.py | | `-- draw_text.toml | `-- readme.txt ``` 然后修改`功能单元的处理逻辑`,即`draw_text.py`里的`process`函数,加上在视频帧上打出文字hello world的动作。 修改`hello_world.toml`流程图的配置。 将SDK里自带的一个mp4文件`car_test_video.mp4`拷贝到data目录中。 修改`mock_task.toml`里面的`任务的输入输出配置`,为使用本地mp4文件。输入文件为`../data/car_test_video.mp4`,输出文件为`../hilens_data_dir/hello.mp4` 执行`build_project.sh`进行工程构建。很快,不知道构建了个啥。 执行 `main.sh` 运行应用。 输出有些报错,可以不用管, ```html [2022-07-23 04:31:28,100][ WARN][ timer.cc:208 ] Schedule timer failed, timer is not running. [2022-07-23 04:31:28,100][ERROR][iva_auth_info_updater.cc:29 ] IvaManager::SetIAMAuthInfo Not enough meassage. userId and (domain_id or vas_x_role_name) is empty. [2022-07-23 04:31:28,100][ INFO][iva_auth_info_updater.cc:63 ] IvaManager::SetIAMAuthInfo Not enough meassage. ak is empty. [2022-07-23 04:31:47,109][ INFO][flow_scheduler.cc:397 ] shutdown flow scheduler. [2022-07-23 04:31:47,109][ERROR][flow_scheduler.cc:377 ] the scheduler caught an error : Stop operation [2022-07-23 04:31:47,115][ INFO][ job_manager.cc:82 ] delete job : IVA_JOB ``` 因为目标文件生成了,播放时有Hello World文字在上面的效果。  再试一下视频流,把摄像头插上开发板上,用`lsusb`可以看到系统识别到了: ```shell Bus 007 Device 002: ID 0c45:64ab Microdia HX-USB Camera ``` 将`hello_world.toml`另存为`hello_world_camera.toml`,在文件里将`video_demuxer`和`video_decoder`去掉,改为`local_camera`。 再修改`mock_task.toml`里面的`任务的输入输出配置`,输入使用摄像头,输出到rtsp,地址为PC上的推流服务。然后在PC上启动windows下的SDK里的`connect_wizard`,使用`开发板侧视频流`启动推流。 执行 `main.sh camera`指定使用配置文件`hello_world_camera.toml`来运行应用: ```bash [2022-07-23 08:04:25,931][ INFO][video_out_flowunit.cc:305 ] video_out url is rtsp://192.168.3.8:8554/outstream [2022-07-23 08:04:25,931][ INFO][video_out_flowunit.cc:266 ] videoout url=rtsp://192.168.3.8:8554/outstream [2022-07-23 08:04:25,946][ INFO][ ffmpeg_writer.cc:55 ] Open url rtsp://192.168.3.8:8554/outstream, format rtsp success ``` 浏览器里自动打开输出实时画面,有添加文字效果。  2. 视频文件做车辆检测 用检测模型检测出`视频画面中车辆并画框`,输入输出都是视频文件。这个应用作为模板案例已内置在sdk中,不需要另外下载。 先用`create.py`创建`car_det`工程,这次加了一个选项 `-s car_det`,代表使用这个`solution`来创建。可以看到工程目录如下: ```html root@rock-3a:~/sdk/workspace/car_det# tree -L 4 --dirsfirst . |-- CMake | |-- FindFFMPEG.cmake | `-- Function.cmake |-- bin | |-- main.sh | `-- mock_task.toml |-- data | |-- car_test_pic.jpg | |-- car_test_video.mp4 | `-- test_http.py |-- dependence | |-- modelbox_requirements.txt | `-- readme.txt |-- etc | `-- flowunit | |-- cpp | |-- draw_car_bbox | | |-- draw_car_bbox.py | | `-- draw_car_bbox.toml | |-- yolox_post | | |-- yolox_post.py | | |-- yolox_post.toml | | `-- yolox_utils.py | `-- readme.txt |-- flowunit_cpp | `-- CMakeLists.txt |-- graph | |-- car_det.toml | |-- car_det_http.toml | |-- car_det_server.toml | `-- modelbox.conf |-- hilens_data_dir |-- model | `-- yolox_infer | |-- yolox_infer.toml | `-- yolox_nano_288x512.rknn |-- CMakeLists.txt |-- build_project.sh `-- rpm_copyothers.sh ``` 目录中有模型推理单元`yolox_infer`,包含yolox模型文件和模型配置文件。ModelBox内置了rknn推理引擎和推理逻辑,开发者不需编写推理代码。此模型由PyTorch框架训练得到,事先使用[rknn-toolkit2](https://github.com/rockchip-linux/rknn-toolkit2)工具将它转换为RK3568支持的模型格式,可以在[RK3568模型转换验证案例](https://developer.huaweicloud.com/develop/aigallery/notebook/detail?id=a7072b40-690e-4d98-be64-64a00f6fc69a)中查看模型转换过程。 推理后的后处理在flowunit里,有`yolox_post`和`draw_car_bbox`,做后处理,然后做画框展示。 工程有3个流程图。默认流程图是`car_det.toml`,运行它来看看效果,先`build_project.sh`再`main.sh`运行,12秒的视频,处理耗时48秒: ```html [2022-07-23 09:26:55,104][ INFO][ ffmpeg_writer.cc:55 ] Open url /root/sdk/workspace/car_det/bin/../hilens_data_dir/car_test_result.mp4, format mp4 success [2022-07-23 09:27:43,049][ INFO][ffmpeg_video_demuxer.cc:147 ] Stream /root/sdk/workspace/car_det/bin/../data/car_test_video.mp4 is end ```  在来看http服务,输入一个图片,给出检测结果图片的。运行`main.sh http`指定使用`car_det_http.toml`流程图: ```html [2022-07-23 09:52:01,939][ INFO][httpserver_sync_receive.cc:188 ] Start server at http://0.0.0.0:8083/v1/car_det ``` 使用`test_http.py`调用这个http服务: ```json root@rock-3a:~/sdk/workspace/car_det/data# python test_http.py test_http.py:33: DeprecationWarning: tostring() is deprecated. Use tobytes() instead. img_str = cv2.imencode('.jpg', img_data)[1].tostring() response: {"det_result": "[[0.07672460377216339, 0.3569239377975464, 0.2763637900352478, 0.7063356041908264, 0.7665719985961914, 2.0], [0.6121819615364075, 0.09047098457813263, 0.7309271693229675, 0.28249451518058777, 0.72760009765625, 2.0], [0.38874685764312744, 0.17702166736125946, 0.4968656301498413, 0.36404821276664734, 0.6740775108337402, 2.0], [0.2635308504104614, 0.0011769375996664166, 0.3374212980270386, 0.02468840591609478, 0.34745872020721436, 2.0]]"} ``` 查看生成的结果文件:  到这里就告一段落。 ------------ 这一部分是:使用yolov3做口罩检测 口罩检测不同于车辆检测,车辆检测内置于SDK中,模型文件、相关配置都作为解决方案提供了,创建好工程就在那里了。而口罩检测需要自行下载模型和配置文件,并放置到对应的工程目录,其实也很方便。 [下载地址](https://e-share.obs-website.cn-north-1.myhuaweicloud.com/?token=0awK+RuZ0De/GWps7y6qRVUhiXBsrkH2u+k5falBeP5XXOarM+Di1r8ihSd3itx9pxg+nA9lLRCNJO7VSLN/lshflsGfY/h2grPHXTypyDCJdYuB/B+D2hKo4iJ2B7PtAIOf4URv6Hswp36TKPJ8w+r4eE4WXqKEIfEeS/A+AnTMW5Qytd+kQhtN1c1FdCLj5jBza4nBK0urxGiS4YI2Q6boNdz8Mv5eJAXDOBm5V2phU5P6DP1E9409/ZTWYBDhWHui3OczoHLjIzh3xUltlClfy6DyoKAzkshw9LrFOInUyUhfnihJzag95HFiETwq2e0gn3VHmM+cXcijxt+QP5JwFMwZLWBbFUw6V5eGXJRnaIMW97Hfqfb3wLCe//RNigcP4L4JJ3YOvENQWJxxC3rl6uvo2zFlDkbuKdMqfFM1UlB/8HpYsrlKXrKRI092ai4E2Xh6VRs0tl7m0HQOzDJWwv4WpZ2v8YNX9hNskNbbiayscw9gEY4iwpFSykdGzNK5Enb63QiNbuYFBGdmtUMvp1DDqEpTBi4+VzzXNn2xjUo2qu2FQq6QAfLBzcmh+SiGJ5bGQaMhxb6mEQwzj4qoVJ5C6PoonbPqWqIkdV4=),提取码 modbox 选择`common.zip`(功能单元和配置、任务配置、测试视频 5M) 和`rknpu2.zip`(推理功能单元和流程配置 14M)下载即可。 仍然是先用 `create.py` 创建名为`mask_det_yolo3`的工程,然后用`-t infer`选项创建一个名为`mask_infer`的推理功能单元,会在工程目录的model下生成以下内容 ```html |-- model | `-- mask_infer | `-- mask_infer.toml ``` 将rknpu2.zip里面的rknn模型文件和2个配置文件放入(覆盖原mask_infer.toml): ```html workspace/mask_det_yolo3/model/mask_infer/ |-- mask_infer.toml |-- yolo3_resnet18_mask_det_288x512.toml `-- yolo3_resnet18_mask_det_288x512_rknpu2.rknn ``` `mask_infer.toml`里定义了三个模型的输出,应该是对于`head头肩部`、`face`、`mask口罩`的信息。 接下来使用参数`-t python`创建2个功能单元,分别是`yolo3_post`后处理,和`draw_mask_bbox`在原图上画框展示,生成内容如下: ```html workspace/mask_det_yolo3/etc/ `-- flowunit |-- cpp |-- draw_mask_bbox | |-- draw_mask_bbox.py | `-- draw_mask_bbox.toml |-- readme.txt `-- yolo3_post |-- yolo3_post.py `-- yolo3_post.toml ``` 将common.zip里面的功能单元内容复制进去覆盖原文件。 带没带口罩的结果的展示,其逻辑是在画图单元实现:如果face检测框与mask检测框的`重合度`大于某个阈值,就判为佩戴口罩;否则,就判为没有佩戴口罩;如果没有检测到face检测框,就会显示Unknown。 接下来就是`串流程图`(graph/mask_det_yolo3.toml),和`配置任务的输入输出`(bin/mock_task.toml),当然下载里都有已经配置好的文件,拷贝到对应目录。同时把测试视频也拷贝到data目录。 `mask_det_yolo3.toml`里定义了: 各个功能单元的处理流转流程 ```c data_source_parser > video_demuxer > video_decoder > image_resize > mask_detection > yolo3_post > draw_mask_bbox > video_out ``` 以及 功能单元之间的输出输入之间的接口对接配置,比较细节就不说了。 配置任务的输入输出在hello_world和车辆检测部分说过,也不说了。 准备工作到此结束,下面就是进入工程目录,进行`build_project.sh`然后`bin/main.sh`运行应用进行视频文件的戴口罩检测,并输出结果到视频文件。  下载的里面还有一个camera的配置文件,是可以将输入输出都配置为视频流来使用的,这个晚点再试一下。
黄生
发表于2022-07-29 07:42:18
2022-07-29 07:42:18
最后回复
101