下载
中文
注册

API接口开发方式(C++)

样例介绍

本样例以Atlas 200I/500 A2 推理产品,使用mxVision C++接口开发图像目标检测应用进行演示,图像目标检测模型推理流程图如图1所示。

图1 目标检测模型推理流程图

样例取用TensorFlow框架YoloV3模型。模型的输入、输出数据格式参见如下。

  • 输入数据:分辨率为416 * 416的RGB格式图片。
  • 输出数据:识别目标的坐标、类别及其对应的置信度。

准备工作

  1. 请先完成mxVision安装部署后,再进行快速入门样例。
    表1 环境要求软件依赖

    软件依赖名称

    推荐版本

    获取链接

    系统依赖

    -

    Ubuntu系统CentOS系统

    CANN开发套件包

    7.0.0

    CANN获取链接

    npu-driver驱动包

    23.0.0

    请参见版本配套表,根据实际硬件设备型号选择配套的驱动、固件。

    请参见各硬件产品中驱动和固件安装升级指南获取对应的指导。

    npu-firmware固件包

    23.0.0

  2. 获取样例代码。本样例代码仅支持在Atlas 200I/500 A2 推理产品上运行。

    请访问获取链接,获取样例代码压缩包。

  3. 以普通用户登录已安装mxVision的开发环境并将样例代码压缩包上传。
  4. 解压样例代码压缩包,进入解压后的目录,命令参考如下。
    unzip YoloV3Infer.zip
    cd YoloV3Infer

    样例代码目录结构参考如下。

    YoloV3Infer
    ├── model
    │ ├── yolov3.names                        # yolov3后处理标签文件
    │ ├── yolov3_tf_bs1_fp16.cfg            # yolov3后处理配置文件
    │ ├── aipp_yolov3_416_416.aippconfig  # yolov3 om模型aipp转换文件
    │ ├── yolov3_tf_bs1_fp16.om             # yolov3 om模型,需要自行下载pb文件转换
    ├── main.cpp                  # 主程序文件
    ├── CMakeLists.txt           
    ├── run.sh                     # 运行程序的脚本
    ├── README.md                 
    ├── test.jpg                  # 测试用图片,需要用户自行准备
  5. 准备用于推理的模型。

    用户可参考模型转换功能(ATC)转换om模型进行推理,具体转换方法请参考4解压目录中“README.md”的“模型获取”章节,该参考样例使用到的om模型为使用了AIPP预处理配置的模型。

  6. 准备用于推理的图片数据。

    用户需使用自行获取的图片进行测试(请将获取的图片名称更名为“test.jpg”),以下图片为展示用途。

    图2 test.jpg

代码解析

