From 90c38234fe6b336e788bb2d41ff460d8eaa72325 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 28 Nov 2024 09:02:41 +0000 Subject: [PATCH 01/28] update contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt. Signed-off-by: hid54630209 --- contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt b/contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt index 5926979a6..d9954411a 100644 --- a/contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt +++ b/contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt @@ -18,7 +18,7 @@ include_directories(${MX_SDK_HOME}/opensource/lib/glib-2.0/include) link_directories(${MX_SDK_HOME}/lib) link_directories(${MX_SDK_HOME}/opensource/lib) -add_compile_options(-std=c++11 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations) +add_compile_options(-std=c++14 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations) add_compile_options("-DPLUGIN_NAME=${PLUGIN_NAME}") add_definitions(-DENABLE_DVPP_INTERFACE) -- Gitee From 0c671bd3b9c1d9463fe0ceb5a4fa5d7ea752ac8e Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 28 Nov 2024 09:03:03 +0000 Subject: [PATCH 02/28] update contrib/Collision/plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt. Signed-off-by: hid54630209 --- .../plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/Collision/plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt b/contrib/Collision/plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt index db5491159..303499e7e 100644 --- a/contrib/Collision/plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt +++ b/contrib/Collision/plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt @@ -19,7 +19,7 @@ include_directories(${MX_SDK_HOME}/opensource/lib/glib-2.0/include) link_directories(${MX_SDK_HOME}/lib) link_directories(${MX_SDK_HOME}/opensource/lib) -add_compile_options(-std=c++11 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations) +add_compile_options(-std=c++14 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations) add_compile_options("-DPLUGIN_NAME=${PLUGIN_NAME}") add_definitions(-DENABLE_DVPP_INTERFACE) -- Gitee From 1a4c07849375cb284b2902b7a2233828cd47cccd Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 28 Nov 2024 09:25:44 +0000 Subject: [PATCH 03/28] update contrib/Collision/collision.py. Signed-off-by: hid54630209 --- contrib/Collision/collision.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/contrib/Collision/collision.py b/contrib/Collision/collision.py index f2389fe78..4d1824f23 100644 --- a/contrib/Collision/collision.py +++ b/contrib/Collision/collision.py @@ -42,17 +42,11 @@ if __name__ == '__main__': fd = os.open('./out_collision.h264', os.O_RDWR | os.O_CREAT, 640) fo = os.fdopen(fd, "wb") - T = 0 while True: # Obtain the inference result by specifying streamName and uniqueId. infer_result = streamManagerApi.GetResult(STREAM_NAME, 0, 300000) fo.write(infer_result.data) - T = T + 1 - print(T) - # the toal frames of video - if T > 100: - print('ending') - break + fo.close() # destroy streams -- Gitee From adfaef3b35ea0e1013d0d88a1b71db87af5a7742 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 28 Nov 2024 09:26:28 +0000 Subject: [PATCH 04/28] update contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt. Signed-off-by: hid54630209 --- contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt b/contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt index d9954411a..349ed8ac4 100644 --- a/contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt +++ b/contrib/Collision/plugins/MxpiCollisionClassName/CMakeLists.txt @@ -28,3 +28,5 @@ add_library(${TARGET_LIBRARY} SHARED MxpiCollisionClassName.cpp) target_link_libraries(${TARGET_LIBRARY} glib-2.0 gstreamer-1.0 gobject-2.0 gstbase-1.0 gmodule-2.0) target_link_libraries(${TARGET_LIBRARY} mxpidatatype plugintoolkit mxbase mindxsdk_protobuf) + +install(TARGETS ${TARGET_LIBRARY} PERMISSIONS OWNER_READ GROUP_READ LIBRARY DESTINATION ${MX_SDK_HOME}/lib/plugins) -- Gitee From fa6ab1555678593812b9553b4832e981cfd73b0a Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 28 Nov 2024 09:26:57 +0000 Subject: [PATCH 05/28] update contrib/Collision/plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt. Signed-off-by: hid54630209 --- .../plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/Collision/plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt b/contrib/Collision/plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt index 303499e7e..8d7e8b216 100644 --- a/contrib/Collision/plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt +++ b/contrib/Collision/plugins/MxpiTrackIdReplaceClassName/CMakeLists.txt @@ -30,3 +30,5 @@ target_link_libraries(${TARGET_LIBRARY} glib-2.0 gstreamer-1.0 gobject-2.0 gstba target_link_libraries(${TARGET_LIBRARY} mxpidatatype plugintoolkit mxbase mindxsdk_protobuf) +install(TARGETS ${TARGET_LIBRARY} PERMISSIONS OWNER_READ GROUP_READ LIBRARY DESTINATION ${MX_SDK_HOME}/lib/plugins) + -- Gitee From a291344b740ec6d009bb5f2ca65f0c566a9ac601 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 28 Nov 2024 09:30:06 +0000 Subject: [PATCH 06/28] update contrib/Collision/collision.py. Signed-off-by: hid54630209 --- contrib/Collision/collision.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/Collision/collision.py b/contrib/Collision/collision.py index 4d1824f23..1d664ea52 100644 --- a/contrib/Collision/collision.py +++ b/contrib/Collision/collision.py @@ -42,10 +42,13 @@ if __name__ == '__main__': fd = os.open('./out_collision.h264', os.O_RDWR | os.O_CREAT, 640) fo = os.fdopen(fd, "wb") + T = 0 while True: # Obtain the inference result by specifying streamName and uniqueId. infer_result = streamManagerApi.GetResult(STREAM_NAME, 0, 300000) fo.write(infer_result.data) + T = T + 1 + print(T) fo.close() -- Gitee From be1dfd09e54b0af19dc25a3e3a35d7ef134d8669 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 28 Nov 2024 11:34:43 +0000 Subject: [PATCH 07/28] update contrib/Collision/README.md. Signed-off-by: hid54630209 --- contrib/Collision/README.md | 215 +++++++++--------------------------- 1 file changed, 55 insertions(+), 160 deletions(-) diff --git a/contrib/Collision/README.md b/contrib/Collision/README.md index dfc22daf9..dbc444a3e 100644 --- a/contrib/Collision/README.md +++ b/contrib/Collision/README.md @@ -1,22 +1,11 @@ # 车辆碰撞识别 ## 1 介绍 -此项目的碰撞插件基于MindXSDK开发,在昇腾芯片上进行目标检测和跟踪,可以对车辆进行画框和编号,检测到车辆碰撞后,可将动向编号提示为“Collision”并将检测结果可视化并保存。 +### 1.1 简介 +此项目的碰撞插件基于mxVision开发,在昇腾芯片上进行目标检测和跟踪,可以对车辆进行画框和编号,检测到车辆碰撞后,可将动向编号提示为“Collision”并将检测结果可视化并保存。 项目主要流程为:通过live555服务器进行拉流输入视频,然后进行视频解码将264格式的视频解码为YUV格式的图片,图片缩放后经过模型推理进行车辆识别,识别结果经过yolov3后处理后得到识别框,对识别框进行跟踪并编号,用编号覆盖原有的类别信息,如检测到车辆发生碰撞,碰撞的车辆的编号将会被“Collision”所替换,再将识别框和类别信息分别转绘到图片上,最后将图片编码成视频进行输出。 -### 1.1 支持的产品 - -昇腾310(推理) - -### 1.2 支持的版本 - -本样例配套的CANN版本为[7.0.RC1](https://gitee.com/link?target=https%3A%2F%2Fwww.hiascend.com%2Fsoftware%2Fcann%2Fcommercial)。支持的SDK版本为[5.0.RC3](https://gitee.com/link?target=https%3A%2F%2Fwww.hiascend.com%2Fsoftware%2FMindx-sdk)。 - -MindX SDK安装前准备可参考《用户指南》,[安装教程](https://gitee.com/ascend/mindxsdk-referenceapps/blob/master/docs/quickStart/1-1安装SDK开发套件.md) - -### 1.3 特性及适用场景 - 本案例可以满足对视频的检测,对检测到的碰撞的车辆在碰撞时刻,输出“Collision”的字样进行提醒。经过测试我们可以知道有以下限制条件: 1.对一个正常清晰的路面,我们可以完成绝大多数正常的一个车辆碰撞检测。 @@ -25,9 +14,7 @@ MindX SDK安装前准备可参考《用户指南》,[安装教程](https://git 3.当车辆很密集时,障碍物很多时,就会导致物体画框增多,画框不同角度的重叠就可能导致碰撞误判。 -### 1.4 软件方案介绍 - -基于MindX SDK的车辆碰撞识别业务流程为:待检测视频存放在live555服务器上经mxpi_rtspsrc拉流插件输入,然后使用视频解码插件mxpi_videodecoder将视频解码成图片,再通过图像缩放插件mxpi_imageresize将图像缩放至满足检测模型要求的输入图像大小要求,缩放后的图像输入模型推理插件mxpi_tensorinfer得到检测结果,再经yolov3后处理插件处理推理结果,得到识别框。再接入跟踪插件中识别框进行目标跟踪,得到目标的跟踪编号,然后在使用mxpi_trackidreplaceclassname插件将跟踪编号覆盖类名信息,再接入本项目开发的碰撞检测插件mxpi_collisionclassname,使用mxpi_object2osdinstances和mxpi_opencvosd分别将识别框和类名(更替写入跟踪编号或者“Collison”碰撞提醒)绘制到原图片,再通过mxpi_videoencoder将图片合成视频 +本案例的车辆碰撞识别业务流程为:待检测视频存放在live555服务器上经mxpi_rtspsrc拉流插件输入,然后使用视频解码插件mxpi_videodecoder将视频解码成图片,再通过图像缩放插件mxpi_imageresize将图像缩放至满足检测模型要求的输入图像大小要求,缩放后的图像输入模型推理插件mxpi_tensorinfer得到检测结果,再经yolov3后处理插件处理推理结果,得到识别框。再接入跟踪插件中识别框进行目标跟踪,得到目标的跟踪编号,然后在使用mxpi_trackidreplaceclassname插件将跟踪编号覆盖类名信息,再接入本项目开发的碰撞检测插件mxpi_collisionclassname,使用mxpi_object2osdinstances和mxpi_opencvosd分别将识别框和类名(更替写入跟踪编号或者“Collison”碰撞提醒)绘制到原图片,再通过mxpi_videoencoder将图片合成视频 表1.1 系统方案各子系统功能描述: @@ -47,7 +34,22 @@ MindX SDK安装前准备可参考《用户指南》,[安装教程](https://git | 12 | OSD可视化插件 | 主要实现对每帧图像标注跟踪结果。 | | 13 | 视频编码插件 | 用于将OSD可视化插件输出的图片进行视频编码,输出视频。 | -### 1.5 代码目录结构与说明 +本案例的技术实现流程图如下所示: + +![SDK流程图](../Collision/image/SDK_process.png) + +注:红色为本项目开发插件 蓝色为沿用其他项目开发插件 其余为SDK内置插件 +### 1.2 支持的产品 + +本项目以昇腾Atlas 300I pro和 Atlas300V pro为主要的硬件平台。 + +### 1.3 支持的版本 + +| MxVision版本 | CANN版本 | Driver/Firmware版本 | + | --------- | ------------------ | -------------- | +| 6.0.RC3 | 8.0.RC3 | 24.1.RC3 | + +### 1.4 代码目录结构与说明 ``` ├── model @@ -73,67 +75,40 @@ MindX SDK安装前准备可参考《用户指南》,[安装教程](https://git └── collision.py ``` -### 1.6 技术实现流程图 - -![SDK流程图](../Collision/image/SDK_process.png) - -注:红色为本项目开发插件 蓝色为沿用其他项目开发插件 其余为SDK内置插件 +### 1.5 三方依赖 -## 2 环境依赖 +本项目除了依赖昇腾Driver、Firmware、CANN和MxVision及其要求的配套软件外,还需额外依赖以下软件: -推荐系统为ubuntu 18.04,环境依赖软件和版本如下表: +| 软件名称 | 版本 | +|--------| ------ | +| ffmpeg | 3.4.11 | -| 软件名称 | 版本 | 说明 | 获取方式 | -| ------------------- | ----------- | ----------------------------- | ------------------------------------------------------------ | -| MindX SDK | 5.0.RC3 | mxVision软件包 | [链接](https://gitee.com/link?target=https%3A%2F%2Fwww.hiascend.com%2Fsoftware%2FMindx-sdk) | -| ubuntu | 18.04.1 LTS | 操作系统 | Ubuntu官网获取 | -| Ascend-CANN-toolkit | 7.0.RC1 | Ascend-cann-toolkit开发套件包 | [链接](https://gitee.com/link?target=https%3A%2F%2Fwww.hiascend.com%2Fsoftware%2Fcann%2Fcommercial) | +*ffmpeg需要源码编译安装,请用户参考链接[]至相关网站下载源码进行编译安装。 -在编译运行项目前,需要设置环境变量: +## 2 设置环境变量 -- 环境变量介绍 +在执行后续步骤前,需要设置环境变量: +```bash +# 执行环境变量脚本使环境变量生效 +. ${ascend-toolkit-path}/set_env.sh +. ${mxVision-path}/set_env.sh +# mxVision-path: mxVision安装路径 +# ascend-toolkit-path: CANN安装路径 ``` -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 ASCEND_OPP_PATH=${install_path}/opp -export ASCEND_AICPU_PATH=${install_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 -#用于设置python3.9.2库文件路径 -export LD_LIBRARY_PATH=/usr/local/python3.9.2/lib:$LD_LIBRARY_PATH -#如果用户环境存在多个python3版本,则指定使用python3.9.2版本 -export PATH=/usr/local/python3.9.2/bin:$PATH -``` - -注:其中SDK安装路径${MX_SDK_HOME}替换为用户的SDK安装路径;install_path替换为开发套件包所在路径。LD_LIBRARY_PATH用以加载开发套件包中lib库。 - - - -## 3 依赖安装 - -推理中涉及到第三方软件依赖如下表所示。 - -| 依赖软件 | 版本 | 说明 | 使用教程 | -| -------- | ---------- | ------------------------------ | -----------------------------------------------------------: | -| live555 | 1.09 | 实现视频转rstp进行推流 | [链接]([guide/mindx/sdk/tutorials/reference_material/Live555离线视频转RTSP说明文档.md · Ascend/docs-openmind - Gitee.com](https://gitee.com/ascend/docs-openmind/blob/master/guide/mindx/sdk/tutorials/reference_material/Live555离线视频转RTSP说明文档.md)) | -| ffmpeg | 2021-07-21 | 实现mp4格式视频转为264格式视频 | [链接]([guide/mindx/sdk/tutorials/reference_material/pc端ffmpeg安装教程.md · Ascend/docs-openmind - Gitee.com](https://gitee.com/ascend/docs-openmind/blob/master/guide/mindx/sdk/tutorials/reference_material/pc端ffmpeg安装教程.md)) | -| python | 3.9.2 | 与SDK配套 | [链接]([Linux(Ubuntu)系统安装Python (biancheng.net)](http://c.biancheng.net/view/4162.html)) | +## 3 准备模型 +**步骤1** 下载模型相关文件 -## 4 模型转换 +根据[链接](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/ActionRecognition/ATC%20YOLOv3%28FP16%29%20from%20TensorFlow%20-%20Ascend310.zip)下载得到yolov3_tf.pb文件,并放到项目根目录的`./models`文件夹。 -本项目中适用的模型是yolov3模型,yolov3模型可以在昇腾官网ModelZoo直接下载:[YOLOv3-昇腾社区 (hiascend.com)]([ATC YOLOv3(FP16)-昇腾社区 (hiascend.com)](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/ActionRecognition/ATC%20YOLOv3%28FP16%29%20from%20TensorFlow%20-%20Ascend310.zip))。下载后使用模型转换工具 ATC 将 pb 模型转换为 om 模型,模型转换工具相关介绍参考链接:[https://gitee.com/ascend/docs-openmind/blob/master/guide/mindx/sdk/tutorials/%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99.md](https://gitee.com/ascend/docs-openmind/blob/master/guide/mindx/sdk/tutorials/%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99.md) 。 +**步骤2** 转换模型格式 -模型转换,步骤如下: - -从上述下载链接中下载yolov3模型解压缩文件yolov3_tf.pb至 ./model 文件夹下,进入 `./models` 文件夹下执行命令: +进入 `./models` 文件夹下执行命令: ``` -atc --model=./yolov3_tf.pb --framework=3 --output=./yolov3 --soc_version=Ascend310 --insert_op_conf=./aipp_yolov3_416_416.aippconfig --input_shape="input:1,416,416,3" --out_nodes="yolov3/yolov3_head/Conv_6/BiasAdd:0;yolov3/yolov3_head/Conv_14/BiasAdd:0;yolov3/yolov3_head/Conv_22/BiasAdd:0" +atc --model=./yolov3_tf.pb --framework=3 --output=./yolov3 --soc_version=Ascend310P3 --insert_op_conf=./aipp_yolov3_416_416.aippconfig --input_shape="input:1,416,416,3" --out_nodes="yolov3/yolov3_head/Conv_6/BiasAdd:0;yolov3/yolov3_head/Conv_14/BiasAdd:0;yolov3/yolov3_head/Conv_22/BiasAdd:0" ``` 执行该命令后会在当前文件夹下生成项目需要的模型文件 yolov3.om。执行后终端输出为: @@ -146,123 +121,43 @@ ATC run success, welcome to the next use. 表示命令执行成功。 +## 4 编译与运行 -## 5 准备 - -按照第3小结**软件依赖**安装live555和ffmpeg,按照 [Live555离线视频转RTSP说明文档]([guide/mindx/sdk/tutorials/reference_material/Live555离线视频转RTSP说明文档.md · Ascend/docs-openmind - Gitee.com](https://gitee.com/ascend/docs-openmind/blob/master/guide/mindx/sdk/tutorials/reference_material/Live555离线视频转RTSP说明文档.md))将mp4视频转换为h264格式。并将生成的264格式的视频上传到`live/mediaServer`目录下,然后修改collision.pipeline文件中mxpi_rtspsrc0的内容。 +**步骤1** 启动rtsp服务 -``` - "mxpi_rtspsrc0": { - "factory": "mxpi_rtspsrc", - "props": { - "rtspUrl":"rtsp://xxx.xxx.xxx.xxx:xxxx/xxx.264", // 修改为自己所使用的的服务器和文件名 - "channelId": "0" - }, - "next": "mxpi_videodecoder0" - }, -``` +按照 [教程](https://gitee.com/ascend/mindxsdk-referenceapps/blob/master/docs/%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99/Live555%E7%A6%BB%E7%BA%BF%E8%A7%86%E9%A2%91%E8%BD%ACRTSP%E8%AF%B4%E6%98%8E%E6%96%87%E6%A1%A3.md) 自行准备数据,并启动rtsp服务。 -我们默认ffmpeg转换视频为264格式时,分辨率统一为1280*720,如果自己需要更改分辨率,请同时修改collision.pipeline文件中mxpi_videoencoder0的"imageHeight"和"imageWidth"内容。 +**步骤2** 修改collision.pipeline配置文件 - "mxpi_videoencoder0": { - "props": { - "inputFormat": "YUV420SP_NV12", - "outputFormat": "H264", - "fps": "1", - "iFrameInterval": "50", - "imageHeight":"720", - "imageWidth":"1280" - }, - "factory": "mxpi_videoencoder", - "next": "queue7" - }, -## 6 编译与运行 +第**9**行 `"rtspUrl":"rtsp://xxx.xxx.xxx.xxx:xxxx/xxx.264"`中的rtsp://xxx.xxx.xxx.xxx:xxxx/xxx.264替换为可用的 rtsp 流地址。 -**步骤1** 按照第2小结**环境依赖**中的步骤设置环境变量。 +第**152**行 `"imageHeight":"720"`中的720替换为视频帧实际的高。 -**步骤2** 按照第 4 小节 **模型转换** 中的步骤获得 om 模型文件,放置在 `./model` 目录下。 +第**153**行 `"imageWidth":"1280"`中的1280替换为视频帧实际的宽。 -**步骤3** 修改`Collision/plugins/MxpiCollisionClassName`和`Collision/plugins/MxpiTrackIdReplaceClassName`文件夹下的CMakeLists.txt文件。将其中的"$ENV{MX_SDK_HOME}"修改成自己的SDK目录。 +**步骤3** 编译 -**步骤4** 编译。进入 `Collision` 目录,在 `Collision` 目录下执行命令: +进入mxVision安装目录的`operators/opencvosd`目录下执行命令: ``` -bash build.sh +bash generate_osd_om.sh ``` -命令执行成功后会在`Collision/plugins/MxpiCollisionClassName`和`Collision/plugins/MxpiTrackIdReplaceClassName`目录下分别生成build文件夹。将`Collision/plugins/MxpiTrackIdReplaceClassName/build`目录下生成的的libmxpi_trackidreplaceclassname.so下载后上传到`${SDK安装路径}/mxVision/lib/plugins`目录下,同时将`Collision/plugins/MxpiCollisionClassName/build`目录下生成的libmxpi_collisionclassname.so下载后上传到`${SDK安装路径}/mxVision/lib/plugins`目录下。 - -**步骤5** 运行。回到主目录下,在主目录下执行命令: +进入 `Collision` 目录,在 `Collision` 目录下执行命令: ``` -python3.9.2 collision.py -``` - -命令执行成功后会在当前目录下生成检测结果视频文件out_collision.h264,查看文件验证目标跟踪结果。 - - - -## 7 结果展示(部分截图) - -生成的out_collision.h264文件在本地我们可以用适配.h264文件格式的视频播放软件进行播放。也可以使用ffmpeg转换成.mp4格式进行本地播放。 - -``` -ffmpeg -i out_collision.h264 -vcodec h264 out_collision.mp4 +bash build.sh ``` -![碰撞前](../Collision/image/before_collision.png)![碰撞时](../Collision/image/collision.png)![碰撞后](../Collision/image/after_collision.png) - - -## 8 性能测试 - -使用sdk自带的性能统计工具测试项目性能 - -**步骤1:**修改sdk插件性能统计工具的配置文件,文件位于 *${MX_SDK_HOME}/config/sdk.conf* - -``` -enable_ps=true #打开性能统计开关 - -ps_log_dir=logs #生成日志地址路径 - -ps_interval_time=1 #性能统计时间间隔,单位s -``` - -**步骤2:**执行运行命令 +**步骤4** 运行。回到主目录下,在主目录下执行命令: ``` python3.9.2 collision.py ``` -**步骤3:**在${ps_log_dir}下查看生成的性能日志,打开performance-statistics.log.tpr日式文件查看吞吐率,与推理视频帧率保持一致,满足实时性要求 - -``` -{"streamName":"collision","throughput":33,"throughputRate":33,"type":"throughputRate"} -{"streamName":"collision","throughput":31,"throughputRate":31,"type":"throughputRate"} -``` - - - -## 9 常见问题 - -视频编码参数配置错误 - -1.**问题描述:** - -`Collision/collision.pipeline`中视频编码分辨率参数已经手动指定imageHeight 和 imageWidth 属性,需要和视频输入分配率相同,否则会包如下类型的错: - -![error](../Collision/image/error.png) - -**解决方案:** - -确保`Collision/collision.pipeline`中 mxpi_videoencoder0 插件的 imageHeight 和 imageWidth 属性值是输入.h264视频的高和宽。此时我们可以在用ffmpeg进行视频拉流时找到设置.h264视频的高和宽。 - -2.**问题描述:** - -`Collision/collision.py`中视频帧数参数目前未确定,系统则会对缺省的视频拉流帧数进行识别并输出,所以会造成输出长视频不完整和短视频重复的结果。 - -**解决方案:** +命令执行成功后会在当前目录下生成检测结果视频文件out_collision.h264, 会在标准输出打印保存视频文件的帧数。 -确保`Collision/collision.py`中第52行`if t > 'xxx'`的属性值是输入.h264视频帧数。此时我们可以在用ffmpeg进行视频拉流时找到设置.h264视频的帧数。 +**步骤5** 停止服务、查看结果 -![视频格式转换](../Collision/image/video_conversion.png) \ No newline at end of file +命令行输入Ctrl+C组合键可手动停止服务,打开out_collision.h264查看文件、观测目标跟踪结果。 \ No newline at end of file -- Gitee From 5c43d24d61a9add651f917a4ae93bec9dfe04526 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 28 Nov 2024 11:57:45 +0000 Subject: [PATCH 08/28] update contrib/Collision/README.md. Signed-off-by: hid54630209 --- contrib/Collision/README.md | 55 +++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/contrib/Collision/README.md b/contrib/Collision/README.md index dbc444a3e..f9f7d29c8 100644 --- a/contrib/Collision/README.md +++ b/contrib/Collision/README.md @@ -52,27 +52,34 @@ ### 1.4 代码目录结构与说明 ``` +├── build.sh +├── collision.pipeline # pipeline文件 +├── collision.py +├── image +│ ├── after_collision.png +│ ├── before_collision.png +│ ├── collision.png +│ ├── error.png +│ ├── SDK_process.png +│ └── video_conversion.png ├── model -│ ├── aipp_yolov3_416_416.aippconfig # 模型转换aipp配置文件 -│ ├── coco.names # 类名 -│ ├── yolov3.cfg # yolov3配置文件 -│ └── yolov3.om # om模型 -│ +│ ├── aipp_yolov3_416_416.aippconfig # 模型转换aipp配置文件 +│ ├── coco.names # 类名 +│ └── yolov3.cfg # yolov3配置文件 ├── plugins -│ ├── MxpiCollisionClassName # 碰撞检测插件 -│ │ ├── CMakeLists.txt -│ │ ├── MxpiCollisionClassName.cpp -│ │ ├── MxpiCollisionClassName.h -│ │ └── build.sh -│ └── MxpiTrackIdReplaceClassName # 跟踪编号取代类名插件 +│ ├── MxpiCollisionClassName # 碰撞检测插件 +│ │ ├── build.sh +│ │ ├── CMakeLists.txt +│ │ ├── MxpiCollisionClassName.cpp +│ │ └── MxpiCollisionClassName.h +│ └── MxpiTrackIdReplaceClassName # 跟踪编号取代类名插件 +│ ├── build.sh │ ├── CMakeLists.txt │ ├── MxpiTrackIdReplaceClassName.cpp -│ ├── MxpiTrackIdReplaceClassName.h -│ └── build.sh -│ -├── build.sh -├── collision.pipeline # pipeline文件 -└── collision.py +│ └── MxpiTrackIdReplaceClassName.h +└── README.md + + ``` ### 1.5 三方依赖 @@ -83,7 +90,7 @@ |--------| ------ | | ffmpeg | 3.4.11 | -*ffmpeg需要源码编译安装,请用户参考链接[]至相关网站下载源码进行编译安装。 +*ffmpeg需要下载源码编译安装,请用户至相关网站下载源码进行编译安装。 ## 2 设置环境变量 @@ -101,11 +108,11 @@ ## 3 准备模型 **步骤1** 下载模型相关文件 -根据[链接](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/ActionRecognition/ATC%20YOLOv3%28FP16%29%20from%20TensorFlow%20-%20Ascend310.zip)下载得到yolov3_tf.pb文件,并放到项目根目录的`./models`文件夹。 +根据[链接](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/ActionRecognition/ATC%20YOLOv3%28FP16%29%20from%20TensorFlow%20-%20Ascend310.zip)下载得到yolov3_tf.pb文件,并放到项目根目录的`model`文件夹。 **步骤2** 转换模型格式 -进入 `./models` 文件夹下执行命令: +进入项目根目录的`model`文件夹下执行命令: ``` atc --model=./yolov3_tf.pb --framework=3 --output=./yolov3 --soc_version=Ascend310P3 --insert_op_conf=./aipp_yolov3_416_416.aippconfig --input_shape="input:1,416,416,3" --out_nodes="yolov3/yolov3_head/Conv_6/BiasAdd:0;yolov3/yolov3_head/Conv_14/BiasAdd:0;yolov3/yolov3_head/Conv_22/BiasAdd:0" @@ -125,7 +132,7 @@ ATC run success, welcome to the next use. **步骤1** 启动rtsp服务 -按照 [教程](https://gitee.com/ascend/mindxsdk-referenceapps/blob/master/docs/%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99/Live555%E7%A6%BB%E7%BA%BF%E8%A7%86%E9%A2%91%E8%BD%ACRTSP%E8%AF%B4%E6%98%8E%E6%96%87%E6%A1%A3.md) 自行准备数据,并启动rtsp服务。 +按照 [教程](https://gitee.com/ascend/mindxsdk-referenceapps/blob/master/docs/%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99/Live555%E7%A6%BB%E7%BA%BF%E8%A7%86%E9%A2%91%E8%BD%ACRTSP%E8%AF%B4%E6%98%8E%E6%96%87%E6%A1%A3.md) 自行准备视频数据,并启动rtsp服务。 **步骤2** 修改collision.pipeline配置文件 @@ -153,11 +160,13 @@ bash build.sh **步骤4** 运行。回到主目录下,在主目录下执行命令: ``` -python3.9.2 collision.py +python3 collision.py ``` 命令执行成功后会在当前目录下生成检测结果视频文件out_collision.h264, 会在标准输出打印保存视频文件的帧数。 **步骤5** 停止服务、查看结果 -命令行输入Ctrl+C组合键可手动停止服务,打开out_collision.h264查看文件、观测目标跟踪结果。 \ No newline at end of file +命令行输入Ctrl+C组合键可手动停止服务,打开out_collision.h264查看文件、观测目标跟踪结果。 + +*考虑到保存检测结果的视频会占用较大存储空间,请用户合理控制服务运行时间,避免保存检测结果的视频文件过大、影响服务器正常工作。 \ No newline at end of file -- Gitee From b0b6e7f0f354016d95ab29959153658bd429a019 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Mon, 2 Dec 2024 12:02:30 +0000 Subject: [PATCH 09/28] update contrib/Collision/README.md. Signed-off-by: hid54630209 --- contrib/Collision/README.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/contrib/Collision/README.md b/contrib/Collision/README.md index f9f7d29c8..75f8859ef 100644 --- a/contrib/Collision/README.md +++ b/contrib/Collision/README.md @@ -128,7 +128,7 @@ ATC run success, welcome to the next use. 表示命令执行成功。 -## 4 编译与运行 +## 4 运行 **步骤1** 启动rtsp服务 @@ -142,7 +142,7 @@ ATC run success, welcome to the next use. 第**153**行 `"imageWidth":"1280"`中的1280替换为视频帧实际的宽。 -**步骤3** 编译 +**步骤3** 生成osd相关文件 进入mxVision安装目录的`operators/opencvosd`目录下执行命令: @@ -157,16 +157,24 @@ bash build.sh ``` -**步骤4** 运行。回到主目录下,在主目录下执行命令: +**步骤4** 启动服务 + +回到主目录下,在主目录下执行命令: ``` python3 collision.py ``` -命令执行成功后会在当前目录下生成检测结果视频文件out_collision.h264, 会在标准输出打印保存视频文件的帧数。 +命令执行成功后会在标准输出实时打印已保存的视频帧数量。 + + +**步骤5** 停止服务 + +命令行输入Ctrl+C组合键可手动停止服务。 + +*考虑到保存检测结果的视频会占用较大存储空间,请用户合理控制服务运行时间、及时停止服务,避免视频文件过大、影响服务器正常工作。 -**步骤5** 停止服务、查看结果 -命令行输入Ctrl+C组合键可手动停止服务,打开out_collision.h264查看文件、观测目标跟踪结果。 +**步骤6** 查看结果 -*考虑到保存检测结果的视频会占用较大存储空间,请用户合理控制服务运行时间,避免保存检测结果的视频文件过大、影响服务器正常工作。 \ No newline at end of file +命令执行成功后会在当前目录下生成检测结果视频文件out_collision.h264,打开out_collision.h264查看文件、观测目标跟踪结果。 -- Gitee From 332a770c03aa8655626e383dd05ccf9a824c84a2 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Mon, 2 Dec 2024 12:16:05 +0000 Subject: [PATCH 10/28] update contrib/Collision/README.md. Signed-off-by: hid54630209 --- contrib/Collision/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/Collision/README.md b/contrib/Collision/README.md index 75f8859ef..55e0a6dc2 100644 --- a/contrib/Collision/README.md +++ b/contrib/Collision/README.md @@ -128,7 +128,7 @@ ATC run success, welcome to the next use. 表示命令执行成功。 -## 4 运行 +## 4 编译与运行 **步骤1** 启动rtsp服务 @@ -142,7 +142,7 @@ ATC run success, welcome to the next use. 第**153**行 `"imageWidth":"1280"`中的1280替换为视频帧实际的宽。 -**步骤3** 生成osd相关文件 +**步骤3** 编译 进入mxVision安装目录的`operators/opencvosd`目录下执行命令: -- Gitee From 361c64cc61660b316dbe0fc92c972f97a2484cec Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Mon, 2 Dec 2024 12:18:21 +0000 Subject: [PATCH 11/28] update contrib/Collision/README.md. Signed-off-by: hid54630209 --- contrib/Collision/README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/contrib/Collision/README.md b/contrib/Collision/README.md index 55e0a6dc2..050284502 100644 --- a/contrib/Collision/README.md +++ b/contrib/Collision/README.md @@ -82,15 +82,6 @@ ``` -### 1.5 三方依赖 - -本项目除了依赖昇腾Driver、Firmware、CANN和MxVision及其要求的配套软件外,还需额外依赖以下软件: - -| 软件名称 | 版本 | -|--------| ------ | -| ffmpeg | 3.4.11 | - -*ffmpeg需要下载源码编译安装,请用户至相关网站下载源码进行编译安装。 ## 2 设置环境变量 -- Gitee From c5c40fcbc5b19822060b25162b544bfcb227e2a3 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Tue, 3 Dec 2024 12:06:16 +0000 Subject: [PATCH 12/28] update contrib/Collision/README.md. Signed-off-by: hid54630209 --- contrib/Collision/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/Collision/README.md b/contrib/Collision/README.md index 050284502..0f694c0ec 100644 --- a/contrib/Collision/README.md +++ b/contrib/Collision/README.md @@ -2,7 +2,7 @@ ## 1 介绍 ### 1.1 简介 -此项目的碰撞插件基于mxVision开发,在昇腾芯片上进行目标检测和跟踪,可以对车辆进行画框和编号,检测到车辆碰撞后,可将动向编号提示为“Collision”并将检测结果可视化并保存。 +I 1此项目的碰撞插件基于mxVision开发,在昇腾芯片上进行目标检测和跟踪,可以对车辆进行画框和编号,检测到车辆碰撞后,可将动向编号提示为“Collision”并将检测结果可视化并保存。 项目主要流程为:通过live555服务器进行拉流输入视频,然后进行视频解码将264格式的视频解码为YUV格式的图片,图片缩放后经过模型推理进行车辆识别,识别结果经过yolov3后处理后得到识别框,对识别框进行跟踪并编号,用编号覆盖原有的类别信息,如检测到车辆发生碰撞,碰撞的车辆的编号将会被“Collision”所替换,再将识别框和类别信息分别转绘到图片上,最后将图片编码成视频进行输出。 -- Gitee From 5ced2f010b5494445dda57dae524a861562d130e Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Tue, 3 Dec 2024 12:09:03 +0000 Subject: [PATCH 13/28] update contrib/Collision/README.md. Signed-off-by: hid54630209 --- contrib/Collision/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/Collision/README.md b/contrib/Collision/README.md index 0f694c0ec..050284502 100644 --- a/contrib/Collision/README.md +++ b/contrib/Collision/README.md @@ -2,7 +2,7 @@ ## 1 介绍 ### 1.1 简介 -I 1此项目的碰撞插件基于mxVision开发,在昇腾芯片上进行目标检测和跟踪,可以对车辆进行画框和编号,检测到车辆碰撞后,可将动向编号提示为“Collision”并将检测结果可视化并保存。 +此项目的碰撞插件基于mxVision开发,在昇腾芯片上进行目标检测和跟踪,可以对车辆进行画框和编号,检测到车辆碰撞后,可将动向编号提示为“Collision”并将检测结果可视化并保存。 项目主要流程为:通过live555服务器进行拉流输入视频,然后进行视频解码将264格式的视频解码为YUV格式的图片,图片缩放后经过模型推理进行车辆识别,识别结果经过yolov3后处理后得到识别框,对识别框进行跟踪并编号,用编号覆盖原有的类别信息,如检测到车辆发生碰撞,碰撞的车辆的编号将会被“Collision”所替换,再将识别框和类别信息分别转绘到图片上,最后将图片编码成视频进行输出。 -- Gitee From 47c6516b261bf4e6e4bfee7fcb26a8b839422210 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Tue, 3 Dec 2024 12:57:47 +0000 Subject: [PATCH 14/28] update contrib/FCOS/README.md. Signed-off-by: hid54630209 --- contrib/FCOS/README.md | 203 ++++++++--------------------------------- 1 file changed, 36 insertions(+), 167 deletions(-) diff --git a/contrib/FCOS/README.md b/contrib/FCOS/README.md index c88789d5d..25846bb18 100644 --- a/contrib/FCOS/README.md +++ b/contrib/FCOS/README.md @@ -2,6 +2,8 @@ ## 1 介绍 +### 1.1 简介 + 本开发项目演示FCOS模型实现目标检测。本系统基于mxVision SDK进行开发,以昇腾Atlas310卡为主要的硬件平台,主要实现目标检测。待检测的图片中物体不能被遮挡太严重,并且物体要完全出现在图片中。图片亮度不能过低。输入一张图片,最后会输出图片中能检测到的物体。项目主要流程: 1.环境搭建; @@ -9,36 +11,35 @@ 3.生成后处理插件; 4.进行精度、性能对比。 -### 1.1支持的产品 +### 1.2 支持的产品 -本产品以昇腾310(推理)卡为硬件平台。 +本项目以昇腾x86_64 Atlas 300l (型号3010)和arm Atlas 300l (型号3000)为主要的硬件平台。 -### 1.2支持的版本 +### 1.3 支持的版本 -该项目支持的SDK版本为5.0.0,CANN版本为7.0.0。 +| MxVision版本 | CANN版本 | Driver/Firmware版本 | +| --------- | ------------------ | -------------- | +| 5.0.0 | 7.0.0 | 23.0.0 | -### 1.3软件方案介绍 +### 1.4 三方依赖 -基于MindXSDK的FCOS目标检测的业务流程为: +项目运行过程中涉及到的第三方软件依赖如下表所示: -1. 将待检测的图片放到相应的文件夹下。 -2. 首先使用mmcv库对图片进行前处理(改变图片大小、归一化、补边操作)。‘ -3. 将图片转换成为二进制的numpy数组,传入pipeline中。 -4. 放缩后的图片输入模型推理插件mxpi_tensorinfer进行处理; -5. 将经过模型推理输出时候的张量数据流输入到mxpi_objectpostprocessor中,对FCOS目标检测模型推理输出的张量进行后处理; -6. 处理完毕之后将数据传入mxpi_dataserialize0插件中,将stream结果组装成json字符串输出。 +| 软件名称 | 说明 | 使用教程 | +| ----------- | -------------------- | --------------------------------------------------------- | +| pycocotools | 用于实现代码测评 | [点击打开链接](https://cocodataset.org/) | +| mmdetection | 用于实现模型精度评估 | [点击打开链接](https://github.com/open-mmlab/mmdetection) | +| mmcv | 用于实现图片前处理 | [点击打开链接](https://github.com/open-mmlab/mmcv) | -下表为系统方案各个子系统功能的描述: +安装python COCO测评工具,mmcv和mmdetection。执行命令: -| 序号 | 子系统 | 功能描述 | -| ---- | ---------- | ---------------------------------------------------------------------------------------------------------------------- | -| 1 | 图片输入 | 传入图片,修改图片的大小和格式为符合模型要求的格式 | -| 2 | 图像前处理 | 对图片进行改变大小、补边、归一化等操作。 | -| 3 | 模型推理 | 将已经处理好的图片传入到mxpi_tensorinfer中,使用目标检测模型FCOS进行推理,得到推理的张量数据流 | -| 4 | 模型后处理 | 将模型推理得到的张量数据流传入mxpi_objectpostprocessor中进行张量后处理。对模型输出的目标框进行去重,排序和筛选等工作。 | -| 5 | 组装字符串 | stream结果组装成json字符串输出。 | +``` +pip3 install pycocotools +pip3 install mmcv-full +pip3 install mmdet +``` -### 1.4代码目录结构与说明 +### 1.5 代码目录结构说明 本项目名为FCOS目标检测,项目的目录如下所示: @@ -63,25 +64,7 @@ |_ main.py ``` -### 1.5技术实现流程图 - -本项目实现对输入的图片进行目标检测,整体流程如下: - -![avatar](./image/image1.png) - -### 1.6特性以及适用场景 -本项目是根据COCO数据集进行训练,仅仅适合COCO官方数据集中的80类物体进行识别。在此这八十类物体不一一列出。 -## 2环境依赖 - -推荐系统为ubuntu 18.04,环境软件和版本如下: - -| 软件名称 | 版本 | 说明 | 获取方式 | -| ------------------- | ------ | ----------------------------- | ----------------------------------------------------------------- | -| MindX SDK | 5.0.0 | mxVision软件包 | [点击打开链接](https://www.hiascend.com/software/Mindx-sdk) | -| ubuntu | 18.04 | 操作系统 | 请上ubuntu官网获取 | -| Ascend-CANN-toolkit | 7.0.0 | Ascend-cann-toolkit开发套件包 | [点击打开链接](https://www.hiascend.com/software/cann/commercial) | -| mmdetection | 2.25.0 | 用于评估准确度 | 请上mmdetection官网 | - +## 2 设置环境变量 在项目开始运行前需要设置环境变量: ``` @@ -89,38 +72,23 @@ . ${SDK安装路径}/mxVision/set_env.sh ``` -## 3 软件依赖 - -项目运行过程中涉及到的第三方软件依赖如下表所示: - -| 软件名称 | 说明 | 使用教程 | -| ----------- | -------------------- | --------------------------------------------------------- | -| pycocotools | 用于实现代码测评 | [点击打开链接](https://cocodataset.org/) | -| mmdetection | 用于实现模型精度评估 | [点击打开链接](https://github.com/open-mmlab/mmdetection) | -| mmcv | 用于实现图片前处理 | [点击打开链接](https://github.com/open-mmlab/mmcv) | - -.安装python COCO测评工具,mmcv和mmdetection。执行命令: - -``` -pip3 install pycocotools -pip3 install mmcv-full -pip3 install mmdet -``` - -## 4 模型转换 +## 3 准备模型 本项目使用的模型是FCOS目标检测模型这个模型是一个无anchor检测器。FCOS直接把预测特征图上的每个位置$(x,y)$当作训练样本,若这个位置在某个ground truth box的内部,则视为正样本,该位置的类别标签$c$对应这个box的类别,反之则视为负样本。这个网络的输出为目标框的左上角坐标、右下角坐标、类别和置信度。本项目的onnx模型可以直接[下载](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/Fcos/ATC%20Fcos.zip)。下载后,里面自带的om模型是可以直接使用的,或者自行使用ATC工具将onnx模型转换成为om模型,模型转换工具的使用说明参考[链接](https://gitee.com/ascend/docs-openmind/blob/master/guide/mindx/sdk/tutorials/%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99.md)。 模型转换步骤如下: -1.从下载链接处下载onnx模型至FCOS/models文件夹下。 +**步骤1:** +从下载链接处下载onnx模型至FCOS/models文件夹下。 +**步骤2:** 模型转换语句如下: ``` atc --model=fcos.onnx --framework=5 --soc_version=Ascend310 --input_format=NCHW --input_shape="input:1,3,800,1333" --output=fcos_bs1 --precision_mode=allow_fp32_to_fp16 ``` +**步骤3:** 执行完该命令之后,会在models文件夹下生成.om模型,并且转换成功之后会在终端输出: ``` @@ -130,15 +98,15 @@ ATC run success, welcome to the next use. -## 5准备 +## 4 编译与运行 -### 步骤1 +**步骤1:** 准备一张待检测图片,并上传到FCOS文件夹下。然后修改main.py文件里面的图片路径为待检测的图片路径。并且从https://github.com/pjreddie/darknet/blob/master/data/coco.names 里面下载coco.names文件,并且将这个文件存放到models文件夹下。并且修改main.py里IMAGENAME为图片的路径: ```python IMAGENAME = '{image path}' // 120行 ``` -### 步骤2 +**步骤2:** 进入FCOS/plugin/FCOSPostprocess目录,在该目录下运行下列命令: @@ -147,7 +115,7 @@ bash build.sh ``` 这个后处理插件即可以使用。 -## 6编译与运行 +**步骤3:** 在FCOS目录下执行命令: @@ -155,70 +123,13 @@ bash build.sh python3 main.py ``` -最后生成的结果会在FCOS文件夹目录下result.jpg图片中。 - -## 7精度测试 - -1.下载COCO VAL 2017[数据集](http://images.cocodataset.org/zips/val2017.zip -)和[标注文件](http://images.cocodataset.org/annotations/annotations_trainval2017.zip -)。在FCOS目录下创建dataset目录,将数据集压缩文件和标注数据压缩文件都解压至 `FCOS/dataset` 目录下。再次创建一个文件夹名为binresult,在FCOS目录下。确保解压后的FCOS目录结构为: - -``` -|- models -| |- fcos.onnx //onnx模型 -| |_ Fcos_tf_bs.cfg -|- pipeline -| |_ FCOSdetection.pipeline -|- plugin -| |_FCOSPostprocess -| |- CMakeLists.txt -| |- FCOSDetectionPostProcess.cpp -| |- FCOSDetectionPostProcess.h -| |_ build.sh -|- binresult -|- dataset -| |- annotations -| | |_ instances_val2017.json -| |_ val2017 -| |-000000581615.jpg -| |-000000581781.jpg -| |_other-images -|- image -| |- image1.png -| |_ image2.png -|- build.sh -|- colorlist.txt -|- evaluate.py -|_ main.py -``` - -2.再修改后处理插件cpp文件中的: -```cpp - //107行 - if (*(beginRes + CENTERPOINT) < THRESHOLD_) { - continue; - } - //123行 - MxBase::NmsSort(objectInfo, RATE); -``` -将上面的代码全部注释掉,再重新生成一次插件。 +**步骤4:查看结果** -3.执行命令: - -``` -python3 evaluate.py -``` - -命令执行完毕之后,会在binresult文件夹,生成模型输出的目标框、置信度等信息。 - -4.最后在终端输出COCO格式的测评结果,输出结果如下: - -![avatar](./image/image2.png) +最后生成的结果会在FCOS文件夹目录下result.jpg图片中。 -上图中第一行可以看到,这个模型在COCO VAL 2017数据集上,IOU阈值为0.50:0.05:0.95时的精确度为0.347。原模型的推理精度也为0.347这个数据与原模型的推理精度误差范围在0.01内。 -## 8常见问题 -### 8.1 模型路径配置问题: +## 5 常见问题 +### 5.1 模型路径配置问题: 问题描述: 检测过程中用到的模型以及模型后处理插件需配置路径属性。 @@ -244,46 +155,4 @@ python3 evaluate.py "factory": "mxpi_objectpostprocessor", "next": "mxpi_dataserialize0" }, -``` -### 8.2 精度测试脚本运行时, TypeError报错问题: -问题描述: -运行精度测试脚本过程中, 出现如下类似报错: -``` -********* -File "***/pycocotools/cocoeval.py", line 507 in setDetParams - self.iouThrs = np.linspace(.5, 0.95, np.round((0.95 - .5) / .05) + 1, endpoint=True) -******** -TypeError: 'numpy.float64' object cannot be interpreted as an integer -``` - -解决措施: -打开pycocotools库下的cocoeval.py文件, 将文件中的代码: -``` -self.iouThrs = np.linspace(.5, 0.95, np.round((0.95 - .5) / .05) + 1, endpoint=True) -self.recThrs = np.linspace(.0, 1.00, np.round((1.00 - .0) / .01) + 1, endpoint=True) -``` -修改为: -``` -self.iouThrs = np.linspace(.5, 0.95, 10, endpoint=True) -self.recThrs = np.linspace(.0, 1.00, 101, endpoint=True) -``` - -### 8.3 精度测试脚本运行时, NameError报错问题: -问题描述: -运行精度测试脚本过程中, 出现如下类似报错: -``` -********* -File "***/pycocotools/coco.py", line 308 in loadRes - if type(resFile) == str or type(resFile) == unicode: -NameError: name 'unicode' is not defined -``` - -解决措施: -打开pycocotools库下的coco.py文件, 将文件中的代码: -``` -if type(resFile) == str or type(resFile) == unicode: -``` -修改为: -``` -if type(resFile) == str: ``` \ No newline at end of file -- Gitee From 04d0da12a8b7c712ad8855f10e6a3501f0b0ed2b Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Tue, 3 Dec 2024 13:02:30 +0000 Subject: [PATCH 15/28] update contrib/FCOS/README.md. Signed-off-by: hid54630209 --- contrib/FCOS/README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/contrib/FCOS/README.md b/contrib/FCOS/README.md index 25846bb18..bde6e2961 100644 --- a/contrib/FCOS/README.md +++ b/contrib/FCOS/README.md @@ -4,7 +4,7 @@ ### 1.1 简介 -本开发项目演示FCOS模型实现目标检测。本系统基于mxVision SDK进行开发,以昇腾Atlas310卡为主要的硬件平台,主要实现目标检测。待检测的图片中物体不能被遮挡太严重,并且物体要完全出现在图片中。图片亮度不能过低。输入一张图片,最后会输出图片中能检测到的物体。项目主要流程: +本开发项目演示FCOS模型实现目标检测。本系统基于mxVision SDK进行开发,主要实现目标检测。待检测的图片中物体不能被遮挡太严重,并且物体要完全出现在图片中。图片亮度不能过低。输入一张图片,最后会输出图片中能检测到的物体。项目主要流程: 1.环境搭建; 2.模型转换; @@ -66,10 +66,11 @@ pip3 install mmdet ## 2 设置环境变量 在项目开始运行前需要设置环境变量: - -``` -. /usr/local/Ascend/ascend-toolkit/set_env.sh -. ${SDK安装路径}/mxVision/set_env.sh +```bash +. ${ascend-toolkit-path}/set_env.sh +. ${mxVision-path}/set_env.sh +# mxVision-path: mxVision安装路径 +# ascend-toolkit-path: CANN安装路径 ``` ## 3 准备模型 -- Gitee From d720f840ddf1c85af5d2a90feb4e8efea1c50774 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Tue, 3 Dec 2024 13:24:51 +0000 Subject: [PATCH 16/28] update contrib/FCOS/build.sh. Signed-off-by: hid54630209 --- contrib/FCOS/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/FCOS/build.sh b/contrib/FCOS/build.sh index 2f013a99a..9ee279ef1 100644 --- a/contrib/FCOS/build.sh +++ b/contrib/FCOS/build.sh @@ -27,7 +27,7 @@ for sample in "${SAMPLE_FOLDER[@]}";do } done -if [ ${err_flag} -eq 1]; then +if [ ${err_flag} -eq 1 ]; then exit 1 fi exit 0 \ No newline at end of file -- Gitee From defcea3e0f3bc4b2c4245b61478a8faac0879f60 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Tue, 3 Dec 2024 13:36:07 +0000 Subject: [PATCH 17/28] add contrib/FCOS/models/coco.names. Signed-off-by: hid54630209 --- contrib/FCOS/models/coco.names | 80 ++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 contrib/FCOS/models/coco.names diff --git a/contrib/FCOS/models/coco.names b/contrib/FCOS/models/coco.names new file mode 100644 index 000000000..5ec6eeea2 --- /dev/null +++ b/contrib/FCOS/models/coco.names @@ -0,0 +1,80 @@ +person +bicycle +car +motorbike +aeroplane +bus +train +truck +boat +traffic light +fire hydrant +stop sign +parking meter +bench +bird +cat +dog +horse +sheep +cow +elephant +bear +zebra +giraffe +backpack +umbrella +handbag +tie +suitcase +frisbee +skis +snowboard +sports ball +kite +baseball bat +baseball glove +skateboard +surfboard +tennis racket +bottle +wine glass +cup +fork +knife +spoon +bowl +banana +apple +sandwich +orange +broccoli +carrot +hot dog +pizza +donut +cake +chair +sofa +pottedplant +bed +diningtable +toilet +tvmonitor +laptop +mouse +remote +keyboard +cell phone +microwave +oven +toaster +sink +refrigerator +book +clock +vase +scissors +teddy bear +hair drier +toothbrush -- Gitee From 8613196e733ee5446516243cbb74f2d7c8e28535 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Wed, 4 Dec 2024 06:18:25 +0000 Subject: [PATCH 18/28] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- contrib/FCOS/README.md | 129 ++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 84 deletions(-) diff --git a/contrib/FCOS/README.md b/contrib/FCOS/README.md index bde6e2961..bf8b9c942 100644 --- a/contrib/FCOS/README.md +++ b/contrib/FCOS/README.md @@ -4,12 +4,11 @@ ### 1.1 简介 -本开发项目演示FCOS模型实现目标检测。本系统基于mxVision SDK进行开发,主要实现目标检测。待检测的图片中物体不能被遮挡太严重,并且物体要完全出现在图片中。图片亮度不能过低。输入一张图片,最后会输出图片中能检测到的物体。项目主要流程: +本开发项目演示FCOS模型实现目标检测。本项目使用的模型是FCOS目标检测模型这个模型是一个无anchor检测器。FCOS直接把预测特征图上的每个位置$(x,y)$当作训练样本,若这个位置在某个ground truth box的内部,则视为正样本,该位置的类别标签$c$对应这个box的类别,反之则视为负样本。这个网络的输出为目标框的左上角坐标、右下角坐标、类别和置信度。 + +本系统基于mxVision SDK进行开发,主要实现目标检测。待检测的图片中物体不能被遮挡太严重,并且物体要完全出现在图片中。图片亮度不能过低。输入一张图片,最后会输出图片中能检测到的物体信息、并输出可视化结果图片。 + -1.环境搭建; -2.模型转换; -3.生成后处理插件; -4.进行精度、性能对比。 ### 1.2 支持的产品 @@ -23,45 +22,39 @@ ### 1.4 三方依赖 -项目运行过程中涉及到的第三方软件依赖如下表所示: - -| 软件名称 | 说明 | 使用教程 | -| ----------- | -------------------- | --------------------------------------------------------- | -| pycocotools | 用于实现代码测评 | [点击打开链接](https://cocodataset.org/) | -| mmdetection | 用于实现模型精度评估 | [点击打开链接](https://github.com/open-mmlab/mmdetection) | -| mmcv | 用于实现图片前处理 | [点击打开链接](https://github.com/open-mmlab/mmcv) | +本项目除了依赖昇腾Driver、Firmware、CANN和MxVision及其要求的配套软件外,还需额外依赖以下软件: -安装python COCO测评工具,mmcv和mmdetection。执行命令: - -``` -pip3 install pycocotools -pip3 install mmcv-full -pip3 install mmdet -``` +| 软件名称 | 版本 | +|---------------|----------| +| opencv-python | 4.6.0.66 | +| numpy | 1.23.2 | +| mmcv | 1.7.0 | +| webcolors | 1.13 | ### 1.5 代码目录结构说明 本项目名为FCOS目标检测,项目的目录如下所示: ``` -|- models -| |- fcos.onnx //onnx模型 -| |_ Fcos_tf_bs.cfg -|- pipeline -| |_ FCOSdetection.pipeline -|- plugin -| |_FCOSPostprocess -| |- CMakeLists.txt -| |- FCOSDetectionPostProcess.cpp -| |- FCOSDetectionPostProcess.h -| |_ build.sh -|- image -| |- image1.png -| |_ image2.png -|- build.sh -|- evaluate.py -|- colorlist.txt -|_ main.py +├── build.sh +├── colorlist.txt +├── evaluate.py +├── image +│ ├── image1.png +│ └── image2.png +├── main.py +├── models +│ ├── coco.names +│ └── Fcos_tf_bs.cfg +├── pipeline +│ └── FCOSdetection.pipeline +├── plugin +│ └── FCOSPostprocess +│ ├── build.sh +│ ├── CMakeLists.txt +│ ├── FCOSDetectionPostProcess.cpp +│ └── FCOSDetectionPostProcess.h +└── README.md ``` ## 2 设置环境变量 @@ -75,22 +68,19 @@ pip3 install mmdet ## 3 准备模型 -本项目使用的模型是FCOS目标检测模型这个模型是一个无anchor检测器。FCOS直接把预测特征图上的每个位置$(x,y)$当作训练样本,若这个位置在某个ground truth box的内部,则视为正样本,该位置的类别标签$c$对应这个box的类别,反之则视为负样本。这个网络的输出为目标框的左上角坐标、右下角坐标、类别和置信度。本项目的onnx模型可以直接[下载](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/Fcos/ATC%20Fcos.zip)。下载后,里面自带的om模型是可以直接使用的,或者自行使用ATC工具将onnx模型转换成为om模型,模型转换工具的使用说明参考[链接](https://gitee.com/ascend/docs-openmind/blob/master/guide/mindx/sdk/tutorials/%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99.md)。 +步骤1 下载模型相关文件 -模型转换步骤如下: +根据[链接](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/Fcos/ATC%20Fcos.zip)下载并解压,在解压后的model目录下得到fcos.onnx文件,并放在项目根目录的``models`` 目录下。 -**步骤1:** -从下载链接处下载onnx模型至FCOS/models文件夹下。 -**步骤2:** -模型转换语句如下: +步骤2 转换模型格式 +放在项目根目录的``models`` 目录下,执行如下命令: ``` atc --model=fcos.onnx --framework=5 --soc_version=Ascend310 --input_format=NCHW --input_shape="input:1,3,800,1333" --output=fcos_bs1 --precision_mode=allow_fp32_to_fp16 ``` -**步骤3:** -执行完该命令之后,会在models文件夹下生成.om模型,并且转换成功之后会在终端输出: +执行完该命令之后,会在models文件夹下生成fcos_bs1.om模型,并且转换成功之后会在终端输出: ``` ATC start working now, please wait for a moment. @@ -101,59 +91,30 @@ ATC run success, welcome to the next use. ## 4 编译与运行 -**步骤1:** +**步骤1** 准备一张jpg图片,修改main.py + + +第**120**行 `IMAGENAME = '{image path}'`中的{image path}替换为实际的jpg图片路径。 -准备一张待检测图片,并上传到FCOS文件夹下。然后修改main.py文件里面的图片路径为待检测的图片路径。并且从https://github.com/pjreddie/darknet/blob/master/data/coco.names 里面下载coco.names文件,并且将这个文件存放到models文件夹下。并且修改main.py里IMAGENAME为图片的路径: -```python -IMAGENAME = '{image path}' // 120行 -``` -**步骤2:** + +**步骤2** 编译 进入FCOS/plugin/FCOSPostprocess目录,在该目录下运行下列命令: ``` bash build.sh ``` -这个后处理插件即可以使用。 -**步骤3:** -在FCOS目录下执行命令: +**步骤3** 运行 + +在项目根目录下执行以下命令: ``` python3 main.py ``` -**步骤4:查看结果** +**步骤4** 查看结果 最后生成的结果会在FCOS文件夹目录下result.jpg图片中。 - -## 5 常见问题 -### 5.1 模型路径配置问题: -问题描述: -检测过程中用到的模型以及模型后处理插件需配置路径属性。 - -后处理插件以及模型推理插件配置例子: - -```json -// 模型推理插件 - "mxpi_tensorinfer0": { - "props": { - "dataSource": "mxpi_imageresize0", - "modelPath": "./models/fcos_bs1.om" - }, - "factory": "mxpi_tensorinfer", - "next": "mxpi_objectpostprocessor0" - }, -// 模型后处理插件 - "mxpi_objectpostprocessor0":{ - "props": { - "dataSource" : "mxpi_tensorinfer0", - "postProcessConfigPath": "./models/Fcos_tf_bs.cfg", - "postProcessLibPath": "libFCOSDetectionPostProcess.so" - }, - "factory": "mxpi_objectpostprocessor", - "next": "mxpi_dataserialize0" - }, -``` \ No newline at end of file -- Gitee From 6a2dcc1e9c21b80944c58e15fc90f982b958a6b1 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Wed, 4 Dec 2024 06:19:48 +0000 Subject: [PATCH 19/28] update contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt. Signed-off-by: hid54630209 --- contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt b/contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt index 14fdc0321..38bf8a03a 100644 --- a/contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt +++ b/contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt @@ -18,7 +18,7 @@ include_directories(${MX_SDK_HOME}/opensource/include/opencv4) link_directories(${MX_SDK_HOME}/opensource/lib/) link_directories(${MX_SDK_HOME}/lib) -add_compile_options(-std=c++11 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations) +add_compile_options(-std=c++14 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations) add_compile_options("-DPLUGIN_NAME=${PLUGIN_NAME}") add_definitions(-DENABLE_DVPP_INTERFACE) -- Gitee From ab43158623ae7d6fa4ed8ef5c34d11f917fce063 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Wed, 4 Dec 2024 06:20:17 +0000 Subject: [PATCH 20/28] update contrib/FCOS/plugin/FCOSPostprocess/FCOSDetectionPostProcess.cpp. Signed-off-by: hid54630209 --- .../FCOS/plugin/FCOSPostprocess/FCOSDetectionPostProcess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/FCOS/plugin/FCOSPostprocess/FCOSDetectionPostProcess.cpp b/contrib/FCOS/plugin/FCOSPostprocess/FCOSDetectionPostProcess.cpp index 479aa5271..6c174f69c 100644 --- a/contrib/FCOS/plugin/FCOSPostprocess/FCOSDetectionPostProcess.cpp +++ b/contrib/FCOS/plugin/FCOSPostprocess/FCOSDetectionPostProcess.cpp @@ -99,7 +99,7 @@ APP_ERROR FCOSPostProcess::Process( } std::vector objectInfo; auto res0 = (float *)tensors[0].GetBuffer(); - auto classIdx = (__int64 *)tensors[1].GetBuffer(); + auto classIdx = (int64 *)tensors[1].GetBuffer(); auto shape1 = tensors[1].GetShape(); for (uint32_t i = 0; i < shape[1]; i++) { float *beginRes = res0 + i * 5; -- Gitee From f0a5b10dec2b8ebe4e16652d3dbbcdb6f0a0b284 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Wed, 4 Dec 2024 06:42:24 +0000 Subject: [PATCH 21/28] update contrib/FCOS/README.md. Signed-off-by: hid54630209 --- contrib/FCOS/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/FCOS/README.md b/contrib/FCOS/README.md index bf8b9c942..9e1351b42 100644 --- a/contrib/FCOS/README.md +++ b/contrib/FCOS/README.md @@ -91,7 +91,7 @@ ATC run success, welcome to the next use. ## 4 编译与运行 -**步骤1** 准备一张jpg图片,修改main.py +**步骤1** 准备一张jpg图片放到项目目录下,然后修改main.py 第**120**行 `IMAGENAME = '{image path}'`中的{image path}替换为实际的jpg图片路径。 @@ -99,7 +99,7 @@ ATC run success, welcome to the next use. **步骤2** 编译 -进入FCOS/plugin/FCOSPostprocess目录,在该目录下运行下列命令: +进入在项目根目录的plugin/FCOSPostprocess目录,在该目录下运行下列命令: ``` bash build.sh @@ -116,5 +116,5 @@ python3 main.py **步骤4** 查看结果 -最后生成的结果会在FCOS文件夹目录下result.jpg图片中。 +标准输出中会打印目标检测信息,项目根目录下result.jpg图片中会保存可视化检测结果。 -- Gitee From bd794eb2b6884a58f90ca7b43c49ce0cc3f76c44 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Wed, 4 Dec 2024 07:44:29 +0000 Subject: [PATCH 22/28] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- contrib/FCOS/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/FCOS/README.md b/contrib/FCOS/README.md index 9e1351b42..bff645c28 100644 --- a/contrib/FCOS/README.md +++ b/contrib/FCOS/README.md @@ -116,5 +116,5 @@ python3 main.py **步骤4** 查看结果 -标准输出中会打印目标检测信息,项目根目录下result.jpg图片中会保存可视化检测结果。 +标准输出中会打印目标检测信息,项目根目录下result.jpg图片会保存可视化检测结果。 -- Gitee From 37aa675496be7d7e6783b106727616f3a8d3a0f1 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Wed, 4 Dec 2024 08:05:36 +0000 Subject: [PATCH 23/28] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20co?= =?UTF-8?q?ntrib/FCOS/evaluate.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/FCOS/evaluate.py | 206 --------------------------------------- 1 file changed, 206 deletions(-) delete mode 100644 contrib/FCOS/evaluate.py diff --git a/contrib/FCOS/evaluate.py b/contrib/FCOS/evaluate.py deleted file mode 100644 index 89edff607..000000000 --- a/contrib/FCOS/evaluate.py +++ /dev/null @@ -1,206 +0,0 @@ -# !/usr/bin/env python -# coding=utf-8 - -# Copyright(C) 2021. Huawei Technologies Co.,Ltd. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import sys -import os -import argparse -import json -import cv2 -import numpy as np -import time -import mmcv - -from pycocotools.coco import COCO -from pycocotools.cocoeval import COCOeval -import MxpiDataType_pb2 as MxpiDataType -from StreamManagerApi import StreamManagerApi, MxDataInput, InProtobufVector, StringVector, MxProtobufIn -from mmdet.core import bbox2result -from mmdet.core import encode_mask_results -from mmdet.datasets import CocoDataset - - -def resizeImage(img, size): - old_h = img.shape[0] - old_w = img.shape[1] - scale_ratio = min(size[0] / old_w, size[1] / old_h) - new_w = int(np.floor(old_w * scale_ratio)) - new_h = int(np.floor(old_h * scale_ratio)) - img = mmcv.imresize(img, (new_w, new_h), backend='cv2') - return img, scale_ratio - - -def preprocess(imagePath): - image = mmcv.imread(imagePath, backend='cv2') - image, SCALE = resizeImage(image, (1333, 800)) - h = image.shape[0] - w = image.shape[1] - mean = np.array([102.9801, 115.9465, 122.7717], dtype=np.float32) - std = np.array([1.0, 1.0, 1.0], dtype=np.float32) - norm_img_data = mmcv.imnormalize(image, mean, std, to_rgb=False) - pad_left = (1333 - w) // 2 - pad_top = (800 - h) // 2 - pad_right = 1333 - w - pad_left - pad_bottom = 800 - h - pad_top - image_for_infer = mmcv.impad(norm_img_data, - padding=(pad_left, pad_top, pad_right, - pad_bottom), - pad_val=0) - image_for_infer = image_for_infer.transpose(2, 0, 1) - return image_for_infer, [SCALE, pad_left, pad_top, pad_right, pad_bottom] - - -if __name__ == '__main__': - # init stream manager - stream_manager_api = StreamManagerApi() - ret = stream_manager_api.InitManager() - if ret != 0: - print("Failed to init Stream manager, ret=%s" % str(ret)) - exit() - - # create streams by pipeline config file - pipeline_path = './pipeline/FCOSdetection.pipeline' - print('pipeline path: ', pipeline_path) - with open(pipeline_path, "rb") as f: - pipeline_str = f.read() - ret = stream_manager_api.CreateMultipleStreams(pipeline_str) - if ret != 0: - print("Failed to create Stream, ret=%s" % str(ret)) - exit() - stream_name = b"detection" - in_plugin_id = 0 - - image_folder = './dataset/val2017' - annotation_file = './dataset/annotations/instances_val2017.json' - - coco_gt = COCO(annotation_file) - image_ids = coco_gt.getImgIds() - print('Test on coco2017 test-dev dataset, ', len(image_ids), - ' images in total.') - - coco_result = [] - - for image_idx, image_id in enumerate(image_ids): - print('image_idx = %d image_id = %d.' % - (image_idx, image_id)) # image_id is name of picture - image_info = coco_gt.loadImgs(image_id)[0] # 获取这张测试图片的信息 - image_path = os.path.join(image_folder, - image_info['file_name']) # 获取测试图片的路径 - print('Detect image: ', image_idx, ': ', image_info['file_name'], - ', image id: ', image_id) - if os.path.exists(image_path) != 1: - print("The test image does not exist. Exit.") - exit() - - tensorData, return_image = preprocess(image_path) - tensor = tensorData[None, :] - - visionList = MxpiDataType.MxpiVisionList() - visionVec = visionList.visionVec.add() - visionInfo = visionVec.visionInfo - - visionInfo.width = 1333 - visionInfo.height = 800 - visionInfo.widthAligned = 1333 - visionInfo.heightAligned = 800 - visionData = visionVec.visionData - visionData.dataStr = tensor.tobytes() - visionData.deviceId = 0 - visionData.memType = 0 - visionData.dataSize = len(tensor) - - # stream_name = b"detection" - KEYVALUE = b'appsrc0' - protobufVec = InProtobufVector() - protobuf = MxProtobufIn() - protobuf.key = KEYVALUE - protobuf.type = b"MxTools.MxpiVisionList" - protobuf.protobuf = visionList.SerializeToString() - protobufVec.push_back(protobuf) - unique_id = stream_manager_api.SendProtobuf(stream_name, in_plugin_id, - protobufVec) - - if unique_id < 0: - print("Failed to send data to stream.") - exit() - key_vec = StringVector() - key_vec.push_back(b"mxpi_objectpostprocessor0") - infer_result = stream_manager_api.GetProtobuf( - stream_name, 0, key_vec) # 获取本张图片的测试结果(目标框) - if infer_result.size() == 0: - print("infer_result is null") - continue - if infer_result[0].errorCode != 0: - print("infer_result error. errorCode=%d" % - (infer_result[0].errorCode)) - exit() - - objectList = MxpiDataType.MxpiObjectList() - objectList.ParseFromString(infer_result[0].messageBuf) - SCALE, pad_left, pad_top, pad_right, pad_bottom = return_image # 用来复原目标框 - bboxfileName = 'bboxres' + str(image_id) + '.bin' - classfileName = 'class' + str(image_id) + '.bin' - bboxresultList = [] - classresultList = [] - for obj in objectList.objectVec: - box = { - 'x0': max(int((obj.x0 - pad_left) / SCALE), 0), - 'x1': max(int((obj.x1 - pad_left) / SCALE), 0), - 'y0': max(int((obj.y0 - pad_top) / SCALE), 0), - 'y1': max(int((obj.y1 - pad_top) / SCALE), 0), - 'class': obj.classVec[0].classId, - 'confidence': obj.classVec[0].confidence - } - # box: x0, y0, w, h - bboxresultList.append(max(float((obj.x0 - pad_left) / SCALE), 0.0)) - bboxresultList.append(max(float((obj.y0 - pad_top) / SCALE), 0.0)) - bboxresultList.append(max(float((obj.x1 - pad_left) / SCALE), 0.0)) - bboxresultList.append(max(float((obj.y1 - pad_top) / SCALE), 0.0)) - bboxresultList.append(obj.classVec[0].confidence) - classresultList.append(obj.classVec[0].classId) - - bboxresultnumpy = np.array(bboxresultList, dtype=np.float32) - classresultnumpy = np.array(classresultList, dtype=np.int64) - bboxresultnumpy.tofile('./binresult/' + bboxfileName) - classresultnumpy.tofile('./binresult/' + classfileName) - - coco_dataset = CocoDataset( - ann_file='./dataset/annotations/instances_val2017.json', pipeline=[]) - results = [] - - for ids in coco_dataset.img_ids: - print('image ids = {}'.format(ids)) - bbox_results = [] - # read bbox information - BBOX_RES_PATH = './binresult/bboxres' + str(ids) + '.bin' - REBLES_RES_PATH = './binresult/class' + str(ids) + '.bin' - bboxes = np.fromfile(BBOX_RES_PATH, dtype=np.float32) - bboxes = np.reshape(bboxes, [100, 5]) - bboxes.tolist() - # read label information - labels = np.fromfile(REBLES_RES_PATH, dtype=np.int64) - labels = np.reshape(labels, [100, 1]) - labels.tolist() - bbox_results = [bbox2result(bboxes, labels[:, 0], 80)] - - result = bbox_results - results.extend(result) - print('Evaluating...') - eval_results = coco_dataset.evaluate(results, - metric=[ - 'bbox', - ], - classwise=True) - print(eval_results) \ No newline at end of file -- Gitee From 8839e3ac796a0eb08d6a646db266b8371759f8ab Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Wed, 4 Dec 2024 08:06:16 +0000 Subject: [PATCH 24/28] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20co?= =?UTF-8?q?ntrib/FCOS/build.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/FCOS/build.sh | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 contrib/FCOS/build.sh diff --git a/contrib/FCOS/build.sh b/contrib/FCOS/build.sh deleted file mode 100644 index 9ee279ef1..000000000 --- a/contrib/FCOS/build.sh +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright(C) 2022. Huawei Technologies Co.,Ltd. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -set -e -current_folder="$( cd "$(dirname "$0")" ;pwd -P )" - -SAMPLE_FOLDER=( -/plugin/FCOSPostprocess/ -) - -err_flag=0 -for sample in "${SAMPLE_FOLDER[@]}";do - cd "${current_folder}/${sample}" - bash build.sh || { - echo -e "Failed to build ${sample}" - err_flag=1 - } -done - -if [ ${err_flag} -eq 1 ]; then - exit 1 -fi -exit 0 \ No newline at end of file -- Gitee From 7b02d394a5a870f06d7b23c980f99ea06098d4df Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Wed, 4 Dec 2024 08:07:19 +0000 Subject: [PATCH 25/28] update contrib/FCOS/README.md. Signed-off-by: hid54630209 --- contrib/FCOS/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/contrib/FCOS/README.md b/contrib/FCOS/README.md index bff645c28..109a96ef8 100644 --- a/contrib/FCOS/README.md +++ b/contrib/FCOS/README.md @@ -36,9 +36,7 @@ 本项目名为FCOS目标检测,项目的目录如下所示: ``` -├── build.sh ├── colorlist.txt -├── evaluate.py ├── image │ ├── image1.png │ └── image2.png -- Gitee From 9bb4bbaaa4b76b578c19397860f4b06c9cde26cc Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Wed, 4 Dec 2024 08:08:23 +0000 Subject: [PATCH 26/28] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20co?= =?UTF-8?q?ntrib/FCOS/image/image2.png?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/FCOS/image/image2.png | Bin 137683 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 contrib/FCOS/image/image2.png diff --git a/contrib/FCOS/image/image2.png b/contrib/FCOS/image/image2.png deleted file mode 100644 index b5c62be596f510d624766da680bc5af2e41aaa87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137683 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

