# RTMHumanKeypointsDetection **Repository Path**: wa_wwd/rtm-human-keypoints-detection ## Basic Information - **Project Name**: RTMHumanKeypointsDetection - **Description**: 基于MindX SDK,在昇腾平台上,开发的实时视频人体关键点检测(Real Time Human Keypoints Detection)参考设计 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2022-07-29 - **Last Updated**: 2024-05-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MindX SDK -- 实时人体关键点检测 ## 1 案例概述 ### 1.1 概要描述 在本系统中,目的是基于MindX SDK,在昇腾平台上,开发端到端实时视频**人体关键点检测**参考设计,实现其功能,并满足任务的相关要求。 ### 1.2 模型介绍 本项目主要用到了用于人体关键点检测的OpenPose模型: OpenPose模型相关文件可以在此处下载:https://github.com/Daniil-Osokin/lightweight-human-pose-estimation.pytorch ### 1.3 实现流程 1、基础环境:Ascend 310、mxVision、Ascend-CANN-toolkit、Ascend Driver 2、模型转换:pytorch模型转昇腾离线模型:checkpoint_iter_370000.pth --> openpose_pytorch_368.om 3、业务流程编排与配置 4、mxpi_rtmopenposepostprocess插件的后处理库开发 技术流程图如下: ![pipeline](image/pipeline.png) ## 2 软件方案介绍 ### 2.1 项目方案架构介绍 本系统设计了不同的功能模块。主要流程为:视频拉流传入业务流中,然后通过解码插件对视频进行解码,再对解码出来的YUV图像进行尺寸调整,然后利用OpenPose模型进行人体关键点检测,然后我们自己编写的后处理插件会把人体关键点信息传递给绘图插件,绘图完毕后进行视频编码,最后把结果输出。各模块功能描述如表2.1所示: 表2.1 系统方案中各模块功能: | 序号 | 子系统 | 功能描述 | | :--- | :--------- | :----------------------------------------------------------- | | 1 | 视频拉流 | 调用MindX SDK的 **mxpi_rtspsrc**接收外部调用接口的输入视频路径,对视频进行拉流 | | 2 | 视频解码 | 调用MindX SDK的**mxpi_videodecoder** | | 3 | 图像缩放 | 调用**mxpi_imageresize**对解码后的YUV格式的图像进行指定宽高的缩放 | | 4 | 检测推理 | 使用已经训练好的OpenPose模型,检测出图像中的车辆信息。插件:**mxpi_tensorinfer** | | 5 | 模型后处理 | 使用自己编译的**mxpi_rtmopenposepostprocess**插件的后处理库libmxpi_rtmopenposepostprocess.so,进行人体关键点检测的后处理 | | 6 | 绘图 | 调用OSD基础功能在YUV图片上绘制直线。插件:**mxpi_opencvosd** | | 7 | 视频编码 | 调用MindX SDK的**mxpi_videoencoder**进行视频编码 | | 8 | 输出 | 调用MindX SDK的**appsink**进行业务流结果的输出 | ### 2.2 代码目录结构与说明 本工程名称为RTMHumanKeypointsDetection,工程目录如下图所示: ``` ├── models │ ├── convert_to_onnx.py │ ├── model_conversion.sh │ └── insert_op.cfg ├── pipeline │ └── rtmOpenpose.pipeline # pipeline文件 ├── plugins # 实时人体关键点检测后处理库 │ ├── build.sh │ ├── CMakeLists.txt │ ├── MxpiRTMOpenposePostProcess.cpp │ └── MxpiRTMOpenposePostProcess.h ├── test │ └── main.cpp ├── CMakeLists.txt ├── main.cpp ├── build.sh # 编译后处理插件脚本 └── run.sh # 运行 ``` ## 3 开发环境准备 ### 3.1 环境依赖说明 推荐系统为ubuntu 18.04,环境依赖软件和版本如下表: | 依赖软件 | 版本 | 说明 | | --------- | ------------------ | ----------------------------- | | ubuntu | ubuntu 18.04.6 LTS | 操作系统 | | CANN | 5.0.5.alpha001 | Ascend-cann-toolkit开发套件包 | | MindX SDK | 2.0.4 | mxVision软件包 | ### 3.2 环境搭建 #### 3.2.1 依赖安装 - CANN获取[链接](https://www.hiascend.com/software/cann),安装[参考链接](https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/505alpha001/softwareinstall/instg/atlasdeploy_03_0002.html) - MindX SDK获取[链接](https://www.hiascend.com/software/Mindx-sdk),安装[参考链接](https://www.hiascend.com/document/detail/zh/mind-sdk/204/vision/mxvisionug/mxvisionug_0048.html) #### 3.2.2 环境变量设置 ```bash # 执行如下命令,打开.bashrc文件 vi .bashrc # 在.bashrc文件中添加以下环境变量 export MX_SDK_HOME=${SDK安装路径}/mxVision export install_path=/usr/local/Ascend/ascend-toolkit/latest export PATH=/usr/local/python3.9.2/bin:${install_path}/atc/ccec_compiler/bin:${install_path}/atc/bin:$PATH export LD_LIBRARY_PATH=${install_path}/atc/lib64:${MX_SDK_HOME}/lib:${MX_SDK_HOME}/opensource/lib:$LD_LIBRARY_PATH export GST_PLUGIN_SCANNER=${MX_SDK_HOME}/opensource/libexec/gstreamer-1.0/gst-plugin-scanner export GST_PLUGIN_PATH=${MX_SDK_HOME}/opensource/lib/gstreamer-1.0:${MX_SDK_HOME}/lib/plugins # 保存退出.bashrc文件 # 执行如下命令使环境变量生效 source ~/.bashrc #查看环境变量 env ``` 注:其中SDK安装路径`${SDK安装路径}`需要替换为用户的SDK安装路径,install_path需要替换为用户Ascend-cann-toolkit开发套件包所在路径。 ### 3.3 第三方软件依赖 | 依赖软件 | 说明 | 使用教程 | | -------- | ------------------------------ | ------------------------------------------------------------ | | live555 | 实现视频转rstp进行推流 | [链接](https://gitee.com/ascend/mindxsdk-referenceapps/blob/master/docs/参考资料/Live555离线视频转RTSP说明文档.md) | | ffmpeg | 实现mp4格式视频转为264格式视频 | [链接](https://gitee.com/ascend/mindxsdk-referenceapps/blob/master/docs/参考资料/pc端ffmpeg安装教程.md#https://ffmpeg.org/download.html) | ### 3.4 模型转换 本项目中使用的模型是OpenPose模型,参考实现项目[https://github.com/Daniil-Osokin/lightweight-human-pose-estimation.pytorch](https://github.com/Daniil-Osokin/lightweight-human-pose-estimation.pytorch)。该项目中使用的是pytorch模型,本项目在MindX SDK中需要使用om模型,我们需要对模型进行转换。首先需要将pytorch模型转换为onnx模型,然后使用ATC模型转换工具将onnx模型转换为om模型。 本项目提供了输入尺寸为(368,368)的onnx模型,如不需要修改模型输入尺寸,可直接执行步骤10。 转换步骤如下: 1. 从上述参考实现项目链接下载 pytorch 项目文件,执行命令: ```bash git clone https://github.com/Daniil-Osokin/lightweight-human-pose-estimation.pytorch.git ``` 或者下载zip压缩包再进行解压,得到`lightweight-human-pose-estimation.pytorch-master` 项目文件夹。 2. 按照参考实现项目中的要求配置pytorch环境。 3. 使用本项目目录里 的`models/convert_to_onnx.py`替换`lightweight-human-pose-estimation.pytorch-master/scripts/convert_to_onnx.py`文件。 4. 从参考实现项目中获取pytorch模型文件:[https://download.01.org/opencv/openvino_training_extensions/models/human_pose_estimation/checkpoint_iter_370000.pth](https://download.01.org/opencv/openvino_training_extensions/models/human_pose_estimation/checkpoint_iter_370000.pth),将下载得到的checkpoint_iter_370000.pth模型文件放置在 `lightweight-human-pose-estimation.pytorch-master` 项目目录下。 5. 修改`lightweight-human-pose-estimation.pytorch-master/scripts/convert_to_onnx.py`文件中的`net_input = Variable(torch.randn(1, 3, 368, 368))`行内的`368,368`,改为自己需要修改的尺寸 6. 在`lightweight-human-pose-estimation.pytorch-master` 目录下执行命令 ```bash python scripts/convert_to_onnx.py --checkpoint-path=checkpoint_iter_370000.pth ``` 注: `--checkpoint-path` 参数为下载的pytorch模型文件所在目录,可添加 `--output-name` 参数,指定输出的 onnx 模型文件名,不指定时的默认文件名为 human-pose-estimation.onnx。 7. 将转换成功得到的onnx文件复制到本项目`models/`目录下。 8. 进入`models/`目录,修改`insert_op.cfg` 文件,将 `src_image_size_w` 和 `src_image_size_h` 分别设置为上述转换 onnx 模型时指定的模型输入宽度和高度。 9. 编辑 `model_conversion.sh` 文件,将 ```bash atc --model=./human-pose-estimation.onnx --framework=5 --output=openpose_pytorch_368 --soc_version=Ascend310 --input_shape="data:1, 3, 368, 368" --input_format=NCHW --insert_op_conf=./insert_op.cfg ``` 行中的`--model`参数改为上述转换得到的onnx文件名,`--output`参数设置为输出 om 模型的名称,`--input_shape`参数设置为指定的模型输入宽、高。 10. 进入`models/`目录,执行转换脚本: ```bash bash model_convertion.sh ``` 等待该脚本执行完毕,可能需要一些时间,该脚本执行完成后会在当前目录下生成项目需要的om模型文件。执行后终端输出为: ```bash ATC start working now, please wait for a moment. ATC run success, welcome to the next use. ``` 表示转换成功。 ## 4 编译与运行 **步骤1** 按照3.4节**模型转换**中的步骤获得om模型文件,放在`models/`目录下,注意检查om模型文件名是否和`pipeline/rtmOpenpose.pipeline`中的mxpi_tensorinfer0 插件 modelPath 属性值相同,若不同需改为一致。若修改了模型的输入尺寸,还需要将 mxpi_imageresize0 插件中的 resizeWidth 和 resizeHeight 属性改成修改后的模型输入尺寸值;将 mxpi_rtmopenposepostprocess0 插件中的 inputWidth 和 inputHeight 属性改成修改后的模型输入尺寸值。 **步骤2** 按照3.2.2节**环境变量设置**中的步骤设置环境变量。 **步骤3** 修改`plugins/CMakeLists.txt`文件,将其中的`$ENV{MX_SDK_HOME}`修改成自己的SDK目录。 **步骤4** 按照3.3节**第三方软件依赖**,使用ffmpeg将视频转换为264格式,将视频上传到`live/mediaServer`目录下,启用live555服务推流。将`pipeline/rtmOpenpose.pipeline`中的`rtspUrl`修改为自己的url和文件名;将 mxpi_videoencoder0 插件中的 imageHeight 和 imageWidth 更改为上传视频的实际高和宽。 **步骤5** 编译。在`plugins/`目录里面执行命令: ```bash bash build.sh sudo cp build/libmxpi_rtmopenposepostprocess.so ${SDK安装路径}/mxVision/lib/plugins/ ``` 注:其中SDK安装路径`${SDK安装路径}`需要替换为用户的SDK安装路径 **步骤6** 运行。回到项目主目录下执行命令: ```bash bash run.sh ``` 命令执行成功后会在当前目录下生成结果视频文件`out.h264`,查看文件验证检测结果。 ## 5 性能测试 **测试帧率:** 使用`/test`目录下的main.cpp替换项目目录下的main.cpp,然后按照第4小结编译与运行中的步骤进行编译运行,服务器会输出运行到该帧的平均帧率。 ![帧率测试](image/帧率测试.jpg) 注:输入视频帧率应高于25,否则无法发挥全部性能。 ## 6 常见问题 ### 6.1 检测输出帧率过低问题 **问题描述:** 控制台输出检测的帧率严重低于25fps(如下10fps)。 ```bash I20220727 09:21:02.990229 32360 MxpiVideoEncoder.cpp:324] Plugin(mxpi_videoencoder0) fps (10). ``` **解决方案:** 确保输入的视频帧率高于25fps。 ### 6.2 视频编码参数配置错误问题 **问题描述:** 运行过程中报错如下: ```bash E20220728 17:05:59.947093 19710 DvppWrapper.cpp:573] input width(888) is not same as venc input format(1280) E20220728 17:05:59.947126 19710 MxpiVideoEncoder.cpp:310] [mxpi_videoencoder0][2010][DVPP: encode H264 or H265 fail] Encode fail. ``` `pipeline/rtmOpenpose.pipeline`中视频编码插件分辨率参数指定错误。手动指定imageHeight 和 imageWidth 属性,需要和视频输入分配率相同。 **解决方案:** 确保`pipeline/rtmOpenpose.pipeline`中 mxpi_videoencoder0 插件中的 imageHeight 和 imageWidth 为输入视频的实际高和宽。