首页 > 其他分享 >【SDK案例系列 08】基于 MindX SDK + Pytorch YoLoV5的目标检测

【SDK案例系列 08】基于 MindX SDK + Pytorch YoLoV5的目标检测

时间:2023-01-06 18:46:34浏览次数:64  
标签:yolov5 MindX -- onnx 08 sh yolov5s SDK

源码下载:

https://gitee.com/ai_samples/atlas_mindxsdk_samples/blob/master/contrib/cv/object_detection/image_yolov5

快速运行攻略(MindX SDK环境已经部署完毕情况下):

1、获取模型文件

(1)yolov5s_sim_t.onnx文件

https://gitee.com/ai_samples/pytorch_models/tree/master/cv/object_detection/yolov5

存放到 image_yolov5/data/models/yolov5 目录下

2、模型文件转换

(1)image_yolov5/data/models/yolov5目录下执行模型转换,根据芯片类型,执行atc_310.sh 或 atc_310P3.sh

bash atc_310.sh
bash atc_310P3.sh

3、修改run_cpp.sh & run_python.sh中MX_SDK_HOME为MindX SDK安装目录

export MX_SDK_HOME=/usr/local/sdk_home/mxVision

4、执行run_cpp.sh 或者 run_python.sh

bash run_cpp.sh
bash run_python.sh

一、安装昇腾驱动

先安装昇腾驱动,昇腾驱动请参考各个产品安装手册,安装完成后npu-smi info 显示安装成功

[root@localhost ~]#
[root@localhost ~]# npu-smi info
+-------------------------------------------------------------------------------------------------+
| npu-smi 22.0.2                   Version: 22.0.2                                                |
+------------------+--------------+---------------------------------------------------------------+
| NPU    Name      | Health       | Power(W)             Temp(C)           Hugepages-Usage(page)  |
| Chip   Device    | Bus-Id       | AICore(%)            Memory-Usage(MB)                         |
+==================+==============+===============================================================+
| 1      310       | OK           | 12.8                 45                0   / 0                |
| 0      0         | 0000:05:00.0 | 0                    2621  / 8192                             |
+==================+==============+===============================================================+

二、安装MindX SDK > mxVision

(1)MindX SDK需要通过官网获取。

(2)mxVision说明手册:

https://www.hiascend.com/document/detail/zh/mind-sdk/30rc3/quickstart/visionquickstart/visionquickstart_0000.html

(3)安装MindX SDK

./Ascend-mindxsdk-mxvision_3.0.RC2_linux-aarch64.run --install --install-path=/usr/local/sdk_home

--install-path为指定安装的路径

(4)安装成功后会提示如下信息

Installing collected packages:mindx
Successfully installed mindx-3.0.RC2

(5)安装成功后在对应目录下查看,能看到mxVision

[root@localhost sdk_home]#
[root@localhost sdk_home]# pwd
/usr/local/sdk_home
[root@localhost sdk_home]# ls
mxVision mxVision-3.0.RC2
[root@localhost sdk_home]#
[root@localhost sdk_home]#

(6)MindX SDK使用中需要用到OSD功能,安装后需要执行以下命令,生成om文件

bash /usr/local/sdk_home/mxVision/operators/opencvosd/generate_osd_om.sh

执行成功后,显示如下效果

[root@localhost ~]# bash /usr/local/sdk_home/mxVision/operators/opencvosd/generate_osd_om.sh
ASCEND_HOME is set to /usr/local/Ascend by user
Set ASCEND_VERSION to the default value:ascend-toolkit/latest
ATC start working now,please wait for a moment.
ATC run success, welcome to the next use.

The model has been successfully converted to om,please get it under /usr/local/sdk_home/mxVision/operators/opencvosd.
[root@localhost ~]# 

(9)安装完MindX SDK后,需要配置环境变量

.bashrc文件添加以下环境变量

# 安装mxVision时配置
. /usr/local/sdk_home/mxVision/set_env.sh

用户也可以通过修改~/.bashrc文件方式设置永久环境变量,操作如下:

a) 以运行用户在任意目录下执行vi ~/.bashrc命令,打开.bashrc文件,在文件最后一行后面添加上述内容。
b) 执行:wq!命令保存文件并退出。
c) 执行source ~/.bashrc命令使其立即生效。

三、ATC模型转换

样例模型快速下载地址:

https://gitee.com/ai_samples/pytorch_models/tree/master/cv/object_detection/yolov5

1、yolov5-2.0获取权重文件。(yolov5-5.0 跳过此步)

(1)pt文件转换为onnx文件

python3.7 pytorch 1.5 建议搭配yolov5 2.0

下载ultralytics-2.0(软件包名为yolov5-2.0.tar.gz)。

wget https://github.com/ultralytics/yolov5/archive/v2.0.tar.gz

