• [问题求助] 【物联网应用侧开发SDK产品】【node.js 功能】构建npm报错
    【功能模块】我想使用开发微信小程序连接华为云的物联网平台,就简单的数据收发就行,我看有官方的node.js sdk,然后我npm install后,构建npm会报下面的错,有大神知道吗?【操作步骤&问题现象】1、npm install @huaweicloud/huaweicloud-sdk-core2、npm install @huaweicloud/huaweicloud-sdk-iotda3、构建npm【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [沙箱纠错] 使用MindX SDK开发智能质检应用_步骤
    7.2 运行程序步骤,没有在北京4找到ECS-ai这台ECS
  • [问题求助] 【mindx SDK产品】【pipeline功能】已经加载的pipeline如何切换输入源
    使用mindx SDK对视频片段进行推理时,加载pipeline文件后会对模型进行加载等工作。我有一个场景,是同一个模型对若干个视频片段进行识别,每推理一个视频片段时不重新加载pipeline,只切换视频源。
  • [MindX SDK] sdk版本为MindX SDK 2.0.2 配置YOLOV5推理, 推理PNG图像格式报错
    【功能模块】sdk版本为MindX SDK 2.0.2 配置YOLOV5推理, 推理PNG图像格式报错,查看推理配置Pipline文件相关的"mxpi_imagedecoder0": {      "factory": "mxpi_imagedecoder",      "next": "mxpi_imageresize0"    }, 仅支持jpg???【操作步骤&问题现象】1、推理报错:2、如何才能支持PNG格式推理,谢谢求助【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [问题求助] 【Atlas 800 3010产品】【MindX SDK推理】进行FairMot的推理时出现无法初始化所有设备的问题
    【功能模块】推理:在atlas 800 3010上进行fairmot的MindX SDK推理【操作步骤&问题现象】1、从Ascend modelzoo下载fairmot的脚本和模型权重2、启动docker3、进入fairmot源码的infer目录,运行bash run.sh4、出现无法初始化所有设备的报错:【截图信息】【日志信息】(可选,上传日志内容或者附件)call drvMngGetConsoleLogLevel failed , g_conLogLevel = 3[EVENT] PROFILING(18,python3.7):2022-06-24-08:23:17.086.500 [msprof_callback_impl.cpp:151] >>> (tid:18) Started to register profiling callbacks to aclThe device id: 0.Begin to initialize Log.The output directory of logs file doesn't exist.Create directory to save logs information.Save logs information to specified directory.I0624 08:23:17.097687    18 MxStreamManagerDptr.cpp:354] Set the default value of "GST_PLUGIN_SCANNER" based on "MX_SDK_HOME".I0624 08:23:17.097805    18 MxStreamManagerDptr.cpp:354] Set the default value of "GST_PLUGIN_PATH" based on "MX_SDK_HOME".I0624 08:23:17.097939    18 MxStreamManagerDptr.cpp:475] log rotate day(7).I0624 08:23:17.098004    18 MxStreamManagerDptr.cpp:484] log rotate file number(50).call drvMngGetConsoleLogLevel failed , g_conLogLevel = 3[EVENT] PROFILING(32,gst-plugin-scanner):2022-06-24-08:23:17.207.374 [msprof_callback_impl.cpp:151] >>> (tid:32) Started to register profiling callbacks to acl[EVENT] IDEDH(32,gst-plugin-scanner):2022-06-24-08:23:17.301.604 [adx_server_manager.cpp:27][tid:32]>>> start to deconstruct adx server managerI0624 08:23:17.345232    18 MxsmStream.cpp:1569] Validates appsink0 element successfully.I0624 08:23:17.346163    18 MxsmElement.cpp:410] Gets appsrc factory successfully.I0624 08:23:17.346279    18 MxsmStream.cpp:1569] Validates appsrc0 element successfully.I0624 08:23:17.348372    18 MxsmElement.cpp:410] Gets mxpi_dataserialize factory successfully.I0624 08:23:17.348438    18 MxsmStream.cpp:1569] Validates mxpi_dataserialize0 element successfully.I0624 08:23:17.351769    18 MxsmElement.cpp:410] Gets mxpi_modelinfer factory successfully.I0624 08:23:17.351886    18 MxsmStream.cpp:1569] Validates mxpi_modelinfer0 element successfully.I0624 08:23:17.352079    18 MxsmStream.cpp:583] Gets the value of stream_config deviceId(0).I0624 08:23:17.352180    18 MxsmStream.cpp:641] Add element to stream, element name is appsink0I0624 08:23:17.352468    18 MxsmElement.cpp:97] Sets element(appsink0) to async.I0624 08:23:17.352499    18 MxsmElement.cpp:186] Handles appsink factory successfully.I0624 08:23:17.352546    18 MxsmElement.cpp:321] Sets element(appsink0) properties successfully.I0624 08:23:17.352576    18 MxsmElement.cpp:356] Creates appsink0 element successfully.I0624 08:23:17.352681    18 MxsmStream.cpp:428] Adds appsink0 element to Stream successfully.I0624 08:23:17.352703    18 MxsmStream.cpp:641] Add element to stream, element name is appsrc0I0624 08:23:17.352766    18 MxsmElement.cpp:186] Handles appsrc factory successfully.I0624 08:23:17.352823    18 MxsmElement.cpp:220] Sets block property successfully.I0624 08:23:17.352849    18 MxsmElement.cpp:220] Sets max-bytes property successfully.I0624 08:23:17.352869    18 MxsmElement.cpp:220] Sets blocksize property successfully.I0624 08:23:17.352880    18 MxsmElement.cpp:321] Sets element(appsrc0) properties successfully.I0624 08:23:17.352890    18 MxsmElement.cpp:356] Creates appsrc0 element successfully.I0624 08:23:17.352921    18 MxsmStream.cpp:428] Adds appsrc0 element to Stream successfully.I0624 08:23:17.352941    18 MxsmStream.cpp:641] Add element to stream, element name is mxpi_dataserialize0I0624 08:23:17.353083    18 MxsmElement.cpp:186] Handles mxpi_dataserialize factory successfully.I0624 08:23:17.353116    18 MxsmElement.cpp:220] Sets deviceId property successfully.I0624 08:23:17.353132    18 MxsmElement.cpp:240] Sets element(mxpi_dataserialize0) to use stream_config deviceId(0).I0624 08:23:17.353161    18 MxsmElement.cpp:220] Sets outputDataKeys property successfully.I0624 08:23:17.353230    18 MxsmElement.cpp:321] Sets element(mxpi_dataserialize0) properties successfully.I0624 08:23:17.353242    18 MxsmElement.cpp:356] Creates mxpi_dataserialize0 element successfully.I0624 08:23:17.353296    18 MxsmStream.cpp:428] Adds mxpi_dataserialize0 element to Stream successfully.I0624 08:23:17.353333    18 MxsmStream.cpp:641] Add element to stream, element name is mxpi_modelinfer0I0624 08:23:17.353493    18 MxsmElement.cpp:186] Handles mxpi_modelinfer factory successfully.I0624 08:23:17.353529    18 MxsmElement.cpp:220] Sets deviceId property successfully.I0624 08:23:17.353544    18 MxsmElement.cpp:240] Sets element(mxpi_modelinfer0) to use stream_config deviceId(0).I0624 08:23:17.353580    18 MxsmElement.cpp:220] Sets dataSource property successfully.I0624 08:23:17.353619    18 MxsmElement.cpp:220] Sets modelPath property successfully.I0624 08:23:17.353652    18 MxsmElement.cpp:220] Sets tensorFormat property successfully.I0624 08:23:17.353668    18 MxsmElement.cpp:321] Sets element(mxpi_modelinfer0) properties successfully.I0624 08:23:17.353690    18 MxsmElement.cpp:356] Creates mxpi_modelinfer0 element successfully.I0624 08:23:17.353719    18 MxsmStream.cpp:428] Adds mxpi_modelinfer0 element to Stream successfully.I0624 08:23:17.353906    18 MxsmStream.cpp:544] Links all elements successfully.I0624 08:23:17.353940    18 MxsmElement.cpp:878] Element(appsink0) register probe function successfully.I0624 08:23:17.353952    18 MxsmElement.cpp:870] Element(appsrc0) register probe function successfully.I0624 08:23:17.354074    18 MxGstBase.cpp:783] element(mxpi_dataserialize0) gst_change_state NULL_TO_READY.[ERROR] RUNTIME(18,python3.7):2022-06-24-08:23:17.379.561 [runtime.cc:626]18 InitSocType:[INIT][DEFAULT]Call halGetDeviceInfo failed: drvRetCode=4, module type=0, info type=1.[ERROR] RUNTIME(18,python3.7):2022-06-24-08:23:17.379.636 [runtime.cc:704]18 Init:[INIT][DEFAULT]Init SocType failed.[ERROR] RUNTIME(18,python3.7):2022-06-24-08:23:17.379.708 [api_c.cc:2330]18 rtGetSocVersion:[INIT][DEFAULT]ErrCode=507000, desc=[null instance pointer], InnerCode=0x70b0001[ERROR] ASCENDCL(18,python3.7):2022-06-24-08:23:17.379.752 [acl.cpp:167]18 InitSocVersion: [INIT][DEFAULT][Get][SocVersion]get soc version failed, runtime result is 507000[ERROR] ASCENDCL(18,python3.7):2022-06-24-08:23:17.379.778 [acl.cpp:100]18 aclInit: [INIT][DEFAULT][Init][Version]init soc version failed, ret = 507000E0624 08:23:17.379801    18 DeviceManager.cpp:54] Failed to initialize all devices: Error code unknown.E0624 08:23:17.379974    18 MxGstBase.cpp:590] [mxpi_dataserialize0][507000][Error code unknown] Initialize devices failed.E0624 08:23:17.379997    18 MxGstBase.cpp:785] element(mxpi_dataserialize0) MxGstBaseStart error.E0624 08:23:17.380059    18 MxsmStream.cpp:700] [6003][stream change state fail] Failed to set the state of the Stream, named: im_fairmot.E0624 08:23:17.380110    18 MxStreamManagerDptr.cpp:425] [6003][stream change state fail] create stream(im_fairmot) failed.I0624 08:23:17.380126    18 MxsmStream.cpp:753] Begin to destroy stream(im_fairmot).I0624 08:23:17.380151    18 MxsmStream.cpp:809] Send custom eos to the Stream successfully.I0624 08:23:17.380172    18 MxsmStream.cpp:815] Send eos to the Stream successfully.W0624 08:23:17.380190    18 MxsmStream.cpp:823] Failed to flush the Stream data.I0624 08:23:17.380292    18 MxsmStream.cpp:800] Destroys the stream(im_fairmot) successfully.Failed to create stream, ret=6003.I0624 08:23:17.380596    18 MxStreamManager.cpp:76] Begin to destroy management threads.I0624 08:23:17.382032    18 MxStreamManager.cpp:243] Destroy streams successfully.[EVENT] IDEDH(18,python3.7):2022-06-24-08:23:17.409.650 [adx_server_manager.cpp:27][tid:18]>>> start to deconstruct adx server manager
  • [MindX SDK] YOLOX推理应用参考设计案例分享
    # MindX SDK -- YOLOX推理应用参考设计案例 ## 1 案例概述 ### 1.1 概要描述 YOLOX 推理应用是对图片中的不同类目标进行检测,将检测得到的不同类的目标用不同颜色的矩形框标记。输入一幅图像,可以检测得到图像中大部分类别目标的位置。本方案使用在 COCO2017 数据集上训练得到的 YOLOX-Nano 模型进行目标检测,数据集中共包含 80 个目标类,包括行人、自行车、公共汽车、手机、沙发、猫、狗等,可以对不同类别、不同角度、不同密集程度的目标进行检测,并在COCO VAL 2017数据集达到25.3%的准确度。 ### 1.2 模型介绍 YOLOX模型于2021年由开发者Zheng Ge,Songtao Liu,Feng Wang,Zeming Li,Jian Sun在《YOLOX: Exceeding YOLO Series in 2021》首次提出。YOLOX对YOLO系列的进行一些改进,形成了一种新的高性能探测器。配备了一些新的先进检测技术,即解耦头、无锚点和先进的标签分配策略,YOLOX在速度和精度之间实现了更好的平衡,比所有型号尺寸的其他同类产品都好。 ### 1.3 实现流程 YOLOX 的后处理插件接收模型推理插件输出的特征图,该特征图为三张不同分辨率的特征图拼接而成,形状大小为1 x n x 85,其中 n 为三张网络模型输出特征图的像素点数总和,85 为 80 (数据集分类数)+ 4 (目标框回归坐标点)+ 1 (正类置信度)。本项目方案技术流程图如下。 ![pipeline](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/23/1655970638217646084.png) ### 1.4 代码地址 本项目的代码地址为:https://gitee.com/ascend/mindxsdk-referenceapps/tree/master/contrib/YOLOX ## 2 软件方案介绍 ### 2.1 项目方案架构介绍 本系统设计了不同的功能模块。主要流程为:图片经过预处理之后传入流中,利用YOLOX的检测模型初步检测出目标,检测结果输入到后处理插件中,经过阈值筛选,非极大值抑制后得到最终预测结果,最终在原图上进行可视化操作。各模块功能描述如表2.1所示: 表2.1 系统方案中各模块功能: | 序号 | 子系统 | 功能描述 | | ---- | ------ | ------------ | | 1 | 图像输入 | 调用MindX SDK的appsrc输入图片 | | 2 | 模型推理 | 利用yolox的检测模型对原图进行预测 | | 3 | 模型后处理 | 利用yolox后处理插件对推理结果进行处理,得到最终预测结果 | | 4 | 结果输出 | 将目标的位置信息,识别置信度输出 | ### 2.2 代码目录结构与说明 本工程名称为YOLOX,工程目录如下图所示: ``` . ├── build.sh ├── images │   ├── DetectionPipeline.png │   ├── EvaluateInfo.png │   ├── EvaluateInfoPrevious.png │   ├── warning.png │   └── VersionError.png ├── postprocess │   ├── build.sh │   ├── CMakeLists.txt │   ├── YoloxPostProcess.cpp │   └── YoloxPostProcess.h ├── python │   ├── Main │   │   ├── eval_nopre_post.py │   │   ├── eval_pre_post.py │   │   ├── nopre_post.py │   │   ├── pre_post.py │   │   ├── pre_post.py │   │   └── preprocess.py │   ├── models │   │   ├── aipp-configs │   │   │ └── yolox_bgr.cfg │   │   ├── conversion-scripts # 下载的onnx模型存放在该文件夹下 │   │   ├── yolox_eval.cfg │   │   └── coco.names #需要下载,下载链接在下方 │   ├── test │   │   ├── data # 下载的数据集存放在此文件下 │   │   ├── map_calculate.py │   │   └── parse_coco.py #需要下载,下载链接在下方 │   ├── test_img │   │   └── test.jpg # 需要用户自行添加测试数据 │   └── pipeline │   ├── nopre_post.pipeline │   └── pre_post.pipeline └── README.md ``` 注:coco.names文件与parse_coco.py文件分别源于[链接](https://gitee.com/ascend/ModelZoo-PyTorch/tree/master/ACL_PyTorch/built-in/cv/Yolov3_for_Pytorch)的coco2014.names文件和[项目](https://gitee.com/ascend/mindxsdk-referenceapps/tree/master/contrib/FireDetection)中test文件夹下的parse_COCO.py文件,将这两个文件下载之后,分别放到python/models目录下和python/test目录下。 ## 3 开发环境准备 ### 3.1 环境依赖说明 推荐系统为ubuntu 18.04,环境依赖软件和版本如下表: | 软件名称 | 版本 | | -------- | ------ | | cmake | 3.5+ | | mxVision | 2.0.4 | | python | 3.9.2 | 确保环境中正确安装mxVision SDK。 在编译运行项目前,需要设置环境变量: MindSDK 环境变量: ``` . ${SDK-path}/set_env.sh ``` CANN 环境变量: ``` . ${ascend-toolkit-path}/set_env.sh ``` - 环境变量介绍 ``` SDK-path: mxVision SDK 安装路径 ascend-toolkit-path: CANN 安装路径。 ``` ### 3.3 模型转换 本项目中采用的模型是 YOLOX 模型,参考实现代码:https://github.com/Megvii-BaseDetection/YOLOX , 选用的模型是该 pytorch 项目中提供的模型 yolox-Nano.onnx,模型下载链接:https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/YOLOX/yolox_nano.onnx 。本项目使用模型转换工具 ATC 将 onnx 模型转换为 om 模型,模型转换工具相关介绍参考链接:https://support.huaweicloud.com/tg-cannApplicationDev330/atlasatc_16_0005.html 。 1. 从上述项目链接中下载 onnx 模型 yolox_nano.onnx 至 ``python/models/conversion-scripts`` 文件夹下。 2. 将该模型转换为om模型,具体操作为: ``python/models/conversion-scripts`` 文件夹下,执行atc指令: ``` atc --model=yolox_nano.onnx --framework=5 --output=./yolox_nopre_nopost --output_type=FP32 --soc_version=Ascend310 --input_shape="images:1, 3, 416, 416" ``` 若终端输出为: ``` ATC start working now, please wait for a moment. ATC run success, welcome to the next use. W11001: Op [Slice_29] does not hit the high-priority operator information library, which might result in compromised performance. W11001: Op [Slice_9] does not hit the high-priority operator information library, which might result in compromised performance. W11001: Op [Slice_39] does not hit the high-priority operator information library, which might result in compromised performance. W11001: Op [Slice_19] does not hit the high-priority operator information library, which might result in compromised performance. ``` 表示命令执行成功。 ## 4 编译与运行 **步骤1** 在项目根目录执行命令: ``` bash build.sh chmod 640 postprocess/build/libYoloxPostProcess.so cp postprocess/build/libYoloxPostProcess.so ${MX_SDK_HOME}/lib/modelpostprocessors/ ``` **步骤2** 放入待测图片。将一张图片放在路径``python/test_img``下,命名为 test.jpg。 **步骤3** 图片检测。在项目路径``python/Main``下运行命令: ``` python3 nopre_post.py ``` 命令执行成功后在目录``python/test_img``下生成检测结果文件 nopre_post.jpg,查看结果文件验证检测结果。 ## 5 精度测试 **步骤1** 在项目根目录执行命令: ``` bash build.sh cp postprocess/build/libYoloxpostprocess.so ${MX_SDK_HOME}/lib/modelpostprocessors/ ``` **步骤2** 更改``python/Main``路径下的 shell 文件 run.sh 的运行指令为: ``` python nopre_post.py ``` **步骤3** 图片检测。将一张图片放在路径``python/test_img``下,命名为 test.jpg,在该图片上进行检测,**从 ```python/Main/nopre_post.py``` 中找到使用的 pipeline 文件路径,将其中 mxpi_objectpostprocessor0 插件的 postProcessLibPath 属性值中的 ${MX_SDK_HOME} 值改为具体路径值**,然后执行命令: ``` cd python/Main bash run.sh ``` 命令执行成功后在目录``python/test_img``下生成检测结果文件 test_nopre_post.jpg,查看结果文件验证检测结果。 **步骤4** 精度测试。下载COCO VAL 2017数据集和标注文件。 1. 下载COCO VAL 2017[验证数据集](http://images.cocodataset.org/zips/val2017.zip )和[标注文件](http://images.cocodataset.org/annotations/stuff_annotations_trainval2017.zip),并保存在项目目录``python/test/data``下,此文件夹下的组织形式应如下图所示: ``` . ├── annotations │   └── instances_val2017.json └── val2017 ``` 其中:val2017文件夹下应存放有5000张待测图片。 2. 修改``python/models``下的文件 yolox_eval.cfg 的参数 OBJECTNESS_THRESH=0.01 IOU_THRESH=0.65 3. 使用以下指令运行路径``python/test``下的文件 parse_coco.py: ``` python3 parse_coco.py --json_file=data/annotations/instances_val2017.json --img_path=data/val2017 ``` 若运行成功,会在该目录下生成文件夹ground_truth,其中包含每张图像上提取的目标框真实位置与类别的txt文件。 接下来将每张图的预测结果转为txt文件,并保存在同一文件夹下,其步骤如下: 4. 进入``python/Main``路径,运行命令: ``` python3 eval_nopre_post.py ``` 若运行成功,会在``python/test`` 路径下生成 test_nopre_post 文件夹,该目录下包含有每张图像上的检测结果的 txt 文件。 5. 在``python/test``路径下,运行命令: ``` python3 map_calculate.py --npu_txt_path="./test_nopre_post" ``` 若运行成功则得到最终检测精度,结果如下: ![result](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/23/1655970593220319171.png) 注:在pipeline中加图像预处理与不加预处理的验证结果不同的原因为:YOLOX的图像预处理中,Resize方式为按长边缩放,而Mindx SDK默认使用dvpp的图像解码方式,没有按长边缩放的方法,因此本项目将"resizeType"属性设置为 "Resizer_KeepAspectRatio_Fit",这样会导致精度下降。 ## 6 常见问题 ### 5.1 源项目的测试精度为24.3,达不到本项目的精度25.3 源项目的后处理默认使用类间 nms, 而本项目的 nms 调用 MxBase::NmsSort 方法,该方法为类内 nms,若要对齐源项目精度,只需将 源项目代码中的方法 multiclass_nms 的参数 class_agnostic 改为 False 即可。 ### 5.2 未修改 pipeline 文件中的 ${MX_SDK_HOME} 值为具体值 运行demo前需要正确导入环境变量,否则会报错,如下图所示: ![MindXSDKValueError](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/23/1655970561821656350.png) **解决方案:** 检查Mindx SDK安装包的位置,并使用第二章介绍的指令正确导入环境变量。 ### 5.3 后处理插件权限问题 运行检测 demo 和评测时都需要将生成的YOLOX后处理动态链接库的权限修改,否则将会报权限错误,如下图所示: ![permissionerror](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/23/1655970539724819900.png) **解决方案:** 在YOLOX后处理的动态链接库的路径下运行命令: ``` chmod 640 libYoloxPostProcess.so ``` ### 5.4 模型转换时会警告缺slice算子 YOLOX在图像输入到模型前会进行slice操作,而ATC工具缺少这样的算子,因此会报出如图所示的警告: ![warning](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/23/1655970505955986509.png) **解决方案:** 常规的做法是修改slice算子,具体操作可参考[安全帽检测](https://gitee.com/booyan/mindxsdk-referenceapps/tree/master/contrib/HelmetIdentification)的开源项目。 由于在本项目下是否修改算子并不影响检测结果,因此默认不做处理。
  • [问题求助] 【SDC】【二次开发】获取SDK开发代码DEMO
    【功能模块】SDK二次开发【操作步骤&问题现象】1、获得代码DEMO,方便快速开发2、【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [MindX SDK] 【MindX SDK】关于pipeline中skipframe插件和videodecoder插件使用顺序的疑问。
    如下的链接给出了pipeline的示例,我们观察发现skipframe放在videodecoder之后,那是不是说取流回来后每一帧都会进行解码,然后skipframe跳帧取做推理;如果是这样理解的话,是不是把skipframe放在videodecoder前面,先去跳帧再解码,这样的话会不会节省许多的解码计算资源。https://gitee.com/ascend/mindxsdk-referenceapps/blob/master/mxVision/AllObjectsStructuring/pipeline/AllObjectsStructuring.pipeline
  • [MindX SDK] [路面分割参考设计案例分享]
    # MindX SDK -- 路面分割参考设计案例 ## 1 案例概述 ### 1.1 概要描述 [路面分割案例](https://gitee.com/ascend/mindxsdk-referenceapps/tree/master/contrib/RoadSegmentation),本案例主要对含有路面的图片进行语义分割,其主要实现了对输入图片能够正确的标识出路面部分。 ### 1.2 特性及适用场景 本案例可以满足路面的语义分割内容,但同时对输入的图像有以下限制: 1.对于输入的图像是灰度图像时,会影响分割效果。 2.当路面上的障碍物(如车辆)较为密集时,会降低模型的分割效果。 3.当输入图片中的路面有阴影或颜色不一致时,会影响分割效果。 4.当输入图片中不含路面,也会有少量的标识。 5.适用于单张图片的输入。 6.适应于形状规则且与周围环境色差较大的路面图片。 ### 1.3 模型介绍 本案例采用U-net模型,Unet提出的初衷是为了解决医学图像分割的问题,由于效果确实很好后来也被广泛的应用在语义分割的各个方向,比如卫星图像分割,工业瑕疵检测等,下图为U-net模型框架。 ![Unet模型](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/16/1655373144507698477.png) 通过下采样提取目标特征,再通过上采样,最后逐个对其像素点进行分类, ### 1.4 实现流程 基于MindX SDK的路面分割业务流程:待检测图片通过 appsrc 插件输入,然后使用图像解码插件mxpi_imagedecoder对图片进行解码,再通过图像缩放插件mxpi_imageresize将图像缩放至满足检测模型要求的输入图像大小要求,缩放后的图像输入模型推理插件mxpi_tensorinfer得到检测结果,本项目开发的路面分割后处理插件处理推理结果,从中获取掩膜mask,然后与原始图片进行融合,之后通过图像编码插件mxpi_imageencoder将后处理插件的融合后的数据进行编码,最后使用输出插件appsink输出可视化的结果 ![SDK流程](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/16/1655373175506172276.png) 注:红色字体为本项目开发的后处理插件,其他为SDK内置插件 ## 2 软件方案介绍 ### 2.1 技术原理 主要对U-net模型推理出的二分类结果,使用阈值标识出路面的部分,并采用opencv中的图片融合方法将结果与原图进行融合。 ### 2.2 项目方案架构介绍 表1 系统方案各子系统功能描述: | 序号 | 子系统 | 功能描述 | | ---- | ------ | ------------ | | 1 | 图片输入 | Gstreamer原生插件。配合SendData接口与SendDataWithUniqueId接口使用,向Stream中发送数据,appsrc将数据发给下游元件,当且仅当Stream中存在appsrc插件时以上两个接口有效。 | | 2 | 图像解码 | 用于图像解码,只支持JPG/JPEG/BMP格式。说明:JPG/JPEG输入图片格式约束:只支持Huffman编码,码流的subsample为444/422/420/400/440。不支持算术编码。不支持渐进JPEG格式。不支持JPEG2000格式。 | | 3 | 图像缩放 | 对解码后的YUV格式的图像进行指定宽高的缩放,暂时只支持YUV格式的图像。 | | 4 | 模型推理 | 对输入的张量进行推理。 | | 5 | 模型后处理插件 | 将模型推理的结果mask 与原图融合| | 6 | 图像编码 | 用于图片编码。 | | 7 | 图像输出 | Gstreamer原生插件。配合GetResult接口与GetResultWithUniqueId接口使用,从stream中获取数据,当且仅当stream中存在appsink插件时,以上两个接口有效。 | ## 3 开发环境准备 ### 3.1 环境依赖说明 推荐系统为ubuntu 18.04,环境依赖软件和版本如下表: | 软件名称 | 版本 | 说明 | 获取方式 | | ------------------- | ----------- | ----------------------------- | ------------------------------------------------------------ | | MindX SDK | 2.0.4 | mxVision软件包 | [链接](https://gitee.com/link?target=https%3A%2F%2Fwww.hiascend.com%2Fsoftware%2FMindx-sdk) | | ubuntu | 18.04.1 LTS | 操作系统 | Ubuntu官网获取 | | Ascend-CANN-toolkit | 5.0.4 | Ascend-cann-toolkit开发套件包 | [链接](https://gitee.com/link?target=https%3A%2F%2Fwww.hiascend.com%2Fsoftware%2Fcann%2Fcommercial) | ### 3.2 环境搭建 #### 3.2.1 工程创建 ##### 3.2.1.1 导出onnx文件 获取[路面分割文件](https://github.com/tunafatih/Road-Free-Space-Segmentation-Internship-Project),在本地使用pt2onnx.py文件,将pt权重文件转换成onnx文件,或可[点击此处](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/RoadSegmentation/model.zip)下载转换好的onnx文件。 ##### 3.2.1.2 使用Ascend atc工具将onnx模型转换为om模型 在使用[atc工具](https://www.hiascend.com/document/detail/zh/canncommercial/504/inferapplicationdev/atctool)之前**需按第2节环境依赖章节**事先配置好CANN环境,之后将3.1节中导出的onnx文件上传至```model```目录下,在该目录下执行 ``` atc --framework=5 --model=Road.onnx --output=road_segmentation --input_format=NCHW --insert_op_conf=../config/aipp_road_segmentation.config --input_shape="image:1,3,224,224" --log=debug --soc_version=Ascend310 ``` 若出现以下信息,则转换成功 ``` ATC run success ``` #### 3.2.3 开发环境搭建 - 配置MindSDK 环境变量 ``` . ${SDK-path}/set_env.sh ``` - 配置CANN 环境变量 ``` . ${ascend-toolkit-path}/set_env.sh ``` ## 4 编译与运行 示例步骤如下: **步骤1** 修改相应文件 根据所需场景,配置pipeline文件,调整路径参数。 ``` #配置mxpi_tensorinfer插件的模型加载路径: modelPath "mxpi_tensorinfer0": { "props": { "dataSource": "mxpi_imageresize0", "modelPath": "${road_segmentation.om模型路径}" }, "factory": "mxpi_tensorinfer", "next": "appsink0" }, #配置可视化结果输出路径:location "appsink0": { "props": { "blocksize": "4096000", "location":"${输出结果文件名}" }, "factory": "filesink" } ``` **步骤2** 设置环境变量 按**第3.2.3节环境搭建**中设置环境变量 **步骤3** 执行编译的步骤 在样例目录下,执行 ``` bash build.sh ``` **步骤4** 运行及输出结果 在样例目录下,执行 ``` python3.9 main.py test.jpg #测试图片地址 ``` ## 5 常见问题 ### 5.1 图片解码问题 **问题描述:** ![解码失败](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/16/1655373231370242106.png) **解决方案:** 更换图片,详情[imagedecoder插件介绍](https://www.hiascend.com/document/detail/zh/mind-sdk/204/vision/mxvisionug/mxvisionug_0115.html)
  • [MindX SDK] CenterFace动态分辨率模型推理案例分享
    # MindX SDK+CenterFace动态分辨率模型推理 ## 1 介绍 [MindX SDK](https://gitee.com/link?target=https%3A%2F%2Fwww.hiascend.com%2Fsoftware%2Fmindx-sdk) 是华为推出的软件开发套件(SDK),提供极简易用、高性能的API和工具,助力昇腾AI处理器赋能各种应用场景。对于一个训练好的模型,在Mind SDK上仅需在stream流的pipeline配置文件中简单配置几行,便可使用内置的插件实现模型的前处理和后处理,完成常见的推理任务。本文将介绍如何在MindX SDK框架上实现动态分辨率模型的推理。(代码地址:https://gitee.com/ascend/mindxsdk-referenceapps/tree/master/contrib/CenterFace) **动态分辨率:**指模型转化为om格式在MindX SDK上进行推理时,通常模型输入的图片大小一般固定为ATC工具转化时所设定的值。如果所有尺寸的图片都缩放至同一大小,对于尺寸与模型输入差距过大的图片,模型推理的效果难以符合预期。因此在使用ATC工具转化模型时,开启动态分辨率的功能,配置多个档位以适配常见的图片尺寸,模型推理时根据图片大小选用合适的档位。 本案例推理采用[CenterFace](https://github.com/Star-Clouds/CenterFace)(一个轻量化的人脸检测模型,同时实现了人脸检测+关键点检测),考虑到API中已有的后处理插件基类,以及输出结果的特殊性,开发了两个后处理插件,其余均使用框架自带插件。 本文将涵盖以下内容:*模型推理流程*、*动态分辨率模型转换*、*模型后处理开发介绍*。 ## 2 开发工具准备 > MindX SDK模型开发须使用本地IDE工具连接昇腾服务器,使用本教程前,请确保以下环境正确安装。 - 在昇腾机器上安装MindX SDK,MindX SDK软件包安装[参考链接](https://support.huawei.com/enterprise/zh/doc/EDOC1100209684?section=j00h) - Cmake - 本地C++开发环境搭建,以下演示使用[CLion](https://www.jetbrains.com/clion/download/download-thanks.html?platform=windows) - 远程SSH工具,如MobaXterm,xshell,final shell(以下演示使用MobaXterm) ## 3 开发环境配置 请参考官方技术文档:[IDE开发环境搭建](https://gitee.com/ascend/docs-openmind/blob/master/guide/mindx/sdk/tutorials/quick_start/1-2IDE开发环境搭建.md#/ascend/docs-openmind/blob/master/guide/mindx/sdk/tutorials/quick_start/Cmake介绍.md) ## 4 开发流程介绍 在MinX SDK上实现模型推理,通常包含以下几个步骤: - 准备好用于推理的模型。 - 使用ATC工具转换为om模型(转换过程根据模型的要求配置aipp做前处理)。 - 根据业务需求,编排steam流,编写主函数。 - 根据需要开发插件或后处理插件。 ## 5 开发 ### 5.1 准备模型 从CenterFace官方仓下载onnx模型([github下载链接](https://gitee.com/link?target=https%3A%2F%2Fgithub.com%2FStar-Clouds%2FCenterFace%2Fblob%2Fmaster%2Fmodels%2Fonnx%2Fcenterface.onnx)),无法访问github请使用[备用链接](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/CenterFaceWithDynamicResolution/centerface_offical.onnx)。 如果你的模型是其它格式,同样可以通过以下工具转化为MindX SDK使用的模型格式。 ### 5.2 动态分辨率模型转换 转换模型之前需要在昇腾服务器上安装和配置好ATC模型转换工具(模型转换工具相关介绍参考[链接](https://gitee.com/link?target=https%3A%2F%2Fsupport.huaweicloud.com%2Ftg-cannApplicationDev330%2Fatlasatc_16_0005.html))。如果服务器上已经具备ATC工具,但未配置环境变量,可参考如下配置: ```bash export install_path=/usr/local/Ascend/ascend-toolkit/latest export PATH=/usr/local/python3/bin:${install_path}/atc/ccec_compiler/bin:${install_path}/atc/bin:$PATH export PYTHONPATH=${install_path}/atc/python/site-packages:${install_path}/atc/python/site-packages/auto_tune.egg/auto_tune:${install_path}/atc/python/site-packages/schedule_search.egg export LD_LIBRARY_PATH=${install_path}/atc/lib64:$LD_LIBRARY_PATH export ASCEND_OPP_PATH=${install_path}/opp ``` 接着获取模型输入节点的名称,下载Netron,安装后使用Netron打开onnx模型 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654843579757448142.png) 可以看到模型的输入节点名称为:`input.1` 使用SSH工具附带的ftp功能把下载好的onnx模型上传至昇腾服务器,cd进入模型存放的目录,执行如下命令: ```bash atc --model=centerface_offical.onnx --output=centerface_offical --dynamic_image_size="768,1024;800,800;1024,768;864,1120;1120,864;960,1216;1216,960;1056,1312;1312,1056;1152,1408;1408,1152;1248,1504;1504,1248;1344,1600;1600,1344;1440,1696;1696,1440;1536,1792;1792,1536;1632,1888;1888,1632;1728,1984;1984,1728;1824,2080;2080,1824" --soc_version=Ascend310 --input_shape="input.1:1,3,-1,-1" --input_format=NCHW --framework=5 --insert_op_conf=centerface_aipp.cfg ``` 以上命令转成具有多档位的动态分辨率模型,转成单档位可使用如下命令: ```bash atc --model=centerface_offical.onnx --output=centerface_offical --soc_version=Ascend310 --input_shape="input.1:1,3,800,800" --input_format=NCHW --framework=5 --insert_op_conf=centerface_aipp.cfg ``` 命令参数的解释如下: - --model 待转换模型存放的路径 - --output 模型输出路径及输出模型命名 - --soc_version 芯片版本 - --input_shape 模型输入节点名称和tensor形状,当配置动态分辨率属性时,图片宽高应设为-1 - --input_format 输入图片的数据格式 - --dynamic_image_size 动态分辨率属性,配置后模型可接受不同分辨率的输入 - --framework 原模型使用的框架 - --insert_op_conf aipp配置文件 > aipp配置文件为可选,作用在于对模型输入数据进行前处理,是根据模型的输入要求进行具体配置的。 > > 此处因MindX SDK图片解码器仅支持JPG图像,并且解码成YUV420sp,而CenterFace模型的输入格式为RGB888,因此配置了色域转换的相关属性。具体配置文件如下 ```yaml aipp_op{ aipp_mode: static crop: false input_format : YUV420SP_U8 #非动态分辨率请设置具体的宽高 src_image_size_h : 0 src_image_size_w : 0 csc_switch : true rbuv_swap_switch : false matrix_r0c0 : 256 matrix_r0c1 : 0 matrix_r0c2 : 359 matrix_r1c0 : 256 matrix_r1c1 : -88 matrix_r1c2 : -183 matrix_r2c0 : 256 matrix_r2c1 : 454 matrix_r2c2 : 0 input_bias_0 : 0 input_bias_1 : 128 input_bias_2 : 128 mean_chn_0 : 0 mean_chn_1 : 0 mean_chn_2 : 0 min_chn_0 : 0 min_chn_1 : 0 min_chn_2 : 0 var_reci_chn_0: 1.0 var_reci_chn_1: 1.0 var_reci_chn_2: 1.0 } ``` 开启动态分辨率属性后,经过ATC工具转化的模型,已具备接受多个分辨率输入的功能,通过修改pipeline中缩放插件的属性,即可改变模型输入的大小。 ### 5.3 项目创建与pipeline流程编排 #### 新建CLION项目 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654843536158771876.png) #### CmakeLists文件 ```cmake cmake_minimum_required(VERSION 3.10) project(CenterFace) add_compile_options(-fPIC -fstack-protector-all -g -Wl,-z,relro,-z,now,-z -pie -Wall) add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0 -Dgoogle=mindxsdk_private) set(CMAKE_BUILD_TYPE Debug) set(MX_SDK_HOME $ENV{MX_SDK_HOME}) #使用本地IDE运行请配置MX_SDK_HOME的绝对路径 if (NOT DEFINED ENV{MX_SDK_HOME}) string(REGEX REPLACE "(.*)/(.*)/(.*)/(.*)" "\\1" MX_SDK_HOME ${CMAKE_CURRENT_SOURCE_DIR}) message(STATUS "set default MX_SDK_HOME: ${MX_SDK_HOME}") else () message(STATUS "env MX_SDK_HOME: ${MX_SDK_HOME}") endif() set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/") #需要用到的头文件 include_directories( ${MX_SDK_HOME}/include ${MX_SDK_HOME}/opensource/include ${MX_SDK_HOME}/opensource/include/opencv4 ) #链接的动态库 link_directories( ${MX_SDK_HOME}/lib ${MX_SDK_HOME}/opensource/lib ) add_executable(Main main.cpp ) target_link_libraries(Main glog mxbase mxpidatatype plugintoolkit streammanager cpprest mindxsdk_protobuf opencv_world ) ``` #### 主函数编写 ```C++ #include "MxBase/Log/Log.h" #include "MxBase/MemoryHelper/MemoryHelper.h" #include "MxStream/StreamManager/MxStreamManager.h" #include "opencv2/opencv.hpp" #include PostProcessBases/PostProcessDataType.h> #include #include int main(int argc, char *argv[]) { // 读取pipeline文件信息 std::string pipelineConfigPath = "pipeline配置文件路径"; std::string pipelineConfig = ReadPipelineConfig(pipelineConfigPath); if (pipelineConfig == "") { return APP_ERR_COMM_INIT_FAIL; } std::string streamName = "center_face"; // 新建一个流管理MxStreamManager对象并初始化 auto mxStreamManager = std::make_shared(); APP_ERROR ret = mxStreamManager->InitManager(); // 加载pipeline得到的信息,创建一个新的stream业务流 ret = mxStreamManager->CreateMultipleStreams(pipelineConfig); MxStream::MxstDataInput dataBuffer; // 将图片的信息读取到dataBuffer中 ret = readfile(fileName, dataBuffer); // 通过SendData函数传递输入信息到指定的工作元件模块 // streamName是pipeline文件中业务流名称;inPluginId为输入端口编号,对应输入元件的编号 ret = mxStreamManager->SendData(streamName, 0, dataBuffer); delete dataBuffer.dataPtr; // 获取Stream上后处理插件的处理结果 std::vector keyVec = {"mxpi_imagedecoder0", "mxpi_objectpostprocessor0", "mxpi_objectpostprocessor1"}; std::vector output =mxStreamManager->GetProtobuf(streamName, 0, keyVec); // mxpi_imagedecoder0图片解码插件输出信息 auto mxpiVision = std::static_pointer_cast(output[0].messagePtr); // mxpi_objectpostprocessor0 后处理插件1输出信息 auto objectList = std::static_pointer_cast(output[1].messagePtr); // mxpi_objectpostprocessor1 后处理插件2输出信息 auto keypointList = std::static_pointer_cast(output[2].messagePtr); // 把经过后处理之后的推理结果写入到图片中 SaveResult(mxpiVision, objectList, keypointList); mxStreamManager->DestroyAllStreams(); return 0; } ``` > 以上代码仅作主函数的大体逻辑展示 #### pipeline流程编排 模型的推理业务流程如下: 1. 使用StreamManager的api从外部把图片二进制数据送入appsrc插件。 2. 使用图像解码mxpi_imagedecoder对图片进行解码。 3. 通过图像缩放插件mxpi_imageresize将图形缩放至指定的分辨率档位。 4. 缩放后的图形输入模型推理插件mxpi_tensorinfer得到模型输出。 5. 把模型得到的四个输出送入两个后处理插件。 6. 人脸检测插件用来得到人脸检测框,关键点检测插件得到五个关键点。 7. 人脸检测框送入OSD可视化插件编码到原图中。 8. 最后两个后处理插件分支汇聚到appsink结束整个推理流程。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654843473547740298.png) 在pipeline的编排中,对于上图分叉的部分,使用了内置的tee插件接queue插件处理,使得两个后处理插件都能获得模型推理的输出数据。此外OSD可视化插件的输入用到了图像解码挂载的metadata,同样使用了tee插件接queue,图上并未标明。 对应的pipeline文件: ```json { "center_face": { "stream_config": { "deviceId": "0" }, "appsrc0": { "props": { "blocksize": "409600" }, "factory": "appsrc", "next": "mxpi_imagedecoder0" }, "mxpi_imagedecoder0": { "props": { "deviceId": "0" }, "factory": "mxpi_imagedecoder", "next": "mxpi_imageresizer0" }, "mxpi_imageresizer0": { "props": { "dataSource": "mxpi_imagedecoder0", "resizeHeight": "768", "resizeWidth": "1024" }, "factory": "mxpi_imageresize", "next": "tee0" }, "tee0": { "factory": "tee", "next": [ "queue0", "queue1" ] }, "queue0": { "props": { "max-size-buffers": "50" }, "factory": "queue", "next": "mxpi_tensorinfer0" }, "queue1": { "props": { "max-size-buffers": "50" }, "factory": "queue", "next": "mxpi_opencvosd0:0" }, "tee1": { "factory": "tee", "next": [ "queue2", "queue3" ] }, "queue2": { "props": { "max-size-buffers": "50" }, "factory": "queue", "next": "mxpi_objectpostprocessor0" }, "queue3": { "props": { "max-size-buffers": "50" }, "factory": "queue", "next": "mxpi_objectpostprocessor1" }, "mxpi_tensorinfer0": { "props": { "dataSource": "mxpi_imageresizer0", "modelPath": "../model/centerface_offical.om" }, "factory": "mxpi_tensorinfer", "next": "tee1" }, "mxpi_objectpostprocessor0": { "props": { "dataSource": "mxpi_tensorinfer0", "postProcessConfigPath": "../model/centerface.cfg", "postProcessLibPath": "../plugins/lib/plugins/libmxpi_centerfacepostprocessor.so" }, "factory": "mxpi_objectpostprocessor", "next": "mxpi_object2osdinstances0" }, "mxpi_objectpostprocessor1": { "props": { "dataSource": "mxpi_tensorinfer0", "postProcessConfigPath": "../model/centerface.cfg", "postProcessLibPath": "../plugins/lib/plugins/libmxpi_centerfacekeypointpostprocessor.so" }, "factory": "mxpi_keypointpostprocessor", "next": "mxpi_synchronize0:1" }, "mxpi_object2osdinstances0": { "props": { "colorMap": "128, 128, 255|200,200,200|0,128,255|255,128,0", "fontFace": "16", "fontScale": "0.5", "fontThickness": "1", "fontLineType": "16", "rectThickness": "1", "rectLineType": "16" }, "factory": "mxpi_object2osdinstances", "next": "mxpi_opencvosd0:1" }, "mxpi_opencvosd0": { "props": { "dataSourceImage": "mxpi_imagedecoder0", "dataSourceOsd": "mxpi_object2osdinstances0" }, "factory": "mxpi_opencvosd", "next": "mxpi_synchronize0:0" }, "mxpi_synchronize0": { "factory": "mxpi_synchronize", "next": "appsink0" }, "appsink0": { "props": { "blocksize": "4096000" }, "factory": "appsink" } } } ``` > 上述涉及的路径均使用相对路径,相对于main函数文件所在位置。 ### 5.4 后处理插件开发 后处理插件主要包含两个,一个对应人脸检测的功能,另一个对应人脸关键点。后处理插件需要对这模型的四个输出进行处理(包含热图、中心点偏移、目标框宽高和人脸五个关键点的相对目标框大小归一化后的偏移)得到各自的结果,以完成推理。 而后处理插件的开发一般根据自己的任务需求,先在api中寻找是否有已经实现好的基类,继承合适的基类可减少开发的任务量,如果没有便只能继承最基础的基类。通常包含以下几个步骤(下面以人脸检测后处理插件作为演示): #### 编写CMakeLists.txt 编写CMakeLists.txt,主要用于设置后处理动态库的目标文件以及链接相关的第三方库。每一个后处理插件都有一个CMakeLists.txt文件与之对应。编写后处理的CMakeLists.txt文件时,用户只需修改生成的后处理名和生成动态库的目标文件即可,延用原有的配置。人脸检测后处理插件的CMakeList.txt如下: ```cmake cmake_minimum_required(VERSION 3.10) project(mxpi_centerfacepostprocessor) add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0 -Dgoogle=mindxsdk_private) set(PLUGIN_NAME "mxpi_centerfacepostprocessor") set(TARGET_LIBRARY ${PLUGIN_NAME}) # 插件生成的位置 set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../lib/plugins) #在本地IDE上运行时请替换为MX_SDK_HOME的绝对路径,如set(MX_SDK_HOME /home/MindX_SDK/mxvision) set(MX_SDK_HOME $ENV{MX_SDK_HOME}) if (NOT DEFINED ENV{MX_SDK_HOME}) string(REGEX REPLACE "(.*)/(.*)/(.*)/(.*)" "\\1" MX_SDK_HOME ${CMAKE_CURRENT_SOURCE_DIR}) message(STATUS "set default MX_SDK_HOME: ${MX_SDK_HOME}") else () message(STATUS "env MX_SDK_HOME: ${MX_SDK_HOME}") endif() #包含的头文件 include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${MX_SDK_HOME}/include) include_directories(${MX_SDK_HOME}/opensource/include) include_directories(${MX_SDK_HOME}/opensource/include/gstreamer-1.0) include_directories(${MX_SDK_HOME}/opensource/include/glib-2.0) 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("-DPLUGIN_NAME=${PLUGIN_NAME}") add_definitions(-DENABLE_DVPP_INTERFACE) add_library(${TARGET_LIBRARY} SHARED MxCenterfacePostProcessor.cpp MxCenterfacePostProcessor.h) target_link_libraries(${TARGET_LIBRARY} glib-2.0 gstreamer-1.0 gobject-2.0 gstbase-1.0 gmodule-2.0 glog) target_link_libraries(${TARGET_LIBRARY} mxpidatatype plugintoolkit mxbase mindxsdk_protobuf ) #target_link_libraries(${TARGET_LIBRARY} -Wl,-z,relro,-z,now,-z,noexecstack -s) ``` #### 实现人脸框检测的cpp文件 首先,根据任务类型,选择SDK已经支持的后处理基类去派生一个新的子类,这些后处理基类分别为目标检测,分类任务,语义分割,文本生成。这些基类都继承自相同的父类——PostProcessBase。人脸检测框后处理插件继承的类为ObjectPostProcessBase; ```c++ class MxCenterfacePostProcessor : public MxBase::ObjectPostProcessBase ``` **实现基类方法:** inti函数: ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654844885252208174.png) Process函数: ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654844937949430601.png) | 输入参数 | 解释 | | ----------------- | ------------------------------------------------------------ | | tensors | 上游插件的输出,当把后处理插件编排在模型推理插件之后,这里tensors便是模型的输出。 | | objectInfos | MxBase::ObjectInfo是api内置的目标框数据结构,后处理的结果需要存放在里面。 | | resizedImageInfos | 图片size信息,包含原图的宽高和resize之后的宽高,用于后处理逻辑的计算。 | | configParamMap | 从配置文件读取得到的map,在init函数读入。 | 在Process函数中,首先调用父类的CheckAndMoveTensors()接口,对tensors的形状进行校验并搬运内存至Host侧。然后再调用后处理业务函数,这里featLayerData包含单张图片四个输出对应void*指针,数据都是以一维数组形式存储,具体的数据size、type及数据含义需要参考论文原作者的实现。在CenterFace模型中,MxCenterfacePostProcessor后处理插件逻辑包括根据置信度筛选数据、计算出人脸框、使用nms算法对人脸框去重这一系列操作,最终将结果放入objInfo中。 后处理开发完成后,增加一个对外的接口如GetObjectInstance(),以便于让业务流中后处理插件的factory能加载生成的so文件。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654845275412513003.png) > 这里对外接口根据继承的基类有不同名称,通常为Get+基类名称+Instance #### 生成插件 在Clion中点击运行按钮,即可生成对应so文件: ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654843383135724620.png) 生成插件后即可在pipeline配置文件中使用,如下: ```json "mxpi_objectpostprocessor1": { "props": { "dataSource": "mxpi_tensorinfer0", "postProcessConfigPath": "../model/centerface.cfg", "postProcessLibPath": "../plugins/lib/plugins/libmxpi_centerfacekeypointpostprocessor.so" }, "factory": "mxpi_keypointpostprocessor", "next": "XXXX"} ``` factory为后处理插件基类对应插件的名字,后处理插件实际也是用的内置的插件,开发后处理插件相当于在插件的基础上编写,仅需关注业务的具体逻辑代码,如databuff的传递等其他操作由插件完成。 如果不知道factory该填什么,可以在MX_SDK_HOME/lib/plugins下查找。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654843337671691251.png) ## 6 运行过程展示 ### 6.1 本地IDE运行 第一步:配置FaceDetectPostProcessor、KeyPointPostProcessor、C++中CMakeLists文件的SDK路径, ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654843287648131732.png) 第二步:设置cmake编译的环境变量,编译插件。 在设置>构建、执行、部署>cmake界面,找到环境,配置如下: ```bash LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64:/usr/local/Ascend/driver/lib64/; ``` ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654843212875646606.png) 加载FaceDetectPostProcessor中的CMakeLists文件,第一次加载CmakeLists文件时,选择Load Cmake Project,之后重新加载选择Reload Cmake Project。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654843151269379700.png) 加载CmakeLists文件之后,首先在①号位置选择对应的插件,这里选择的是FaceDetectPostProcessor插件,点击②编译 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654843096561305478.png) 点击之后,程序运行,运行完成会显示Finished,得到一个cmake-build-debug文件夹,并且远程会有编译生成的文件夹。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654843018575639101.png) 按以上方法将另一个插件KeyPointPostProcessor中CMakeLists文件进行编译,生成的插件都会存放在plugins目录下。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654842947888770306.png) 第三步:编译、运行main文件 接着加载main.cpp对应的CmakeLists,加载成功会自动生成Main的运行配置,准备图片test.jpg放置在C++目录下,编辑Main运行配置,添加程序实参,并配置环境变量,点击确定。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654842914614432881.png) ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654842871463441960.png) 环境变量如下,其中的MX_SDK_HOME需要替换为昇腾服务器上的绝对路径。 ```bash MX_SDK_HOME=${SDK安装路径} LD_LIBRARY_PATH=${MX_SDK_HOME}/lib:${MX_SDK_HOME}/opensource/lib:${MX_SDK_HOME}/opensource/lib64:/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64:/usr/local/Ascend/driver/lib64/ GST_PLUGIN_SCANNER=${MX_SDK_HOME}/opensource/libexec/gstreamer-1.0/gst-plugin-scanner GST_PLUGIN_PATH=${MX_SDK_HOME}/opensource/lib/gstreamer-1.0:${MX_SDK_HOME}/lib/plugins ``` 然后点击运行。 成功运行后,可在远程的C++/result文件夹中查看结果。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654842804364324769.png) ### 6.2 远程命令行运行 相对于本地运行,远程运行方式会更加简洁方便,具体参考以下操作 第一步:进入到远程文件夹 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654842773435869432.png) 第二步:输入命令: ```bash bash build.sh ``` 此时它会自动将三个CMakeLists全部编译。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654842685849257801.png) 第三步:进入C++文件夹,输入命令运行run.sh文件,假如测试图片在run.sh同级目录,名字为test.jpg,测试命令如下: ```bash cd C++ bash run.sh test.jpg #这里相对路径是相对C++/Main可执行文件的。 #或者准备图片放置在文件夹下,以下命令会依次对文件夹下的图片进行检测。 bash run.sh images ``` ![1653201293644](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654842550524626553.png) 第四步:在result文件中查看运行结果,刷新可以看到是否是刚刚运行生成的结果。 ![1653201442455](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654842482875232996.png) ## 7 常见问题 - 报错:$'\r': command not found![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654842427382418968.png) 解决方案:原因是windows和linux换行符不一致,在CLion右下角将CRLF改成LF,然后上传到远程服务器。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654842131426441396.png)
  • [问题求助] 【IOTDA产品】【Python SDK功能】样例代码运行失败
    【功能模块】https://support.huaweicloud.com/sdkreference-iothub/iot_10_10003.html【操作步骤&问题现象】1、安装SDK2、运行样例代码【截图信息】如下【日志信息】(可选,上传日志内容或者附件)"C:\Program Files\Python38\python.exe" D:/openlab-chs/IOT应用模拟-MQTT-python/main.pyTraceback (most recent call last):  File "D:/openlab-chs/IOT应用模拟-MQTT-python/main.py", line 54, in <module>    from huaweicloudsdkiotda.v5.auth.iotda_credentials import IoTDACredentials  File "C:\Program Files\Python38\lib\site-packages\huaweicloudsdkiotda\v5\auth\iotda_credentials.py", line 5, in <module>    from huaweicloudsdkcore.auth.iam_service import get_keystone_list_projects_request, keystone_list_projects, \ModuleNotFoundError: No module named 'huaweicloudsdkcore.auth.iam_service'
  • [MindX SDK] 【Atlas500产品】【MindX SDK功能】多输入端口自定义模块实现,无法获得输入数据
    【功能模块】自定义功能模块,可以接收分类网络、目标检测网络的输入,根据Data_Source_调用mxpiMetadataManger.GetMetadata(Data_source_)获取的metadata为空【操作步骤&问题现象】1、定义输入端口如下2、自定义模块中实现如下:【截图信息】编译运行后出现问题:问题出现在实现过程中:,根据Data_Source_调用mxpiMetadataManger.GetMetadata(Data_source_)获取的metadata为空,既:pipline构建如下【日志信息】(可选,上传日志内容或者附件)
  • [MindX SDK] SDK OsdSample运行报错
    样例下载链接:https://gitee.com/ascend/mindxsdk-referenceapps/tree/master/tuto问题截图:
  • [问题求助] 【Atlas500产品】【Mindx SDK-2.02功能】是否可以提供个样例,用于自定义功能插件中设置多个输入端口,
    【功能模块】功能:Mindx SDK-2.02,需要自定义包含多个输入端口的功能插件,以完成对上游两个输出结果的组合,但是使用使用手册中没用详细的构建方法,使用可以提供一个多输入端口插件的样例
  • [问题求助] MindX SDK中业务流中插件的修改和创建问题
    【功能模块】MindX SDK中业务流中插件的修改和创建问题【操作步骤&问题现象】1、《人工智能程序设计》课程方案https://education.huaweicloud.com/courses/course-v1:HuaweiX+CBUCNXA030+Self-paced/courseware/72548e98ce8649d793a5f3f5e225b948/25c6f8df69b44f34b2797e76baa49c6c/2、实验02-1, 目标检测(使用MindX SDK开发目标检测应用-yolov3)。在pipline文件中,有许多插件模块,但是这些模块的源代码在哪里?如何修改、创建这些模块?模块和模块具有相关性,参数设置有注意事项?希望能够提供一些提料。【截图信息】【日志信息】(可选,上传日志内容或者附件)
总条数:685 到第
上滑加载中