API接口开发方式(C++)
样例介绍
本样例以Atlas 200I/500 A2 推理产品,使用mxVision C++接口开发图像目标检测应用进行演示,图像目标检测模型推理流程图如图1所示。
样例取用TensorFlow框架YoloV3模型。模型的输入、输出数据格式参见如下。
- 输入数据:分辨率为416 * 416的RGB格式图片。
- 输出数据:识别目标的坐标、类别及其对应的置信度。
准备工作
- 请先完成mxVision安装部署后,再进行快速入门样例。
表1 环境要求软件依赖 软件依赖名称
推荐版本
获取链接
操作系统
请参见支持的硬件和操作系统
-
系统依赖
-
CANN开发套件包
8.0.RC3
npu-driver驱动包
Ascend HDK 24.1.RC3
npu-firmware固件包
Ascend HDK 24.1.RC3
numpy
1.25.2
pip3 install numpy==1.25.2
- 获取样例代码。本样例代码仅支持在Atlas 200I/500 A2 推理产品上运行。
- 以普通用户登录已安装mxVision的开发环境并将样例代码压缩包上传。
- 解压样例代码压缩包,进入解压后的目录,命令参考如下。
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 # 运行程序的脚本,运行前建议使用dos2unix工具执行dos2uinx run.sh命令,对脚本进行格式化处理 ├── README.md ├── test.jpg # 测试用图片,需要用户自行准备
- 准备用于推理的模型。
用户可参考模型转换功能(ATC)转换om模型进行推理,具体转换方法请参考4解压目录中“README.md”的“模型获取”章节,该参考样例使用到的om模型为使用了AIPP预处理配置的模型。
- 准备用于推理的图片数据。
用户需使用自行获取的图片进行测试(请将获取的图片名称更名为“test.jpg”),以下图片为展示用途。
图2 test.jpg
代码解析
在该样例中,关键步骤与代码参考如下,不可以直接拷贝编译运行,完整样例代码请参考样例文件。
- 初始化资源,配置模型相关变量,如模型路径、配置文件路径、标签路径等。
// 初始化资源和变量 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 = MxBase::MxInit();
- 对输入数据进行前处理。执行MxInit初始化资源,同时初始化ImageProcessor对象后,解码图片,得到Image对象,再进行相应的图片缩放,之后将其转化为推理所需要的数据格式(Tensor类型)。
// 前处理 //构建图像处理类 MxBase::ImageProcessor imageProcessor(deviceId); //构建解码后的图像类 MxBase::Image decodedImage; //根据图像路径进行解码 ret = imageProcessor.Decode(imgPath, decodedImage, ImageFormat::YUV_SP_420); MxBase::Image resizeImage; //缩放尺寸 MxBase::Size resizeConfig(YOLOV3_RESIZE, YOLOV3_RESIZE); //执行缩放 ret = imageProcessor.Resize(decodedImage, resizeConfig, resizeImage, MxBase::Interpolation::HUAWEI_HIGH_ORDER_FILTER); std::string path = "./resized_yolov3_416.jpg"; //编码缩放后的图片,并输出到指定路径 ret = imageProcessor.Encode(resizeImage, path); //转换Image对象为Tensor MxBase::Tensor tensorImg = resizeImage.ConvertToTensor(); //设置Tensor所在设备编号 ret = tensorImg.ToDevice(deviceId);
- 构建模型类后,输入前处理构建的Tensor对象,执行Infer接口,之后得到模型输出结果yoloV3Outputs。
// 模型推理 // 构建模型类 MxBase::Model yoloV3(modelPath, deviceId); //构造Infer接口入参Batch Tensor std::vector<MxBase::Tensor> yoloV3Inputs = {tensorImg}; //执行模型推理 std::vector<MxBase::Tensor> yoloV3Outputs = yoloV3.Infer(yoloV3Inputs);
- 对模型输出进行后处理。利用mxVision提供的后处理插件(也可自行开发),可得到目标检测框及其目标类别,并通过opencv将其在原图上呈现。
// 后处理 //后处理原图信息 MxBase::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)); //初始化后处理类 MxBase::Yolov3PostProcess yolov3PostProcess; APP_ERROR ret = yolov3PostProcess.Init(postConfig); //后处理 vector<MxBase::TensorBase> tensors; //依据模型推理结果构建目标检测信息,该信息为mxVision已实现后处理函数必备数据 //若后处理函数为用户自定义,需按照实际情况构造 vector<vector<MxBase::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();
- 去初始化,释放资源。
// 去初始化 ret = MxBase::MxDeInit(); if (ret != APP_ERR_OK) { LogError << "MxDeInit failed, ret=" << ret << "."; return ret; }
运行推理
- 配置环境变量(以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
- 运行推理(运行该脚本前,需根据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所示。
若执行样例时,出现{mxVision安装路径}/lib/libcpprest.so.2.10: error adding symbols: DSO missing from command line报错,请参考程序执行出现error adding symbols: DSO missing from command line报错解决。
父主题: 快速入门