运行如下命令,解压软件包并修改转换脚本,目前ATC(om文件转换工具)支持的onnx算子版本为opset11。

tar -xzf yolov5-2.0.tar.gz
vi yolov5-2.0/models/export.py
:set number
i
# 修改第48行opset_version为11
:wq!

在yolov5-2.0目录运行如下命令:

python models/export.py --weights ./yolov5s.pt --img 640 --batch 1

运行结果:生成yolov5s.onnx文件。

(2)onnx文件简化及算子处理

首先对导出的onnx图使用onnx-simplifer工具进行简化。在yolov5-2.0目录运行如下命令:

python -m onnxsim --skip-optimization yolov5s.onnx yolov5s_sim.onnx

运行结果:生成yolov5s_sim.onnx文件。

然后利用附件脚本image_yolov5/data/models/yolov5/modify_yolov5s_2.0_slice.py修改模型Slice算子。将附件脚本上传yolov5-2.0目录,运行如下命令:

python modify_yolov5s_2.0_slice.py yolov5s_sim.onnx

运行结果:生成yolov5s_sim_t.onnx文件。

2、yolov5-5.0获取权重文件。(yolov5-2.0 跳过此步)

(1)pt文件转换为onnx文件

python3.8 pytorch 1.7 建议搭配yolov5 5.0

下载ultralytics-5.0(软件包名为yolov5-5.0.tar.gz)。

wget https://github.com/ultralytics/yolov5/archive/v5.0.tar.gz

运行如下命令,解压软件包并修改转换脚本,目前ATC(om文件转换工具)支持的onnx算子版本为opset11。

tar -xzf yolov5-5.0.tar.gz
vi yolov5-5.0/models/export.py
:set number
i
# 修改第77行opset_version为11
:wq!

在yolov5-5.0目录运行如下命令:

python models/export.py --weights ./yolov5s.pt --img 640 --batch 1

运行结果:生成yolov5s.onnx文件。

(2)onnx文件简化及算子处理

首先对导出的onnx图使用onnx-simplifer工具进行简化。在yolov5-5.0目录运行如下命令:

python -m onnxsim --skip-optimization yolov5s.onnx yolov5s_sim.onnx

运行结果:生成yolov5s_sim.onnx文件。

然后利用附件脚本image_yolov5/data/models/yolov5/modify_yolov5s_5.0_slice.py修改模型Slice算子。将附件脚本上传yolov5-5.0目录,运行如下命令:

python modify_yolov5s_5.0_slice.py yolov5s_sim.onnx

运行结果:生成yolov5s_sim_t.onnx文件。

3、onnx文件转换为om文件

(1)把生成的yolov5s_sim_t.onnx放在image_yolov5/data/models/yolov5目录下

[root@localhost yolov5]#
[root@localhost yolov5]# ls
aipp_yolov5.cfg  atc_310.sh  atc_310P3.sh  coco2014.names  modify_yolov5s_2.0_slice.py  modify_yolov5s_5.0_slice.py  yolov5.cfg  yolov5.pt  yolov5s_sim_t.onnx
[root@localhost yolov5]# 

(2)执行模型转换命令

Ascend310芯片模型转换命令如下:

atc \
    --model=./yolov5s_sim_t.onnx \
    --framework=5 \
    --output=./yolov5s \
    --input_format=NCHW \
    --input_shape="images:1,3,640,640"  \
    --enable_small_channel=1 \
    --insert_op_conf=./aipp_yolov5.cfg \
    --soc_version=Ascend310 \
    --log=info

Ascend310P3芯片模型转换命令如下:

atc \
    --model=./yolov5s_sim_t.onnx \
    --framework=5 \
    --output=./yolov5s \
    --input_format=NCHW \
    --input_shape="images:1,3,640,640"  \
    --enable_small_channel=1 \
    --insert_op_conf=./aipp_yolov5.cfg \
    --soc_version=Ascend310P3 \
    --log=info

参数说明:

--model:待转换的ONNX模型。

--framework:5代表ONNX模型。

--output:输出的om模型。

--input_format:输入数据的格式。

--input_shape:输入数据的shape。

--insert_op_conf=./aipp_yolov5.cfg:AIPP插入节点,通过config文件配置算子信息,功能包括图片色域转换、裁剪、归一化,主要用于处理原图输入数据,常与DVPP配合使用,详见下文数据预处理。

详细ATC命令转换学习请参考:

https://support.huawei.com/enterprise/zh/doc/EDOC1100234054?idPath=23710424|251366513|22892968|251168373

3、模型转换后,会在目录下生成yolov5s.om

