From c7ae0f21665ea846d8b89be741518017cca5fbeb Mon Sep 17 00:00:00 2001 From: Ssayhi_w Date: Thu, 19 Dec 2024 16:01:21 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E6=96=B0=E5=A2=9EmxVison=20Model=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=BD=BF=E7=94=A8=E6=A0=B7=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/ModleSample/C++/CMakeLists.txt | 45 ++++++++++ contrib/ModleSample/C++/main.cpp | 79 ++++++++++++++++ contrib/ModleSample/C++/run.sh | 11 +++ contrib/ModleSample/README.md | 120 +++++++++++++++++++++++++ contrib/ModleSample/python/main.py | 60 +++++++++++++ 5 files changed, 315 insertions(+) create mode 100644 contrib/ModleSample/C++/CMakeLists.txt create mode 100644 contrib/ModleSample/C++/main.cpp create mode 100644 contrib/ModleSample/C++/run.sh create mode 100644 contrib/ModleSample/README.md create mode 100644 contrib/ModleSample/python/main.py diff --git a/contrib/ModleSample/C++/CMakeLists.txt b/contrib/ModleSample/C++/CMakeLists.txt new file mode 100644 index 000000000..2212d7874 --- /dev/null +++ b/contrib/ModleSample/C++/CMakeLists.txt @@ -0,0 +1,45 @@ +# CMake lowest version requirement +cmake_minimum_required(VERSION 3.5.2) +# project information +project(MindX_SDK_Sample) +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() +# Compile options +add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) +add_definitions(-Dgoogle=mindxsdk_private) +add_compile_options(-std=c++14 -fPIC -fstack-protector-all -Wall) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) +set(CMAKE_CXX_FLAGS_DEBUG "-g") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro,-z,now,-z,noexecstack -s -pie") +set(CMAKE_SKIP_RPATH TRUE) +set(ASCEND_HOME_PATH $ENV{ASCEND_HOME_PATH}) + + +include_directories( +${MX_SDK_HOME}/include/ +${MX_SDK_HOME}/include/MxBase/postprocess/include/ +${MX_SDK_HOME}/opensource/include/ +${MX_SDK_HOME}/opensource/include/opencv4 +${ASCEND_HOME_PATH}/${ARCH_PATTERN}/include +${ASCEND_HOME_PATH}/${ARCH_PATTERN}/runtime/include +) + + +link_directories( +${MX_SDK_HOME}/lib/ +${MX_SDK_HOME}/lib/modelpostprocessors/ +${MX_SDK_HOME}/opensource/lib/ +${MX_SDK_HOME}/opensource/lib64/ +${ASCEND_HOME_PATH}/atc/lib64 +${MX_SDK_HOME}/include/MxBase/postprocess/include +) + + +add_executable(main main.cpp) +target_link_libraries(main ascendcl acl_dvpp mxbase glog opencv_world pthread) +install(TARGETS main DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) \ No newline at end of file diff --git a/contrib/ModleSample/C++/main.cpp b/contrib/ModleSample/C++/main.cpp new file mode 100644 index 000000000..69fcd1b1d --- /dev/null +++ b/contrib/ModleSample/C++/main.cpp @@ -0,0 +1,79 @@ +/* + * Copyright(C) 2024. Huawei Technologies Co.,Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include "acl/acl.h" +#include "MxBase/E2eInfer/Model/Model.h" +#include "MxBase/E2eInfer/Tensor/Tensor.h" +#include "MxBase/E2eInfer/GlobalInit/GlobalInit.h" +#include "MxBase/DeviceManager/DeviceManager.h" +#include "MxBase/Asynchron/AscendStream.h" + + +using namespace MxBase; +using namespace std; + +std::string g_mindIrModelPath = "../model/yolov4_bs.mindir"; // mindir模型路径 +std::string g_OmModelPath = "../model/yolov4_detection.om"; // mindir模型路径 + +void ModelInfer(){ + int32_t deviceId = 0; // 模型部署的芯片 + Model model(g_OmModelPath, deviceId); + std::vector inShape64 = model.GetInputTensorShape(); // 获得模型输入的对应Tensor的数据shape信息。 + std::vector inShape; + std::cout<< "inShape:"; + for (auto s: inShape64) { + std::cout<< " " << s ; + inShape.push_back(static_cast(s)); // 动态模型场景下对应的动态维度查询结果为-1。如果要使用查询的结果直接传入Tensor构造函数构造Tensor,需要将int64_t数据转换为uint32_t数据。 + } + std::cout << std::endl; + TensorDType dtype = model.GetInputTensorDataType(0); // 获得模型输入的对应Tensor的数据类型信息。 + std::vector input; // 输入 + std::vector output; // 输出 + auto n = model.GetOutputTensorNum(); // 获得模型的输出个数。 + std::cout<< "n:" << n << std::endl; + for (size_t i = 0; i < n; i++) { + std::vector ouputShape = model.GetOutputTensorShape(i); // 获得模型输出的对应Tensor的数据shape信息。查询的结果可直接传入Tensor构造函数用来构造Tensor。 + std::cout << "ouputShape size: " << ouputShape.size() << std::endl; + for (size_t j = 0; j < ouputShape.size(); ++j) { + std::cout << "ouputShape[" << j << "] " << ouputShape[j] << std::endl; + } + MxBase::TensorDType outputDType = model.GetOutputTensorDataType(i); // 获得模型输出的对应Tensor的数据类型信息。 + Tensor dst(ouputShape, outputDType); + dst.Malloc(); + dst.ToDevice(0); + output.push_back(dst); + } + Tensor src(inShape, dtype); + src.Malloc(); + src.ToDevice(0); + input.push_back(src); + AscendStream stream(0); + stream.CreateAscendStream(); + auto ret = model.Infer(input, output, stream); // Model的推理接口 + stream.Synchronize(); + stream.DestroyAscendStream(); +} + + +int main(){ + MxBase::MxInit(); + ModelInfer(); + MxBase::MxDeInit(); +} \ No newline at end of file diff --git a/contrib/ModleSample/C++/run.sh b/contrib/ModleSample/C++/run.sh new file mode 100644 index 000000000..a03c19f38 --- /dev/null +++ b/contrib/ModleSample/C++/run.sh @@ -0,0 +1,11 @@ +rm -rf build + +# compile +cmake -S . -Bbuild +make -C ./build -j + +# run +./main + + +exit 0 \ No newline at end of file diff --git a/contrib/ModleSample/README.md b/contrib/ModleSample/README.md new file mode 100644 index 000000000..06cdff211 --- /dev/null +++ b/contrib/ModleSample/README.md @@ -0,0 +1,120 @@ +## 基于MindX SDK的faceswap应用开发 + +## 1、 介绍 + +### 1.1 简介 +faceswap应用基于MindX SDK开发,在昇腾芯片上进行目标检测,脸部关键点推理以及目标替换,将替换结果可视化并保存。 + +### 1.2 支持的产品 + +本项目支持昇腾Atlas 300I pro、 Atlas300V pro + +### 1.3 支持的版本 + +本样例配套的MxVision版本、CANN版本、Driver/Firmware版本如下所示: +| MxVision版本 | CANN版本 | Driver/Firmware版本 | +| --------- | ------------------ | -------------- | +| 6.0.RC3 | 8.0.RC3 | 24.1.RC3 | + +### 1.4 三方依赖 + +| 软件名称 | 版本 | +| ------------- | ---------------- | +| numpy | 1.19.5 | +| opencv-python | 4.10.0.84 | +| Pillow | 9.3.0 | + +### 1.5 三方依赖 + +本Sample工程名称为faceswap,工程目录如下图所示: +```angular2html +|-------- data // 输入存放文件夹(需手动创建) +|-------- models +| |---- yolov4.cfg // yolov4后处理配置文件(用于目标检测) +| |---- coco.names // yolov4模型所有可识别类 +| |---- yolov4_detection.om // yolov4离线推理模型 +| |---- V3ONNX.cfg // 脸部特征点检测模型转换配置文件(用于检测脸部特征点) +| |---- V3ONNXX.om // 脸部特征点检测离线模型 +|-------- pipline +| |---- faceswap.pipeline // 目标替换流水线配置文件 +|-------- result // 存放结果文件(需手动创建) +|-------- faceswap_main.py +|-------- faceswap_post.py // 后处理模块 +|-------- README.md +``` + +## 2、 设置环境变量 + +在编译运行项目前,需要设置环境变量: + +```bash +. /usr/local/Ascend/ascend-toolkit/set_env.sh #toolkit默认安装路径,根据实际安装路径修改 +. ${SDK_INSTALL_PATH}/mxVision/set_env.sh #sdk安装路径,根据实际安装路径修改 +``` + +## 3、 准备模型 + +**步骤1**:模型文件下载 + +目标检测采用提供的离线模型yolov4_detection.om进行推理。 + +[模型下载链接](https://mindx.sdk.obs.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/faceswap/yolov4_detection.om) 。 + +下载后,将yolov4_detection.om模型存放在工程/model目录下。 + +下载脸部特征点检测onnx模型 + +[模型下载链接](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/faceswap/v3.onnx)。 + +下载后,将v3.onnx模型存放在工程/model目录下。 + +**步骤2**:模型转换 + +在项目的model“文件夹下执行以下命令: +``` +atc --model=v3.onnx --framework=5 --output=V3ONNXX --soc_version=Ascend310P3 --insert_op_conf=V3ONNX.cfg --out_nodes="Gemm_169:0" +``` + +执行完模型转换脚本后,会生成相应的V3ONNXX.om模型文件。执行命令后终端输出为: +```bash +ATC start working now, please wait for a moment. +ATC run success, welcome to the next use. +``` + +## 4、 运行 + +**步骤1**:准备两张需要的测试图片 + +在项目根目录下执行以下命令新建`data`文件夹。 +``` +mkdir data +``` +将准备好的测试图片放在`data`文件夹下并分别命名为`face1.jpg`,`face2.jpg`。 + +**步骤2**:创建输出文件夹 + +在项目根目录下执行以下命令新建`result`文件夹,用于存放推理结果。 +``` +mkdir result +``` + +**步骤3**:执行程序 + +在项目根目录下,执行以下命令运行样例。 +``` +python3 faceswap_main.py data/face1.jpg data/face2.jpg +``` + +**步骤4**:查看结果 + +执行完成后,可在`result`目录中查看目标替换结果`face_swap_result.jpg`。 + + +## 5、 常见问题 +- 在目标检测阶段,由于yolov4_detection.om模型的coco.names标签集中同时存在people,face两类标签。当对输入图片的检测结果为people时,无法进行后续的换脸操作,故输入图片应尽可能体现脸部特征,建议输入图片为类似于证件照的半身人像。否则,当输入为全身人像时候,图片标签为people,无法进行后续换脸操作; +- 在特征点检测阶段,由于特征点检测模型限制,输入目标应尽可能采用脸部清晰,轮廓完整的正面图像,即应尽可能输入2D目标图像,且脸部应尽可能避免眼镜等一类装饰物。若图片中存在3D特征,如输入侧脸时,可能会由于脸部特征点检测存在偏差导致换脸效果不佳; +- 针对MindX SDK固有插件的输入限制,输入目标图片的宽高均应限制在[32, 8192]区间内,否则会导致图片入流失败。当输入图片尺寸不符合要求时,系统会提示相应的错误信息。 + + + + diff --git a/contrib/ModleSample/python/main.py b/contrib/ModleSample/python/main.py new file mode 100644 index 000000000..6b9a697f1 --- /dev/null +++ b/contrib/ModleSample/python/main.py @@ -0,0 +1,60 @@ +import cv2 +import numpy as np +import torch + +# from mindx.sdk.base import Tensor # mxVision 中的 Tensor 数据结构 +from mindx.sdk import Tensor +from mindx.sdk import base # mxVision 推理接口 +from mindx.sdk.base import Model # mxVision 推理接口 + + +def process(): + + DEVICE_ID = 0 # 设备id + model_path = '../model/yolov4_detection.om' # 模型路径 + + # 模型加载的两种方式 + # 方式一 + model = base.model(modelPath=model_path, deviceId=DEVICE_ID) # 函数返回参数为Model对象 + + # 方式二 + # model = Model(model_path,0) # 直接使用Model类构造对象 + + print("input_num:",model.input_num) # 获得模型的输入个数。 + print("output_num:",model.output_num) # 获得模型的输出个数。 + + input_shape_vector = model.input_shape(0) # 获得模型输入的对应Tensor的数据shape信息。 + input_shape_list = list(input_shape_vector) + print("input_shape_list:",input_shape_list) + + output_shape_vector = model.output_shape(0) # 获得模型输出的对应Tensor的数据shape信息。 + output_shape_list = list(output_shape_vector) + print("output0_shape_list:",output_shape_list) + + output_shape_vector = model.output_shape(1) # 获得模型输出的对应Tensor的数据shape信息。 + output_shape_list = list(output_shape_vector) + print("output1_shape_list:",output_shape_list) + + input_dtype = model.input_dtype(0) + print("Input dtype:", input_dtype) + + + # 使用numpy生成输入数据 真实情况下读入图片进行推理也可以通过numpy转换为Tensor类型 + img = np.random.randint(0, 255, size=(input_shape_list[0], input_shape_list[1], input_shape_list[2], input_shape_list[3]), dtype=np.uint8).astype(np.uint8) #这里的size根据模型输入的要求确定 + img = Tensor(img) # 将numpy转为转为Tensor类 + output = model.infer([img]) # 执行推理。输入数据类型:List[base.Tensor], 返回模型推理输出的 List[base.Tensor] + + output[0].to_host() # 将 Tensor 数据转移到内存 + output0 = np.array(output[0]) # 将数据转为 numpy array 类型 + print("output0 shape",output0.shape) + + output[1].to_host() # 将 Tensor 数据转移到内存 + output1 = np.array(output[1]) # 将数据转为 numpy array 类型 + print("output1 shape",output1.shape) + + +if __name__ == "__main__": + # 初始化资源和变量 + base.mx_init() # 初始化 mxVision 资源 + process() + base.mx_deinit() \ No newline at end of file -- Gitee From 83f8d7679614c24ea23ab8a592b36cd88d0694df Mon Sep 17 00:00:00 2001 From: Ssayhi_w Date: Thu, 19 Dec 2024 20:53:23 +0800 Subject: [PATCH 2/9] =?UTF-8?q?--Model=E6=8E=A5=E5=8F=A3=E5=9F=BA=E6=9C=AC?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=95=99=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/ModleSample/C++/CMakeLists.txt | 17 +--- contrib/ModleSample/C++/main.cpp | 34 +++++--- contrib/ModleSample/C++/run.sh | 1 - contrib/ModleSample/README.md | 114 ++++++++++++++----------- contrib/ModleSample/model/.keepme | 0 contrib/ModleSample/python/main.py | 42 +++------ 6 files changed, 101 insertions(+), 107 deletions(-) create mode 100644 contrib/ModleSample/model/.keepme diff --git a/contrib/ModleSample/C++/CMakeLists.txt b/contrib/ModleSample/C++/CMakeLists.txt index 2212d7874..49a02d9c5 100644 --- a/contrib/ModleSample/C++/CMakeLists.txt +++ b/contrib/ModleSample/C++/CMakeLists.txt @@ -9,6 +9,7 @@ message(STATUS "set default MX_SDK_HOME: ${MX_SDK_HOME}") else () message(STATUS "env MX_SDK_HOME: ${MX_SDK_HOME}") endif() + # Compile options add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) add_definitions(-Dgoogle=mindxsdk_private) @@ -17,29 +18,15 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) set(CMAKE_CXX_FLAGS_DEBUG "-g") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro,-z,now,-z,noexecstack -s -pie") set(CMAKE_SKIP_RPATH TRUE) -set(ASCEND_HOME_PATH $ENV{ASCEND_HOME_PATH}) - include_directories( ${MX_SDK_HOME}/include/ -${MX_SDK_HOME}/include/MxBase/postprocess/include/ -${MX_SDK_HOME}/opensource/include/ -${MX_SDK_HOME}/opensource/include/opencv4 -${ASCEND_HOME_PATH}/${ARCH_PATTERN}/include -${ASCEND_HOME_PATH}/${ARCH_PATTERN}/runtime/include ) - link_directories( ${MX_SDK_HOME}/lib/ -${MX_SDK_HOME}/lib/modelpostprocessors/ -${MX_SDK_HOME}/opensource/lib/ -${MX_SDK_HOME}/opensource/lib64/ -${ASCEND_HOME_PATH}/atc/lib64 -${MX_SDK_HOME}/include/MxBase/postprocess/include ) - add_executable(main main.cpp) -target_link_libraries(main ascendcl acl_dvpp mxbase glog opencv_world pthread) +target_link_libraries(main mxbase glog pthread) install(TARGETS main DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) \ No newline at end of file diff --git a/contrib/ModleSample/C++/main.cpp b/contrib/ModleSample/C++/main.cpp index 69fcd1b1d..79cae6caa 100644 --- a/contrib/ModleSample/C++/main.cpp +++ b/contrib/ModleSample/C++/main.cpp @@ -18,26 +18,40 @@ #include #include #include -#include "acl/acl.h" #include "MxBase/E2eInfer/Model/Model.h" #include "MxBase/E2eInfer/Tensor/Tensor.h" #include "MxBase/E2eInfer/GlobalInit/GlobalInit.h" #include "MxBase/DeviceManager/DeviceManager.h" #include "MxBase/Asynchron/AscendStream.h" - using namespace MxBase; using namespace std; -std::string g_mindIrModelPath = "../model/yolov4_bs.mindir"; // mindir模型路径 -std::string g_OmModelPath = "../model/yolov4_detection.om"; // mindir模型路径 +std::string g_OmModelPath = "../model/IAT_lol-sim.om"; // mindir模型路径 void ModelInfer(){ int32_t deviceId = 0; // 模型部署的芯片 Model model(g_OmModelPath, deviceId); + + MxBase::VisionDataFormat inputFormat = model.GetInputFormat(); // 获得模型输入的数据组织形式(NHWC 或者 NCHW)。 + switch (inputFormat) { + case MxBase::VisionDataFormat::NCHW: + std::cout << "Input format: NCHW" << std::endl; + break; + case MxBase::VisionDataFormat::NHWC: + std::cout << "Input format: NHWC" << std::endl; + break; + default: + std::cout << "Unknown input format" << std::endl; + break; + } + + std::cout << "model input tensor num: " << model.GetInputTensorNum() << std::endl; + std::cout << "model output tensor num: " << model.GetOutputTensorNum() << std::endl; + std::vector inShape64 = model.GetInputTensorShape(); // 获得模型输入的对应Tensor的数据shape信息。 std::vector inShape; - std::cout<< "inShape:"; + std::cout<< "inputShape:"; for (auto s: inShape64) { std::cout<< " " << s ; inShape.push_back(static_cast(s)); // 动态模型场景下对应的动态维度查询结果为-1。如果要使用查询的结果直接传入Tensor构造函数构造Tensor,需要将int64_t数据转换为uint32_t数据。 @@ -46,14 +60,13 @@ void ModelInfer(){ TensorDType dtype = model.GetInputTensorDataType(0); // 获得模型输入的对应Tensor的数据类型信息。 std::vector input; // 输入 std::vector output; // 输出 - auto n = model.GetOutputTensorNum(); // 获得模型的输出个数。 - std::cout<< "n:" << n << std::endl; - for (size_t i = 0; i < n; i++) { + for (size_t i = 0; i < model.GetOutputTensorNum(); i++) { std::vector ouputShape = model.GetOutputTensorShape(i); // 获得模型输出的对应Tensor的数据shape信息。查询的结果可直接传入Tensor构造函数用来构造Tensor。 - std::cout << "ouputShape size: " << ouputShape.size() << std::endl; + std::cout << "ouputShape: " ; for (size_t j = 0; j < ouputShape.size(); ++j) { - std::cout << "ouputShape[" << j << "] " << ouputShape[j] << std::endl; + std::cout << ouputShape[j] << " "; } + std::cout << std::endl; MxBase::TensorDType outputDType = model.GetOutputTensorDataType(i); // 获得模型输出的对应Tensor的数据类型信息。 Tensor dst(ouputShape, outputDType); dst.Malloc(); @@ -71,7 +84,6 @@ void ModelInfer(){ stream.DestroyAscendStream(); } - int main(){ MxBase::MxInit(); ModelInfer(); diff --git a/contrib/ModleSample/C++/run.sh b/contrib/ModleSample/C++/run.sh index a03c19f38..2bb033d1d 100644 --- a/contrib/ModleSample/C++/run.sh +++ b/contrib/ModleSample/C++/run.sh @@ -7,5 +7,4 @@ make -C ./build -j # run ./main - exit 0 \ No newline at end of file diff --git a/contrib/ModleSample/README.md b/contrib/ModleSample/README.md index 06cdff211..e316c9ca9 100644 --- a/contrib/ModleSample/README.md +++ b/contrib/ModleSample/README.md @@ -1,9 +1,29 @@ -## 基于MindX SDK的faceswap应用开发 +## MxVision快速入门--Model接口基本使用教程 ## 1、 介绍 ### 1.1 简介 -faceswap应用基于MindX SDK开发,在昇腾芯片上进行目标检测,脸部关键点推理以及目标替换,将替换结果可视化并保存。 +Model类,作为模型的抽象,持有模型推理的资源,并主要开放推理接口。 + +本文主要使用C++和python接口的方式,根据传入的模型文件构造Model,然后调用相关接口输出模型信息。使用到的接口主要有: +- C++: +``` +Model::GetInputFormat(); // 获得模型输入的数据组织形式(NHWC 或者 NCHW)。 +Model::GetInputTensorNum(); // 获得模型的输入个数。 +Model::GetOutputTensorNum(); // 获得模型的输出个数。 +Model::GetInputTensorShape(uint32_t index = 0); // 获得模型的输入个数。 +Model::GetOutputTensorShape(uint32_t index = 0); // 获得模型输出的对应Tensor的数据shape信息。 +Model::Infer(std::vector& inputTensors, std::vector& outputTensors, AscendStream &stream = AscendStream::DefaultStream()); // 推理接口 +``` + +- python: +``` +input_shape(index: int) # 获得模型输入的对应Tensor的数据shape信息 +output_shape(index: int) # 获得模型输出的对应Tensor的数据shape信息。 +input_dtype(index: int) # 获得模型输入的对应Tensor的数据类型信息。 +infer(tensorList: List) # 通过输入Tensor列表进行模型推理 +``` +python部分还使用了numpy相关接口实现了Tensor与numpy数组之间的生成和转换。 ### 1.2 支持的产品 @@ -20,26 +40,19 @@ faceswap应用基于MindX SDK开发,在昇腾芯片上进行目标检测,脸 | 软件名称 | 版本 | | ------------- | ---------------- | -| numpy | 1.19.5 | -| opencv-python | 4.10.0.84 | -| Pillow | 9.3.0 | +| numpy | 2.0.2 | ### 1.5 三方依赖 -本Sample工程名称为faceswap,工程目录如下图所示: +本项目工程目录如下图所示: ```angular2html -|-------- data // 输入存放文件夹(需手动创建) -|-------- models -| |---- yolov4.cfg // yolov4后处理配置文件(用于目标检测) -| |---- coco.names // yolov4模型所有可识别类 -| |---- yolov4_detection.om // yolov4离线推理模型 -| |---- V3ONNX.cfg // 脸部特征点检测模型转换配置文件(用于检测脸部特征点) -| |---- V3ONNXX.om // 脸部特征点检测离线模型 -|-------- pipline -| |---- faceswap.pipeline // 目标替换流水线配置文件 -|-------- result // 存放结果文件(需手动创建) -|-------- faceswap_main.py -|-------- faceswap_post.py // 后处理模块 +|-------- C++ +| |---- main.cpp +| |---- CMakeLists.txt +| |---- run.sh +|-------- python +| |---- main.py +|-------- model |-------- README.md ``` @@ -56,64 +69,61 @@ faceswap应用基于MindX SDK开发,在昇腾芯片上进行目标检测,脸 **步骤1**:模型文件下载 -目标检测采用提供的离线模型yolov4_detection.om进行推理。 - -[模型下载链接](https://mindx.sdk.obs.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/faceswap/yolov4_detection.om) 。 - -下载后,将yolov4_detection.om模型存放在工程/model目录下。 - -下载脸部特征点检测onnx模型 - -[模型下载链接](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/faceswap/v3.onnx)。 - -下载后,将v3.onnx模型存放在工程/model目录下。 +本项目意在为开发者介绍使用mxVision软件包中Model相关的C++、python接口使用样例。使用的模型为[RGB图像的夜间增强参考设计](https://gitee.com/ascend/mindxsdk-referenceapps/tree/master/contrib/IAT)中用到的模型。 +原始pth模型源码[地址](https://github.com/cuiziteng/illumination-adaptive-transformer) +本文提供已从pth模型转换好的onnx模型直接使用:[IAT_lol-sim.onnx](https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/IAT/IAT_lol-sim.onnx) +下载后放到项目根目录的model文件夹下。 **步骤2**:模型转换 -在项目的model“文件夹下执行以下命令: +将模型转换为om模型,在model文件夹下,执行以下命令生成om模型: ``` -atc --model=v3.onnx --framework=5 --output=V3ONNXX --soc_version=Ascend310P3 --insert_op_conf=V3ONNX.cfg --out_nodes="Gemm_169:0" +atc --framework=5 --model=./IAT_lol-sim.onnx --input_shape="input_1:1,3,400,600" --output=IAT_lol-sim --soc_version=Ascend310P3 ``` +执行完模型转换脚本后,会生成相应的IAT_lol-sim.om模型文件。 执行后终端输出为(模型转换时出现的warn日志可忽略): -执行完模型转换脚本后,会生成相应的V3ONNXX.om模型文件。执行命令后终端输出为: ```bash ATC start working now, please wait for a moment. ATC run success, welcome to the next use. ``` -## 4、 运行 +## 4、 编译与运行 -**步骤1**:准备两张需要的测试图片 +### 4.1 C++样例运行 -在项目根目录下执行以下命令新建`data`文件夹。 +**步骤1**:进入`C++`文件夹,执行以下命令: ``` -mkdir data +bash run.sh ``` -将准备好的测试图片放在`data`文件夹下并分别命名为`face1.jpg`,`face2.jpg`。 - -**步骤2**:创建输出文件夹 -在项目根目录下执行以下命令新建`result`文件夹,用于存放推理结果。 +**步骤2**:查看结果 +命令执行成功后可在屏幕看到模型信息输出 ``` -mkdir result +Input format: NCHW +model input tensor num: 1 +model output tensor num: 1 +inputShape: 1 3 400 600 +ouputShape: 1 3 400 600 ``` -**步骤3**:执行程序 +### 4.2 python样例运行 -在项目根目录下,执行以下命令运行样例。 +**步骤1**:进入`python`文件夹,执行以下命令: ``` -python3 faceswap_main.py data/face1.jpg data/face2.jpg +python3 main.py ``` -**步骤4**:查看结果 - -执行完成后,可在`result`目录中查看目标替换结果`face_swap_result.jpg`。 - +**步骤2**:查看结果 +命令执行成功后可在屏幕看到模型信息输出 +``` +input num: 1 +output num: 1 +input Tensor shape list: [1, 3, 400, 600] +output Tensor shape list: [1, 3, 400, 600] +Input dtype: dtype.float32 +output numpy array shape (1, 3, 400, 600) +``` -## 5、 常见问题 -- 在目标检测阶段,由于yolov4_detection.om模型的coco.names标签集中同时存在people,face两类标签。当对输入图片的检测结果为people时,无法进行后续的换脸操作,故输入图片应尽可能体现脸部特征,建议输入图片为类似于证件照的半身人像。否则,当输入为全身人像时候,图片标签为people,无法进行后续换脸操作; -- 在特征点检测阶段,由于特征点检测模型限制,输入目标应尽可能采用脸部清晰,轮廓完整的正面图像,即应尽可能输入2D目标图像,且脸部应尽可能避免眼镜等一类装饰物。若图片中存在3D特征,如输入侧脸时,可能会由于脸部特征点检测存在偏差导致换脸效果不佳; -- 针对MindX SDK固有插件的输入限制,输入目标图片的宽高均应限制在[32, 8192]区间内,否则会导致图片入流失败。当输入图片尺寸不符合要求时,系统会提示相应的错误信息。 diff --git a/contrib/ModleSample/model/.keepme b/contrib/ModleSample/model/.keepme new file mode 100644 index 000000000..e69de29bb diff --git a/contrib/ModleSample/python/main.py b/contrib/ModleSample/python/main.py index 6b9a697f1..96405dd00 100644 --- a/contrib/ModleSample/python/main.py +++ b/contrib/ModleSample/python/main.py @@ -1,8 +1,5 @@ -import cv2 import numpy as np -import torch -# from mindx.sdk.base import Tensor # mxVision 中的 Tensor 数据结构 from mindx.sdk import Tensor from mindx.sdk import base # mxVision 推理接口 from mindx.sdk.base import Model # mxVision 推理接口 @@ -11,7 +8,7 @@ from mindx.sdk.base import Model # mxVision 推理接口 def process(): DEVICE_ID = 0 # 设备id - model_path = '../model/yolov4_detection.om' # 模型路径 + model_path = '../model/IAT_lol-sim.om' # 模型路径 # 模型加载的两种方式 # 方式一 @@ -20,41 +17,30 @@ def process(): # 方式二 # model = Model(model_path,0) # 直接使用Model类构造对象 - print("input_num:",model.input_num) # 获得模型的输入个数。 - print("output_num:",model.output_num) # 获得模型的输出个数。 + print("input num:",model.input_num) # 获得模型的输入个数。 + print("output num:", model.output_num) # 获得模型的输出个数。 - input_shape_vector = model.input_shape(0) # 获得模型输入的对应Tensor的数据shape信息。 - input_shape_list = list(input_shape_vector) - print("input_shape_list:",input_shape_list) + inputShapeVector = model.input_shape(0) # 获得模型输入的对应Tensor的数据shape信息。 + inputShapeList = list(inputShapeVector) + print("input Tensor shape list:", inputShapeList) - output_shape_vector = model.output_shape(0) # 获得模型输出的对应Tensor的数据shape信息。 - output_shape_list = list(output_shape_vector) - print("output0_shape_list:",output_shape_list) - - output_shape_vector = model.output_shape(1) # 获得模型输出的对应Tensor的数据shape信息。 - output_shape_list = list(output_shape_vector) - print("output1_shape_list:",output_shape_list) - - input_dtype = model.input_dtype(0) - print("Input dtype:", input_dtype) + outputShapeVector = model.output_shape(0) # 获得模型输出的对应Tensor的数据shape信息。 + outputShapeList = list(outputShapeVector) + print("output Tensor shape list:", outputShapeList) + inputDtype = model.input_dtype(0) + print("Input dtype:", inputDtype) # 使用numpy生成输入数据 真实情况下读入图片进行推理也可以通过numpy转换为Tensor类型 - img = np.random.randint(0, 255, size=(input_shape_list[0], input_shape_list[1], input_shape_list[2], input_shape_list[3]), dtype=np.uint8).astype(np.uint8) #这里的size根据模型输入的要求确定 + img = np.random.randint(0, 255, size=(inputShapeList[0], inputShapeList[1], inputShapeList[2], inputShapeList[3]), dtype=np.uint8).astype(np.float32) #这里的size根据模型输入的要求确定 img = Tensor(img) # 将numpy转为转为Tensor类 output = model.infer([img]) # 执行推理。输入数据类型:List[base.Tensor], 返回模型推理输出的 List[base.Tensor] output[0].to_host() # 将 Tensor 数据转移到内存 - output0 = np.array(output[0]) # 将数据转为 numpy array 类型 - print("output0 shape",output0.shape) - - output[1].to_host() # 将 Tensor 数据转移到内存 - output1 = np.array(output[1]) # 将数据转为 numpy array 类型 - print("output1 shape",output1.shape) - + output = np.array(output[0]) # 将数据转为 numpy array 类型 + print("output numpy array shape", output.shape) if __name__ == "__main__": - # 初始化资源和变量 base.mx_init() # 初始化 mxVision 资源 process() base.mx_deinit() \ No newline at end of file -- Gitee From 2f08d5a0ba9f3033e2841f687f619f93ce4fd35b Mon Sep 17 00:00:00 2001 From: Ssayhi_w Date: Thu, 19 Dec 2024 20:55:46 +0800 Subject: [PATCH 3/9] Model --- {contrib => tutorials}/ModleSample/C++/CMakeLists.txt | 0 {contrib => tutorials}/ModleSample/C++/main.cpp | 0 {contrib => tutorials}/ModleSample/C++/run.sh | 0 {contrib => tutorials}/ModleSample/README.md | 0 {contrib => tutorials}/ModleSample/model/.keepme | 0 {contrib => tutorials}/ModleSample/python/main.py | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename {contrib => tutorials}/ModleSample/C++/CMakeLists.txt (100%) rename {contrib => tutorials}/ModleSample/C++/main.cpp (100%) rename {contrib => tutorials}/ModleSample/C++/run.sh (100%) rename {contrib => tutorials}/ModleSample/README.md (100%) rename {contrib => tutorials}/ModleSample/model/.keepme (100%) rename {contrib => tutorials}/ModleSample/python/main.py (100%) diff --git a/contrib/ModleSample/C++/CMakeLists.txt b/tutorials/ModleSample/C++/CMakeLists.txt similarity index 100% rename from contrib/ModleSample/C++/CMakeLists.txt rename to tutorials/ModleSample/C++/CMakeLists.txt diff --git a/contrib/ModleSample/C++/main.cpp b/tutorials/ModleSample/C++/main.cpp similarity index 100% rename from contrib/ModleSample/C++/main.cpp rename to tutorials/ModleSample/C++/main.cpp diff --git a/contrib/ModleSample/C++/run.sh b/tutorials/ModleSample/C++/run.sh similarity index 100% rename from contrib/ModleSample/C++/run.sh rename to tutorials/ModleSample/C++/run.sh diff --git a/contrib/ModleSample/README.md b/tutorials/ModleSample/README.md similarity index 100% rename from contrib/ModleSample/README.md rename to tutorials/ModleSample/README.md diff --git a/contrib/ModleSample/model/.keepme b/tutorials/ModleSample/model/.keepme similarity index 100% rename from contrib/ModleSample/model/.keepme rename to tutorials/ModleSample/model/.keepme diff --git a/contrib/ModleSample/python/main.py b/tutorials/ModleSample/python/main.py similarity index 100% rename from contrib/ModleSample/python/main.py rename to tutorials/ModleSample/python/main.py -- Gitee From ec2026f1f28f58e6a31c24e3c1d222949ee59596 Mon Sep 17 00:00:00 2001 From: Ssayhi_w Date: Thu, 19 Dec 2024 20:57:16 +0800 Subject: [PATCH 4/9] Model --- tutorials/ModleSample/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/ModleSample/README.md b/tutorials/ModleSample/README.md index e316c9ca9..4ae6e1dd1 100644 --- a/tutorials/ModleSample/README.md +++ b/tutorials/ModleSample/README.md @@ -23,7 +23,7 @@ output_shape(index: int) # 获得模型输出的对应Tensor的数据shape信息 input_dtype(index: int) # 获得模型输入的对应Tensor的数据类型信息。 infer(tensorList: List) # 通过输入Tensor列表进行模型推理 ``` -python部分还使用了numpy相关接口实现了Tensor与numpy数组之间的生成和转换。 +- python部分还使用了numpy相关接口实现了Tensor与numpy数组之间的生成和转换。 ### 1.2 支持的产品 -- Gitee From ac175807d2d2a51e465e58b9058881dbc5d533c8 Mon Sep 17 00:00:00 2001 From: Ssayhi_w Date: Thu, 19 Dec 2024 20:58:32 +0800 Subject: [PATCH 5/9] model --- tutorials/ModleSample/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/ModleSample/README.md b/tutorials/ModleSample/README.md index 4ae6e1dd1..c8c310206 100644 --- a/tutorials/ModleSample/README.md +++ b/tutorials/ModleSample/README.md @@ -42,7 +42,7 @@ infer(tensorList: List) # 通过输入Tensor列表进行模型推理 | ------------- | ---------------- | | numpy | 2.0.2 | -### 1.5 三方依赖 +### 1.5 代码目录结构说明 本项目工程目录如下图所示: ```angular2html -- Gitee From 0a44c789ac6d474753489f2ac3e04f0fbe9c6ec7 Mon Sep 17 00:00:00 2001 From: Ssayhi_w Date: Fri, 20 Dec 2024 14:27:25 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorials/ModleSample/C++/main.cpp | 12 +++++++---- tutorials/ModleSample/python/main.py | 30 ++++++++++++++-------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/tutorials/ModleSample/C++/main.cpp b/tutorials/ModleSample/C++/main.cpp index 79cae6caa..cca694587 100644 --- a/tutorials/ModleSample/C++/main.cpp +++ b/tutorials/ModleSample/C++/main.cpp @@ -29,7 +29,8 @@ using namespace std; std::string g_OmModelPath = "../model/IAT_lol-sim.om"; // mindir模型路径 -void ModelInfer(){ +void ModelInfer() +{ int32_t deviceId = 0; // 模型部署的芯片 Model model(g_OmModelPath, deviceId); @@ -54,14 +55,16 @@ void ModelInfer(){ std::cout<< "inputShape:"; for (auto s: inShape64) { std::cout<< " " << s ; - inShape.push_back(static_cast(s)); // 动态模型场景下对应的动态维度查询结果为-1。如果要使用查询的结果直接传入Tensor构造函数构造Tensor,需要将int64_t数据转换为uint32_t数据。 + //使用查询的结果直接传入Tensor构造函数构造Tensor,需要将int64_t数据转换为uint32_t数据。 + inShape.push_back(static_cast(s)); } std::cout << std::endl; TensorDType dtype = model.GetInputTensorDataType(0); // 获得模型输入的对应Tensor的数据类型信息。 std::vector input; // 输入 std::vector output; // 输出 for (size_t i = 0; i < model.GetOutputTensorNum(); i++) { - std::vector ouputShape = model.GetOutputTensorShape(i); // 获得模型输出的对应Tensor的数据shape信息。查询的结果可直接传入Tensor构造函数用来构造Tensor。 + // 获得模型输出的对应Tensor的数据shape信息。查询的结果可直接传入Tensor构造函数用来构造Tensor。 + std::vector ouputShape = model.GetOutputTensorShape(i); std::cout << "ouputShape: " ; for (size_t j = 0; j < ouputShape.size(); ++j) { std::cout << ouputShape[j] << " "; @@ -84,7 +87,8 @@ void ModelInfer(){ stream.DestroyAscendStream(); } -int main(){ +int main() +{ MxBase::MxInit(); ModelInfer(); MxBase::MxDeInit(); diff --git a/tutorials/ModleSample/python/main.py b/tutorials/ModleSample/python/main.py index 96405dd00..c029a521e 100644 --- a/tutorials/ModleSample/python/main.py +++ b/tutorials/ModleSample/python/main.py @@ -7,33 +7,33 @@ from mindx.sdk.base import Model # mxVision 推理接口 def process(): - DEVICE_ID = 0 # 设备id + device_id = 0 # 设备id model_path = '../model/IAT_lol-sim.om' # 模型路径 # 模型加载的两种方式 # 方式一 - model = base.model(modelPath=model_path, deviceId=DEVICE_ID) # 函数返回参数为Model对象 + model = base.model(modelPath=model_path, deviceId=device_id) # 函数返回参数为Model对象 # 方式二 - # model = Model(model_path,0) # 直接使用Model类构造对象 + # model = Model(model_path, 0) # 直接使用Model类构造对象 - print("input num:",model.input_num) # 获得模型的输入个数。 - print("output num:", model.output_num) # 获得模型的输出个数。 + print("input num:", model.input_num) # 获得模型的输入个数 + print("output num:", model.output_num) # 获得模型的输出个数 - inputShapeVector = model.input_shape(0) # 获得模型输入的对应Tensor的数据shape信息。 - inputShapeList = list(inputShapeVector) - print("input Tensor shape list:", inputShapeList) + input_shape_vector = model.input_shape(0) # 获得模型输入的对应Tensor的数据shape信息 + input_shape_list = list(input_shape_vector ) + print("input Tensor shape list:", input_shape_list) - outputShapeVector = model.output_shape(0) # 获得模型输出的对应Tensor的数据shape信息。 - outputShapeList = list(outputShapeVector) - print("output Tensor shape list:", outputShapeList) + output_shape_vector = model.output_shape(0) # 获得模型输出的对应Tensor的数据shape信息 + output_shape_list = list(output_shape_vector) + print("output Tensor shape list:", output_shape_list) - inputDtype = model.input_dtype(0) - print("Input dtype:", inputDtype) + input_dtype = model.input_dtype(0) + print("Input dtype:", input_dtype) # 使用numpy生成输入数据 真实情况下读入图片进行推理也可以通过numpy转换为Tensor类型 - img = np.random.randint(0, 255, size=(inputShapeList[0], inputShapeList[1], inputShapeList[2], inputShapeList[3]), dtype=np.uint8).astype(np.float32) #这里的size根据模型输入的要求确定 - img = Tensor(img) # 将numpy转为转为Tensor类 + img = np.random.randint(0, 255, size=(input_shape_list[0], input_shape_list[1], input_shape_list[2], input_shape_list[3]), dtype=np.uint8).astype(np.float32) #这里的size根据模型输入的要求确定 + img = Tensor(img) # 将numpy转为转为Tensor类 output = model.infer([img]) # 执行推理。输入数据类型:List[base.Tensor], 返回模型推理输出的 List[base.Tensor] output[0].to_host() # 将 Tensor 数据转移到内存 -- Gitee From 99dfcaffae9f95c8bcc5be800d59a08881d14937 Mon Sep 17 00:00:00 2001 From: Ssayhi_w Date: Fri, 20 Dec 2024 14:40:21 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorials/ModleSample/C++/main.cpp | 34 ++++++++++++++-------------- tutorials/ModleSample/python/main.py | 8 +++++-- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/tutorials/ModleSample/C++/main.cpp b/tutorials/ModleSample/C++/main.cpp index cca694587..144f89eb7 100644 --- a/tutorials/ModleSample/C++/main.cpp +++ b/tutorials/ModleSample/C++/main.cpp @@ -27,14 +27,14 @@ using namespace MxBase; using namespace std; -std::string g_OmModelPath = "../model/IAT_lol-sim.om"; // mindir模型路径 +std::string g_omModelPath = "../model/IAT_lol-sim.om"; // mindir模型路径 void ModelInfer() { int32_t deviceId = 0; // 模型部署的芯片 - Model model(g_OmModelPath, deviceId); + Model model(g_omModelPath, deviceId); - MxBase::VisionDataFormat inputFormat = model.GetInputFormat(); // 获得模型输入的数据组织形式(NHWC 或者 NCHW)。 + MxBase::VisionDataFormat inputFormat = model.GetInputFormat(); // 获得模型输入的数据组织形式(NHWC 或者 NCHW) switch (inputFormat) { case MxBase::VisionDataFormat::NCHW: std::cout << "Input format: NCHW" << std::endl; @@ -50,28 +50,28 @@ void ModelInfer() std::cout << "model input tensor num: " << model.GetInputTensorNum() << std::endl; std::cout << "model output tensor num: " << model.GetOutputTensorNum() << std::endl; - std::vector inShape64 = model.GetInputTensorShape(); // 获得模型输入的对应Tensor的数据shape信息。 + std::vector inShape64 = model.GetInputTensorShape(); // 获得模型输入的对应Tensor的数据shape信息 std::vector inShape; - std::cout<< "inputShape:"; - for (auto s: inShape64) { - std::cout<< " " << s ; - //使用查询的结果直接传入Tensor构造函数构造Tensor,需要将int64_t数据转换为uint32_t数据。 - inShape.push_back(static_cast(s)); + std::cout << "inputShape:"; + for (auto s : inShape64) { + std::cout << " " << s; + // 使用查询的结果直接传入Tensor构造函数构造Tensor,需要将int64_t数据转换为uint32_t数据 + inShape.push_back(static_cast(s)); } std::cout << std::endl; - TensorDType dtype = model.GetInputTensorDataType(0); // 获得模型输入的对应Tensor的数据类型信息。 + TensorDType dtype = model.GetInputTensorDataType(0); // 获得模型输入的对应Tensor的数据类型信息 std::vector input; // 输入 std::vector output; // 输出 for (size_t i = 0; i < model.GetOutputTensorNum(); i++) { - // 获得模型输出的对应Tensor的数据shape信息。查询的结果可直接传入Tensor构造函数用来构造Tensor。 - std::vector ouputShape = model.GetOutputTensorShape(i); - std::cout << "ouputShape: " ; - for (size_t j = 0; j < ouputShape.size(); ++j) { - std::cout << ouputShape[j] << " "; + // 获得模型输出的对应Tensor的数据shape信息 查询的结果可直接传入Tensor构造函数用来构造Tensor + std::vector outputShape = model.GetOutputTensorShape(i); + std::cout << "outputShape: " ; + for (size_t j = 0; j < outputShape.size(); ++j) { + std::cout << outputShape[j] << " "; } std::cout << std::endl; - MxBase::TensorDType outputDType = model.GetOutputTensorDataType(i); // 获得模型输出的对应Tensor的数据类型信息。 - Tensor dst(ouputShape, outputDType); + MxBase::TensorDType outputDType = model.GetOutputTensorDataType(i); // 获得模型输出的对应Tensor的数据类型信息 + Tensor dst(outputShape, outputDType); dst.Malloc(); dst.ToDevice(0); output.push_back(dst); diff --git a/tutorials/ModleSample/python/main.py b/tutorials/ModleSample/python/main.py index c029a521e..07ad8f866 100644 --- a/tutorials/ModleSample/python/main.py +++ b/tutorials/ModleSample/python/main.py @@ -21,7 +21,7 @@ def process(): print("output num:", model.output_num) # 获得模型的输出个数 input_shape_vector = model.input_shape(0) # 获得模型输入的对应Tensor的数据shape信息 - input_shape_list = list(input_shape_vector ) + input_shape_list = list(input_shape_vector) print("input Tensor shape list:", input_shape_list) output_shape_vector = model.output_shape(0) # 获得模型输出的对应Tensor的数据shape信息 @@ -32,7 +32,11 @@ def process(): print("Input dtype:", input_dtype) # 使用numpy生成输入数据 真实情况下读入图片进行推理也可以通过numpy转换为Tensor类型 - img = np.random.randint(0, 255, size=(input_shape_list[0], input_shape_list[1], input_shape_list[2], input_shape_list[3]), dtype=np.uint8).astype(np.float32) #这里的size根据模型输入的要求确定 + img = np.random.randint(\ + 0, 255, \ + size=(input_shape_list[0], input_shape_list[1], input_shape_list[2], input_shape_list[3]), \ + dtype=np.uint8\ + ).astype(np.float32) # 这里的size根据模型输入的要求确定 img = Tensor(img) # 将numpy转为转为Tensor类 output = model.infer([img]) # 执行推理。输入数据类型:List[base.Tensor], 返回模型推理输出的 List[base.Tensor] -- Gitee From 80b3386c1cdc4ae845a5092bbaf77d6a172c5d17 Mon Sep 17 00:00:00 2001 From: Ssayhi_w Date: Fri, 20 Dec 2024 15:40:58 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorials/ModleSample/C++/main.cpp | 1 - tutorials/ModleSample/python/main.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tutorials/ModleSample/C++/main.cpp b/tutorials/ModleSample/C++/main.cpp index 144f89eb7..49eedf0b8 100644 --- a/tutorials/ModleSample/C++/main.cpp +++ b/tutorials/ModleSample/C++/main.cpp @@ -25,7 +25,6 @@ #include "MxBase/Asynchron/AscendStream.h" using namespace MxBase; -using namespace std; std::string g_omModelPath = "../model/IAT_lol-sim.om"; // mindir模型路径 diff --git a/tutorials/ModleSample/python/main.py b/tutorials/ModleSample/python/main.py index 07ad8f866..fe4cb91d6 100644 --- a/tutorials/ModleSample/python/main.py +++ b/tutorials/ModleSample/python/main.py @@ -14,7 +14,7 @@ def process(): # 方式一 model = base.model(modelPath=model_path, deviceId=device_id) # 函数返回参数为Model对象 - # 方式二 + # 方式二 开发者也可尝试使用该方式构建Model,使用时注释15行 # model = Model(model_path, 0) # 直接使用Model类构造对象 print("input num:", model.input_num) # 获得模型的输入个数 -- Gitee From 880b7b08a18f7dd7591c47910e9e195f19b32616 Mon Sep 17 00:00:00 2001 From: Ssayhi_w Date: Fri, 20 Dec 2024 15:47:35 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorials/ModleSample/python/main.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tutorials/ModleSample/python/main.py b/tutorials/ModleSample/python/main.py index fe4cb91d6..1d3b1739c 100644 --- a/tutorials/ModleSample/python/main.py +++ b/tutorials/ModleSample/python/main.py @@ -21,12 +21,10 @@ def process(): print("output num:", model.output_num) # 获得模型的输出个数 input_shape_vector = model.input_shape(0) # 获得模型输入的对应Tensor的数据shape信息 - input_shape_list = list(input_shape_vector) - print("input Tensor shape list:", input_shape_list) + print("input Tensor shape list:", input_shape_vector) output_shape_vector = model.output_shape(0) # 获得模型输出的对应Tensor的数据shape信息 - output_shape_list = list(output_shape_vector) - print("output Tensor shape list:", output_shape_list) + print("output Tensor shape list:", output_shape_vector) input_dtype = model.input_dtype(0) print("Input dtype:", input_dtype) @@ -34,7 +32,7 @@ def process(): # 使用numpy生成输入数据 真实情况下读入图片进行推理也可以通过numpy转换为Tensor类型 img = np.random.randint(\ 0, 255, \ - size=(input_shape_list[0], input_shape_list[1], input_shape_list[2], input_shape_list[3]), \ + size=(input_shape_vector[0], input_shape_vector[1], input_shape_vector[2], input_shape_vector[3]), \ dtype=np.uint8\ ).astype(np.float32) # 这里的size根据模型输入的要求确定 img = Tensor(img) # 将numpy转为转为Tensor类 -- Gitee