~F`= 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�OFzvqk7v&Bf88eTPXRlpir)6!{vpYQFAWwW1_ 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�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

2l3-zvwWFF#hSv}lEt z)3@hz4}Akx>VA4cg~Bt}AP&y(DadUsZg7vtBO`*Wxc!`mnfLDw(sH09o@ZblUOxim~ujC^8vZgvEm#P5358mIl^#T19qgrY(PU2kfQT z9IvxQ%l1jm^lG%;`&ZZ54t05YB{F_1m5N+CR< zR@{vLm?u=0dCBdWwpl)o8NFU>mJH>C3JDI@V`zBG=(}UVY-~_x6eFyvB_Wg+p^#0o zba)kM2yePD$#O>pH9)WR4H2^A`K_9uBy|QWBXh9I`)E@IL2)1s za{;NB$(o+L)z?hMvU5WHg;U+1$m&fM2 zry*l8@SEcNmPPvQ_AIl%(%$V!9!6F_fmsf%*-_ovhxl9cD;|SLF8mi&+ow4(S4RdB zk2kr+O9ExYaFMMK02=TPM}zDT`lT# z=}e&7HhF;b#1cK4D-K{|V=uaTP|?cx{?g+4%-AogZrBFvMTYI|oaoI4ZbB+w_=Oi! zsk2hb0ehU4R(CeCdFDbYi&|a1mC9)~H6|B!)1D>Hw@0}L$DoS5k(EY3il3Lchk(sT7$e`PKAPC~P2FggNcS0_XC%I`X}aW8nT7ycscLIQ%vBdY;d_4vEP*Q=R5RNQ+V zqc^BJ=9g~wZ+qB8uP%tT*(@*3hBisHz?|!TKzGxtHiW|D6GIcE#k4m?LnKzu)$G+TE$Zi} z@+v)0i7wNLng%M|d-hgBmOLHh9LsND)mzpufl&?z)NEpW#k08N?Jv-ie)gNLL&fsl zV%V5x9TB?J%f_ z?vYnHl6E9-B$QUTi9o*K8BSiI->y=fk7Y8Q7teoOZAofp8>Kq^cdnnJN6$rT2+@Y& z@dK)a09Nb2R53Lq+0SA6!*}<~l84gb7wcN~umW3;7u*LfMSw+sE$*VC3aXRST};Kl z2XpI~CxTFQvvm8@7&Q6KQj5@C4Zhl6IO9J@Bl3CCP#)kJcuj;tVO3*c9n)Rb{J|1` zO5`BEg-1i#o>JgHCnW|v_F+1tF5**>0u!erTDmjOPA_2>`MkqGD=FIP2JAyZ$|> z3#FG3VLi##jK~nW{_=hF&+Q1{8*zV{?K5TIT>d!=w`co*^#K(df$wW$z2O1;%;^H~ N($g}yU8Z3h_75Lu)Y$+4 -- Gitee From 746bc00668969b4f49f7f46b85704d6c2a224a47 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Wed, 4 Dec 2024 08:09:20 +0000 Subject: [PATCH 27/28] update contrib/FCOS/README.md. Signed-off-by: hid54630209 --- contrib/FCOS/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/FCOS/README.md b/contrib/FCOS/README.md index 109a96ef8..b4681b8a3 100644 --- a/contrib/FCOS/README.md +++ b/contrib/FCOS/README.md @@ -8,6 +8,10 @@ 本系统基于mxVision SDK进行开发,主要实现目标检测。待检测的图片中物体不能被遮挡太严重,并且物体要完全出现在图片中。图片亮度不能过低。输入一张图片,最后会输出图片中能检测到的物体信息、并输出可视化结果图片。 +本项目实现对输入的图片进行目标检测,整体流程如下: + +![avatar](./image/image1.png) + ### 1.2 支持的产品 -- Gitee From 0640e1e0c02a2e468e2269e19940dc9961e0a229 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Wed, 4 Dec 2024 08:11:01 +0000 Subject: [PATCH 28/28] update contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt. Signed-off-by: hid54630209 --- contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt b/contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt index 38bf8a03a..14fdc0321 100644 --- a/contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt +++ b/contrib/FCOS/plugin/FCOSPostprocess/CMakeLists.txt @@ -18,7 +18,7 @@ include_directories(${MX_SDK_HOME}/opensource/include/opencv4) link_directories(${MX_SDK_HOME}/opensource/lib/) link_directories(${MX_SDK_HOME}/lib) -add_compile_options(-std=c++14 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations) +add_compile_options(-std=c++11 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations) add_compile_options("-DPLUGIN_NAME=${PLUGIN_NAME}") add_definitions(-DENABLE_DVPP_INTERFACE) -- Gitee