[root@localhost yolov5]#
[root@localhost yolov5]# ls
aipp_yolov5.cfg  atc_310.sh  atc_310P3.sh  coco2014.names  modify_yolov5s_2.0_slice.py  modify_yolov5s_5.0_slice.py  yolov5.cfg  yolov5.om  yolov5.pt  yolov5s_sim_t.onnx
[root@localhost yolov5]# 

四、使用image_yolov5

1、修改run_cpp.sh & run_python.sh中MX_SDK_HOME为MindX SDK安装目录

export MX_SDK_HOME=/usr/local/sdk_home/mxVision

2、执行run_cpp.sh 或者 run_python.sh

bash run_cpp.sh
bash run_python.sh

3、目标检测结果与test.jpg一致

目标检测结果:
Results:{"MxpiObject":[{"classVec":[{"classId":16,"className":"dog","confidence":0.672381699,"headerVec":[]}],"x0":73.486389200000005,"x1":939.720642,"y0":132.92338599999999,"y1":603.35412599999995}]}

五、image_yolov5详解

1、技术流程图

在这里插入图片描述

视频解码:调用DVPP解码能力,转换为 YUV 格式图像数据。

图像缩放:调用DVPP,将图像缩放到一定尺寸大小。

目标检测:YoLoV5模型针对图像进行目标检测。

模型后处理:针对推理结果进行后处理文字转换。

数据序列化:将stream结果组装成json字符串输出。

2、pipeline详解

{
  "classification": {
    "stream_config": {  ##设置业务流在哪个芯片上处理
      "deviceId": "0"
    },
    "mxpi_imagedecoder0": {  ##图像解码(纯硬件)
      "factory": "mxpi_imagedecoder",
      "next": "mxpi_imageresize0"
    },
    "mxpi_imageresize0": {  ##图像缩放(纯硬件)
      "props": {
        "parentName": "mxpi_imagedecoder0",
        "resizeHeight": "640",
        "resizeWidth": "640",
        "resizeType": "Resizer_KeepAspectRatio_Fit"
      },
      "factory": "mxpi_imageresize",
      "next": "mxpi_modelinfer0"
    },
    "mxpi_modelinfer0": {  ##模型推理
      "props": {
        "parentName": "mxpi_imageresize0",
        "modelPath": "data/models/yolov5/yolov5s.om",  ##模型路径
        "postProcessConfigPath": "data/models/yolov5/yolov5.cfg",
        "labelPath": "data/models/yolov5/coco2014.names",
        "postProcessLibPath": "libMpYOLOv5PostProcessor.so"
      },
      "factory": "mxpi_modelinfer",
      "next": "mxpi_dataserialize0"
    },
    "mxpi_dataserialize0": {  ##数据序列化
      "props": {
        "outputDataKeys": "mxpi_modelinfer0"
      },
      "factory": "mxpi_dataserialize",
      "next": "appsink0"
    },
    "appsrc0": {
      "props": {
        "blocksize": "409600"
      },
      "factory": "appsrc",
      "next": "mxpi_imagedecoder0"
    },
    "appsink0": {  ##输出推理结果
      "props": {
        "blocksize": "4096000"
      },
      "factory": "appsink"
    }
  }
}

3、C++源码详解

int main(int argc, char* argv[])
{
    // 读取pipeline配置文件
    std::string pipelineConfigPath = "data/pipeline/Sample.pipeline";
    std::string pipelineConfig = ReadPipelineConfig(pipelineConfigPath);
    if (pipelineConfig == "") {
        LogError << "Read pipeline failed.";
        return APP_ERR_COMM_INIT_FAIL;
    }
    // 初始化 Stream manager 资源
    MxStream::MxStreamManager mxStreamManager;
    APP_ERROR ret = mxStreamManager.InitManager();
    if (ret != APP_ERR_OK) {
        LogError << GetError(ret) << "Failed to init Stream manager.";
        return ret;
    }
    // 根据指定的pipeline配置创建Stream
    ret = mxStreamManager.CreateMultipleStreams(pipelineConfig);
    if (ret != APP_ERR_OK) {
        LogError << GetError(ret) << "Failed to create Stream.";
        return ret;
    }
    // 读取测试图片
    MxStream::MxstDataInput dataBuffer;
    ret = ReadFile("data/test.jpg", dataBuffer);
    if (ret != APP_ERR_OK) {
        LogError << GetError(ret) << "Failed to read image file.";
        return ret;
    }
    std::string streamName = "classification";
    int inPluginId = 0;
    // 发送测试图片到Stream进行推理
    ret = mxStreamManager.SendData(streamName, inPluginId, dataBuffer);
    if (ret != APP_ERR_OK) {
        LogError << GetError(ret) << "Failed to send data to stream.";
        delete dataBuffer.dataPtr;
        dataBuffer.dataPtr = nullptr;
        return ret;
    }
    // 获取推理结果
    MxStream::MxstDataOutput* output = mxStreamManager.GetResult(streamName, inPluginId);
    if (output == nullptr) {
        LogError << "Failed to get pipeline output.";
        delete dataBuffer.dataPtr;
        dataBuffer.dataPtr = nullptr;
        return ret;
    }
    // 打印推理结果
    std::string result = std::string((char *)output->dataPtr, output->dataSize);
    LogInfo << "Results:" << result;

    // 销毁Stream
    mxStreamManager.DestroyAllStreams();
    delete dataBuffer.dataPtr;
    dataBuffer.dataPtr = nullptr;

    delete output;
    return 0;
}