在该样例中,关键步骤与代码参考如下,不可以直接拷贝编译运行,完整样例代码请参考样例文件。

  1. 初始化资源,配置模型相关变量,如图片路径、模型路径、配置文件路径、标签路径等。
    // 初始化资源和变量
    const uint32_t YOLOV3_RESIZE = 416; // 图片缩放大小
    
    std::string yolov3ModelPath = "./model/yolov3_tf_bs1_fp16.om"; // 模型路径
    std::string yolov3ConfigPath = "./model/yolov3_tf_bs1_fp16.cfg"; // 后处理配置文件路径
    std::string yolov3LabelPath = "./model/yolov3.names"; // 后处理标签文件路径
    
    v2Param.deviceId = 0; // 配置
    v2Param.labelPath = yolov3LabelPath;
    v2Param.configPath = yolov3ConfigPath;
    v2Param.modelPath = yolov3ModelPath;
    APP_ERROR ret = MxInit();
  2. 对输入数据进行前处理。执行MxInit初始化资源,同时初始化ImageProcessor对象后,解码图片,得到Image对象,再进行相应的图片缩放,之后将其转化为推理所需要的数据格式(Tensor类型)。
    // 前处理 
    //构建图像处理类
    MxBase::ImageProcessor imageProcessor(deviceId); 
    
    //构建解码后的图像类
    MxBase::Image decodedImage;
    //根据图像路径进行解码
    ret = imageProcessor.Decode(imgPath, decodedImage, ImageFormat::YUV_SP_420);
    
    MxBase::Image resizeImage;
    //缩放尺寸
    Size resizeConfig(YOLOV3_RESIZE, YOLOV3_RESIZE);
    //执行缩放
    ret = imageProcessor.Resize(decodedImage, resizeConfig, resizeImage, Interpolation::HUAWEI_HIGH_ORDER_FILTER);
    
    std::string path = "./resized_yolov3_416.jpg";
    //编码缩放后的图片,并输出到指定路径
    ret = imageProcessor.Encode(resizeImage, path);
    
    //转换Image对象为Tensor
    Tensor tensorImg = resizeImage.ConvertToTensor();
    //设置Tensor所在设备编号
    ret = tensorImg.ToDevice(deviceId);
  3. 构建模型类后,输入前处理构建的Tensor对象,执行Infer接口,之后得到模型输出结果yoloV3Outputs。
    // 模型推理 
    // 构建模型类
    MxBase::Model yoloV3(modelPath, deviceId);
    
    //构造Infer接口入参Batch Tensor
    std::vector<Tensor> yoloV3Inputs = {tensorImg};
    //执行模型推理
    std::vector<Tensor> yoloV3Outputs = yoloV3.Infer(yoloV3Inputs);
  4. 对模型输出进行后处理。利用mxVision提供的后处理插件(也可自行开发),可得到目标检测框及其目标类别,并通过opencv将其在原图上呈现。
    // 后处理 
    //后处理原图信息
    ImageInfo imageInfo;
    imageInfo.oriImagePath = argv[1];
    imageInfo.oriImage = decodedImage;
    //执行后处理函数
    ret = YoloV3PostProcess(imageInfo, v2Param.configPath, v2Param.labelPath, yoloV3Outputs);
    
    //YoloV3PostProcess后处理函数主要逻辑
    //创建后处理配置信息
    std::map<std::string, std::string> postConfig;
    postConfig.insert(pair<std::string, std::string>("postProcessConfigPath", yoloV3ConfigPath));
    postConfig.insert(pair<std::string, std::string>("labelPath", yoloV3LablePath));
    
    //初始化后处理类
    Yolov3PostProcess yolov3PostProcess;
    APP_ERROR ret = yolov3PostProcess.Init(postConfig);
    
    //后处理
    vector<TensorBase> tensors;
    //依据模型推理结果构建目标检测信息,该信息为mxVision已实现后处理函数必备数据
    //若后处理函数为用户自定义,需按照实际情况构造
    vector<vector<ObjectInfo>> objectInfos;
    auto shape = yoloV3Outputs[0].GetShape();
    MxBase::ResizedImageInfo imgInfo;
    //缩放前图像宽
    imgInfo.widthOriginal = imageInfo.oriImage.GetOriginalSize().width;
    //缩放前图像高
    imgInfo.heightOriginal = imageInfo.oriImage.GetOriginalSize().height;
    //缩放后图像宽
    imgInfo.widthResize = YOLOV3_RESIZE;
    //缩放后图像高
    imgInfo.heightResize = YOLOV3_RESIZE;
    //图像缩放方式
    imgInfo.resizeType = MxBase::RESIZER_STRETCHING;
    std::vector<MxBase::ResizedImageInfo> imageInfoVec = {};
    imageInfoVec.push_back(imgInfo);
    //执行后处理
    ret = yolov3PostProcess.Process(tensors, objectInfos, imageInfoVec);
    //利用opencv实现目标检测框可视化
    cv::putText(imgBgr, objectInfos[i][j].className, cv::Point(x0 + 10, y0 + 10), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 255,0), 4, 8);
       cv::rectangle(imgBgr, cv::Rect(x0, y0, x1 - x0, y1 - y0), cv::Scalar(0, 255, 0), 4);
    //模型后处理去初始化
    ret = yolov3PostProcess.DeInit();
  5. 去初始化,释放资源。
    // 去初始化 
    ret = MxBase::MxDeInit();
    if (ret != APP_ERR_OK) {
        LogError << "MxDeInit failed, ret=" << ret << ".";
        return ret;
    }

运行推理

  1. 配置环境变量(以CANN的默认安装路径“/usr/local/Ascend/ascend-toolkit”和mxVision的安装路径/usr/local/Ascend/mxVision-{version}为例)。
    source /usr/local/Ascend/ascend-toolkit/set_env.sh
    source /usr/local/Ascend/mxVision-{version}/set_env.sh
  2. 运行推理(运行该脚本前,需根据mxVision安装路径修改CMakeLists.txt文件中的MX_SDK_HOME变量)。
    bash run.sh

    如返回如下信息,则表示运行成功。

    yoloV3Outputs len=3
    ******YoloV3PostProcess******
    Size of objectInfos is 1
    objectInfo-0 ,Size:1
    
    *****objectInfo-0:0
    x0 is 306.2
    y0 is 21.9771
    x1 is 708.318
    y1 is 481.023
    confidence is 0.934635
    classId is 16
    className is dog
    ******YoloV3PostProcess end******

    推理完成后,在当前文件夹下生成“result.jpg”文件,图片结果如图3所示。

    图3 result.jpg文件

若执行样例时,出现{mxVision安装路径}/lib/libcpprest.so.2.10: error adding symbols: DSO missing from command line报错,请参考程序执行出现error adding symbols: DSO missing from command line报错解决。