本章节介绍的样例适用于Atlas 推理系列产品和Atlas 200I/500 A2 推理产品。
下面以Atlas 推理系列产品为例,通过Vision SDK图像分类案例,介绍如何使用Vision SDK流程编排方式开发推理应用。案例使用YoloV3模型对图片进行分类并最后输出分类结果。样例取用TensorFlow框架YoloV3模型。
软件依赖名称 |
推荐版本 |
获取链接 |
---|---|---|
操作系统 |
请参见支持的硬件和操作系统 |
- |
系统依赖 |
- |
|
CANN开发套件包 |
8.0.0 |
CANN获取链接。 |
npu-driver驱动包 |
Ascend HDK 24.1.0 |
|
npu-firmware固件包 |
Ascend HDK 24.1.0 |
请访问获取链接,获取样例代码压缩包。
1 2 |
unzip pipelineSample.zip cd pipelineSample |
样例代码目录结构参考如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|-- pipelineSample | |-- data | | |-- dog1_1024_683.jpg //测试图片 | |-- models //存放模型目录 | | |-- yolov3_tf_bs1_fp16.cfg //模型配置文件 | | |-- aipp_yolov3_416_416.aippconfig //yolov3 om模型aipp转换文件 | | |-- yolov3.names //模型输出类别名称文件 | |-- pipeline //存放pipeline文件 | | |-- Sample.pipeline //pipeline文件 | |-- src | | |-- CMakeLists.txt //CMakeLists文件 | | |-- main.cpp //主函数,图片分类功能的实现文件 | |-- README.md | |-- run.sh //运行程序的脚本,运行前建议使用dos2unix工具执行dos2uinx run.sh命令,对脚本进行格式化处理 |
用户需使用自行获取的图片进行测试(请将获取的图片名称更名为与样例代码的图片名字一致,如dog1_1024_683.jpg),以下图片为展示用途。
编排pipeline文件是使用Vision SDK开发应用最核心的任务,图像分类应用可拆解为一系列的业务流程,通过编辑pipeline文件,调用Vision SDK插件库完成推理业务,本文的pipeline文件内容以图2中所示的业务流程进行样例配置编排。
样例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
{ "objectdetection": { // 修改"objectdetection" 为当前业务推理流程的名称 "stream_config": { "deviceId": "0" // "deviceId" 表示要使用的芯片的ID号 }, "appsrc0": { // "appsrc0" 表示输入元件名称 "props": { // "props"指元件属性 "blocksize": "409600" // 每个buffer读取的大小 }, "factory": "appsrc", // "factory" 定义该元件类型 "next": "mxpi_imagedecoder0" // "next" 填写连接的下游元件--图像解码元件 }, "mxpi_imagedecoder0": { // 图像解码元件名称,0表示编号,如果一个流程中要使用多个图像解码元件,可以依次按照0、1、2...命名 "props": { "handleMethod": "ascend" // 解码方法为ascend }, "factory": "mxpi_imagedecoder", // 使用图像解码插件 "next": "mxpi_imageresize0" // "next" 填写连接的下游元件--图像缩放元件 }, "mxpi_imageresize0": { // 图像缩放元件名称 "props": { "handleMethod": "ascend", // 解码方法为ascend "resizeHeight": "416", // 指定缩放后的高 "resizeWidth": "416",, // 指定缩放后的宽 "resizeType": "Resizer_Stretch" // 缩放方式为拉伸缩放 }, "factory": "mxpi_imageresize", // 使用图像缩放插件 "next": "mxpi_tensorinfer0" // "next" 填写连接的下游元件--模型推理元件 }, "mxpi_tensorinfer0": { // 模型推理元件名称 "props": { // "props"指元件属性,可以加载指定目录中的文件 "dataSource": "mxpi_imageresize0", // "dataSource"填写连接的上游元件--图像缩放元件 "modelPath": "../models/yolov3_tf_bs1_fp16.om", // "modelPath" 属性定义了推理业务使用的模型,用户需要根据获取的模型修改文件名 "waitingTime": "2000", // 多batch模型可容忍的等待组BATCH时间 "outputDeviceId": "-1" // 内存拷贝到指定位置,设为-1则拷贝至Host侧 }, "factory": "mxpi_tensorinfer", // 使用模型推理插件 "next": "mxpi_objectdetection0" // "next"填写连接的下游元件--模型后处理元件 }, "mxpi_objectdetection0": { // 模型后处理元件名称 "props": { // "props"指元件属性,可以加载指定目录中的文件 "dataSource": "mxpi_tensorinfer0", // "dataSource"填写连接的上游元件--模型推理元件 "postProcessConfigPath": "../models/yolov3_tf_bs1_fp16.cfg",// "postProcessConfigPath" 指定模型后处理配置文件 "labelPath": "../models/yolov3.names", // "labelPath" 指定模型输出的类别名称文件 "postProcessLibPath": "libyolov3postprocess.so" // "postProcessLibPath" 指定模型后处理依赖的动态库 }, "factory": "mxpi_objectpostprocessor", // 使用模型后处理插件 "next": "mxpi_dataserialize0" // "next" 填写连接的下游元件--序列化元件 }, "mxpi_dataserialize0": { // 序列化元件名称 "props": { "outputDataKeys": "mxpi_objectdetection0" // "outputDataKeys" 指定需要输出的数据的索引 }, "factory": "mxpi_dataserialize", // 使用序列化插件 "next": "appsink0" // "next" 填写连接的下游元件--输出元件 }, "appsink0": { // 输出元件名称 "props": { "blocksize": "4096000" // 每个buffer读取的大小 }, "factory": "appsink" // 使用输出插件 } } } |
pipeline文件中的注释仅用于辅助理解,在编写pipeline文件时,请删除其中的注释文字,否则会导致文件解析失败。
在这段pipeline中,有以下关键概念:
“pipelineSample/src”目录中的“main.cpp”文件为应用程序源码。
在本样例中,关键步骤与代码参考如下,不可以直接拷贝编译运行,需要根据实际情况修改pipeline文件路径、输入图片路径、Stream名称,Stream名称需要与pipeline文件中的业务推理流程的名称匹配,如上述pipeline文件的业务推理流程的名称为“classification”。完整样例代码请参考样例文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
int main(int argc, char* argv[]) { // 1.解析pipeline文件 std::string pipelineConfigPath = "../pipeline/Sample.pipeline"; // 修改pipeline文件路径 std::string pipelineConfig = ReadPipeline(pipelineConfigPath); if (pipelineConfig == "") { LogError << "Read pipeline failed."; return APP_ERR_COMM_INIT_FAIL; } // 2.初始化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; } // 3.创建stream ret = mxStreamManager.CreateMultipleStreams(pipelineConfig); if (ret != APP_ERR_OK) { LogError << GetError(ret) << "Failed to create Stream."; mxStreamManager.DestroyAllStreams(); return ret; } // 4.读取待推理图片 MxStream::MxstDataInput dataBuffer; ret = ReadFile("../data/dog1_1024_683.jpg", dataBuffer); // 修改输入图片路径 if (ret != APP_ERR_OK) { LogError << GetError(ret) << "Failed to read image file."; mxStreamManager.DestroyAllStreams(); return ret; } std::string streamName = "objectdetection"; // 修改业务推理流程的名称 int inPluginId = 0; // 5.发送待推理图片至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; mxStreamManager.DestroyAllStreams(); return ret; } // 6.获取推理结果 MxStream::MxstDataOutput* output = mxStreamManager.GetResult(streamName, inPluginId); if (output == nullptr) { LogError << "Failed to get pipeline output."; delete dataBuffer.dataPtr; dataBuffer.dataPtr = nullptr; mxStreamManager.DestroyAllStreams(); return ret; } std::string result = std::string((char *)output->dataPtr, output->dataSize); std::cout << "Results:" << result << std::endl; // 7.销毁stream,并释放资源 mxStreamManager.DestroyAllStreams(); delete dataBuffer.dataPtr; dataBuffer.dataPtr = nullptr; delete output; return 0; } |
1 2 |
source /usr/local/Ascend/ascend-toolkit/set_env.sh source /home/mxVision-{version}/set_env.sh |
1 2 |
chmod +x run.sh ./run.sh |
终端上屏显的结果如下,“classId”表示类别号、“className”表示类名称,“confidence”表示该分类的最大置信度:
1 2 3 4 5 6 7 8 9 10 11 12 |
Results:{ "MxpiObject":[{"classVec":[{ "classId":16, "className":"dog", "confidence":0.994434595, "headerVec":[]}], "x0":113.476166, "x1":882.497559, "y0":127.61911, "y1":595.543884 }] } |