4、Python源码详解

if __name__ == '__main__':
    # 初始化 Stream manager 资源
    streamManagerApi = StreamManagerApi()
    ret = streamManagerApi.InitManager()
    if ret != 0:
        print("Failed to init Stream manager, ret=%s" % str(ret))
        exit()

    # 根据指定的pipeline配置创建Stream
    with open("data/pipeline/Sample.pipeline", 'rb') as f:
        pipelineStr = f.read()
    ret = streamManagerApi.CreateMultipleStreams(pipelineStr)
    if ret != 0:
        print("Failed to create Stream, ret=%s" % str(ret))
        exit()

    # 读取测试图片
    dataInput = MxDataInput()
    with open("data/test.jpg", 'rb') as f:
        dataInput.data = f.read()

    # 发送测试图片到Stream进行推理
    streamName = b'classification'
    inPluginId = 0
    uniqueId = streamManagerApi.SendDataWithUniqueId(streamName, inPluginId, dataInput)
    if uniqueId < 0:
        print("Failed to send data to stream.")
        exit()

    # 获取推理结果
    inferResult = streamManagerApi.GetResultWithUniqueId(streamName, uniqueId, 3000)
    if inferResult.errorCode != 0:
        print("GetResultWithUniqueId error. errorCode=%d, errorMsg=%s" % (
            inferResult.errorCode, inferResult.data.decode()))
        exit()

    # 打印推理结果
    print(inferResult.data.decode())

    # 销毁Stream
    streamManagerApi.DestroyAllStreams()

标签:yolov5,MindX,--,onnx,08,sh,yolov5s,SDK
From: https://www.cnblogs.com/hiascend/p/17031338.html

相关文章

  • S2-008
    漏洞名称S2-008(CVE-2012-0392)远程代码执行漏洞利用条件Struts2.0.0-Struts2.3.17漏洞原理S2-008涉及多个漏洞,Cookie拦截器错误配置可造成OGNL表达式执行,但......
  • EL1008E: Property or field 'config' cannot be found on object of type 'org.sprin
    EL1008E:Propertyorfield'config'cannotbefoundonobjectoftype'org.springframework.beans.factory.config.BeanExpressionContext' 1、报错信息将Sprin......
  • 每日食词—day086
    submissionsn.意见书、陈词、提交、报送、子任务prohibitv.禁止、不准、防止modificationn.修改、修饰、修正、更改deletionn.删除、删减、删去gridn......
  • 如何做好美颜sdk与直播平台的适配?
    美颜sdk作为目前社交视频拍摄平台用户的刚需,在近几年可谓是名声大噪,无论是强大的美颜功能还是多元化的趣味拍摄方案都让用户们“爱不释手”,平台自然也是看中了这一点,纷纷为......
  • 408笔记--树基础
    树的定义:树是n个节点(n≥0)的有限集,n=0称为空树。在任意一个非空树中,有且只有一个根节点,其余节点可以分为m个互不相交的有限集,并且每一个集合本身又是一棵树称为根的子树。......
  • 每日食词—day084
    automotiveadj.自动的、自动车benchmarkn. v.基准、评效、评估、衡量FAQabbr.常见问题(FrequentlyAskedQuestions)、常见问题解答、疑问解答、常见问题与解答......
  • 补充完毕,最后一题简单,108根据前面的自己能够勉强写出
    669.修剪二叉搜索树publicTreeNodetrimBST(TreeNoderoot,intlow,inthigh){if(root==null){returnnull;}if(root......
  • 每日食词—day083
    dependenciesn.依赖性、依赖、依赖关系、相关性、相依性materialn. adj.材料、材质、物料、资料backupn. adj.备份variantn. adj.变量、变体、变体型c......
  • upload.html:143 GET http://localhost:8080/user_image/85F250A6-E07D-4FCB-8092-D4A
    publicclassLoginInterceptorConfigureimplementsWebMvcConfigurer{@OverridepublicvoidaddResourceHandlers(ResourceHandlerRegistryregistry){......
  • 1008.Django模型基础03
    一、关系表的数据操作关系表中的数据操作查看数据库中的表结构   一对多表关系数据的添加:1.第一种方式就是跟之前一样,用传参的方法添加,需要注意的是外键的值必......