diff --git "a/docs/quickStart/4-4\346\250\241\345\236\213Tensor\346\225\260\346\215\256\345\244\204\347\220\206&\350\207\252\345\256\232\344\271\211\346\250\241\345\236\213\345\220\216\345\244\204\347\220\206.md" "b/docs/quickStart/4-4\346\250\241\345\236\213Tensor\346\225\260\346\215\256\345\244\204\347\220\206&\350\207\252\345\256\232\344\271\211\346\250\241\345\236\213\345\220\216\345\244\204\347\220\206.md" deleted file mode 100644 index 2d705c404e8145463905eb5b6dd7a5b5ccdad919..0000000000000000000000000000000000000000 --- "a/docs/quickStart/4-4\346\250\241\345\236\213Tensor\346\225\260\346\215\256\345\244\204\347\220\206&\350\207\252\345\256\232\344\271\211\346\250\241\345\236\213\345\220\216\345\244\204\347\220\206.md" +++ /dev/null @@ -1,122 +0,0 @@ -# 模型Tensor数据处理&插件后处理 - -本章节将指导模型Tensor数据解析和封装相关操作。 -配套样例描述如何自定义一个插件进行后处理操作。 -**** -**注意!** -本样例中后处理指使用模型输出的原始metadata,自行开发插件来进行后处理。 -当类型为4-2中相关的内置类型时,效率不如后处理so库方式 -**** - -## medadata结构说明 -该结构为模型推理插件mxpi_tensorinfer输出的原始数据,按以下层级封装。 - -1. MxpiTensorPackageList -模型tensor组合列表。 -```protobuf -repeated MxpiTensorPackage tensorPackageVec; -``` -2. MxpiTensorPackage - -模型tensor组合数据结。 -```protobuf -repeated MxpiMetaHeader headerVec; -repeated MxpiTensor tensorVec; -``` -3. MxpiTensor - -模型tensor数据结构。 -```protobuf -uint64 tensorDataPtr; // 内存指针数值 -int32 tensorDataSize; // 内存大小,需要和实际内存大小一致,否则可能会导致coredump -uint32 deviceId; // Device编号 -MxpiMemoryType memType; // 内存类型 -uint64 freeFunc; // 内存销毁函数指针 -repeated int32 tensorShape; // 张量形状 -bytes dataStr; // 内存中的数据 -int32 tensorDataType; //内存中张量的数据类型 -``` - -## C++结构体说明 -该结构体为TensorBase数据结构相关说明,详情可参考TensorBase.h头文件。 -(位于%SDK%/include/MxBase/Tensor/TensorBase/) -本处仅摘抄部分关键信息 -```c++ -enum TensorDataType { - TENSOR_DTYPE_UNDEFINED = -1, - TENSOR_DTYPE_FLOAT32 = 0, - TENSOR_DTYPE_FLOAT16 = 1, - TENSOR_DTYPE_INT8 = 2, - TENSOR_DTYPE_INT32 = 3, - TENSOR_DTYPE_UINT8 = 4, - TENSOR_DTYPE_INT16 = 6, - TENSOR_DTYPE_UINT16 = 7, - TENSOR_DTYPE_UINT32 = 8, - TENSOR_DTYPE_INT64 = 9, - TENSOR_DTYPE_UINT64 = 10, - TENSOR_DTYPE_DOUBLE64 = 11, - TENSOR_DTYPE_BOOL = 12 -}; - // 获取tensor部署的设备类型 - MemoryData::MemoryType GetTensorType() const; - // buffer记录的数据量 - size_t GetSize() const; - // buffer 字节数据量 - size_t GetByteSize() const; - // tensor 的shape - std::vector GetShape() const; - std::vector GetStrides() const; - // tensor 的 device - int32_t GetDeviceId() const; - // tensor 数据类型 - TensorDataType GetDataType() const; - uint32_t GetDataTypeSize() const; - // 判断是否在Host - bool IsHost() const; - // 判断是否在Device - bool IsDevice() const; - // 获取tensor指针 - void* GetBuffer() const; - APP_ERROR GetBuffer(void *&ptr, const std::vector &indices) const; - // host to device - APP_ERROR ToDevice(int32_t deviceId); - // host to dvpp - APP_ERROR ToDvpp(int32_t deviceId); - // device to host - APP_ERROR ToHost(); - // 组batch相关 - static APP_ERROR BatchConcat(const std::vector &inputs, TensorBase &output); - static APP_ERROR BatchStack(const std::vector &inputs, TensorBase &output); - static APP_ERROR BatchVector(const std::vector &inputs, TensorBase &output, - const bool &keepDims = false); - // 详细信息 - std::string GetDesc(); - // 检查错误 - APP_ERROR CheckTensorValid() const; -``` -## 样例说明 -参考[4-1插件开发调试指导](4-1插件开发调试指导.md)部署自定义插件样例,示例使用samplePluginPostProc作为工程名,远程目录名同样为samplePluginPostProc。 -- 更改mxVision/C++/main.cpp中94行所使用的pipeline为样例中的SamplePluginPost.pipeline -- 更改mxVision/python/main.py中32行使用的pipeline为样例中的SamplePluginPost.pipeline -- 相比4-1样例中的SamplePlugin.pipeline,本样例中pipeline使用新后处理框架下的模型推理插件mxpi_tensorinfer输出原始Tensor至自定义插件并完成后处理示例。 ->该文件位于样例根目录,但代码中实际指向mxVision/pipeline文件夹下,这是为了与使用原有Sample.pipeline的样例统一目录。实际使用时复制pipeline文件或更改代码中的路径均可 - -**** -本样例部署测试同4-1,不再重复。 -**** -**运行结果** -1. C++样例 - ->使用菜单项Build/Rebuild All ....后运行该程序,如果无错误可在输出中看到类似的以下字段 其中MxpiSamplePlugin.cpp文件中的日志输出为插件内部结果,main.cpp日志输出为stream结果。此处tensor[0]相关值应该相同 -```shell -I0730 10:36:55.459653 11981 MxpiSamplePlugin.cpp:118] MxpiSamplePlugin::Process start -W0730 10:36:55.459954 11981 MxpiSamplePlugin.cpp:98] source Tensor number:3 -W0730 10:36:55.460223 11981 MxpiSamplePlugin.cpp:99] Tensor[0] ByteSize in .cpp:172380 -I0730 10:36:55.462554 11981 MxpiSamplePlugin.cpp:174] MxpiSamplePlugin::Process end -I0730 10:36:55.462568 11935 main.cpp:129] Results:{"MxpiClass":[{"classId":42,"className":"The shape of tensor[0] in metadata is 172380, Don’t panic!","confidence":0.314}]} -``` -2. Python样例 ->修改python样例目录下的run.sh脚本(该脚本用于配置环境变量),确认MX_SDK_HOME环境变量指向正确的位置,自定义插件路径已位于GST_PLUGIN_PATH中,或手动修改环境变量,然后执行程序。正常情况下输出以下类似字段 -```shell -{"MxpiClass":[{"classId":42,"className":"The shape of tensor[0] in metadata is 172380, Don’t panic!","confidence":0.314}]} -``` \ No newline at end of file diff --git a/tutorials/SamplePostProcess/src/samplepostprocess/README.md b/tutorials/SamplePostProcess/src/samplepostprocess/README.md new file mode 100644 index 0000000000000000000000000000000000000000..bdbe2398fc2a38a8200713ae17dde1440d881df1 --- /dev/null +++ b/tutorials/SamplePostProcess/src/samplepostprocess/README.md @@ -0,0 +1,8 @@ +# Resnset50样例 +本项目(tutorials\SamplePostProcess\src\samplepostprocess)构建了resnet50网络的新版后处理插件。 +## 继承类型 +>MxBase/PostProcessBases/ClassPostProcessBase.h +## 使用说明 +使用mxpi_classpostprocessor加载后处理so + +>参考https://support.huawei.com/enterprise/zh/doc/EDOC1100207069/4e71a146 \ No newline at end of file diff --git a/tutorials/SamplePostProcess/src/vggpostprocess/CMakeLists.txt b/tutorials/SamplePostProcess/src/vggpostprocess/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b6c01eb54a60c62f0a1234d13640d6093fac5333 --- /dev/null +++ b/tutorials/SamplePostProcess/src/vggpostprocess/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.5.2) +project(vggpostprocess) + +add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0 -Dgoogle=mindxsdk_private) + +set(PLUGIN_NAME "vggpostprocess") +set(TARGET_LIBRARY ${PLUGIN_NAME}) +set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../../lib) + +include_directories(${MX_SDK_HOME}/include) +include_directories(${MX_SDK_HOME}/opensource/include) +include_directories(${MX_SDK_HOME}/opensource/include/gstreamer-1.0) +include_directories(${MX_SDK_HOME}/opensource/include/glib-2.0) +include_directories(${MX_SDK_HOME}/opensource/lib/glib-2.0/include) + +link_directories(${MX_SDK_HOME}/opensource/lib) +link_directories(${MX_SDK_HOME}/lib) + +add_compile_options(-std=c++11 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations) +add_compile_options("-DPLUGIN_NAME=${PLUGIN_NAME}") + +add_definitions(-DENABLE_DVPP_INTERFACE) +add_library(${TARGET_LIBRARY} SHARED vggPostProcess.cpp vggPostProcess.h) + +target_link_libraries(${TARGET_LIBRARY} glib-2.0 gstreamer-1.0 gobject-2.0 gstbase-1.0 gmodule-2.0 glog) +target_link_libraries(${TARGET_LIBRARY} plugintoolkit mxpidatatype mxbase) +#target_link_libraries(${TARGET_LIBRARY} -Wl,-z,relro,-z,now,-z,noexecstack -s) diff --git a/tutorials/SamplePostProcess/src/vggpostprocess/README.md b/tutorials/SamplePostProcess/src/vggpostprocess/README.md new file mode 100644 index 0000000000000000000000000000000000000000..dd9f9c575b8e1b225e20a14225241e98372e125f --- /dev/null +++ b/tutorials/SamplePostProcess/src/vggpostprocess/README.md @@ -0,0 +1,8 @@ +# ssdvgg样例 +本项目(tutorials\SamplePostProcess\src\vggpostprocess)构建了vggpostprocess网络的新版后处理插件。 +## 继承类型 +>MxBase/PostProcessBases/ObjectPostProcessBase.h +## 使用说明 +需补完后处理中tensor检查和object处理逻辑部分,使用mxpi_objectpostprocessor加载后处理so + +>参考https://support.huawei.com/enterprise/zh/doc/EDOC1100207069/397691d0 \ No newline at end of file diff --git a/tutorials/SamplePostProcess/src/vggpostprocess/vggPostProcess.cpp b/tutorials/SamplePostProcess/src/vggpostprocess/vggPostProcess.cpp new file mode 100644 index 0000000000000000000000000000000000000000..987cc487405681a5ab8a62c9ed4ce5d6bf79198c --- /dev/null +++ b/tutorials/SamplePostProcess/src/vggpostprocess/vggPostProcess.cpp @@ -0,0 +1,115 @@ +/* + * Copyright(C) 2020. 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 "VggPostProcess.h" +#include "MxBase/Log/Log.h" + +namespace { +/// need manunel set +} +namespace MxBase { + VggPostProcess &VggPostProcess::operator=(const VggPostProcess &other) { + if (this == &other) { + return *this; + } + ObjectPostProcessBase::operator=(other); + return *this; + } + + APP_ERROR VggPostProcess::Init(const std::map > &postConfig) { + LogDebug << "Start to Init VggPostProcess."; + APP_ERROR ret = ObjectPostProcessBase::Init(postConfig); + if (ret != APP_ERR_OK) { + LogError << GetError(ret) << "Fail to superInit in ObjectPostProcessBase."; + return ret; + } + LogDebug << "End to Init VggPostProcess."; + return APP_ERR_OK; + } + + APP_ERROR VggPostProcess::DeInit() { + return APP_ERR_OK; + } + + bool VggPostProcess::IsValidTensors(const std::vector &tensors) const { + /// need write check + } + + void VggPostProcess::ObjectDetectionOutput(const std::vector &tensors, + std::vector > &objectInfos, + const std::vector &resizedImageInfos) { + LogDebug << "VggPostProcess start to write results."; + for (auto num : {objectNumTensor_,objectInfoTensor_}) { + if ((num >= tensors.size()) || (num <0)) { + LogError << GetError(APP_ERR_INVALID_PARAM) << "TENSOR(" << num + << ") must ben less than tensors'size(" << tensors.size() << ") and larger than 0."; + } + } + uint32_t batchSize = tensors[objectNumTensor_].GetShape()[0]; + for (uint32_t i = 0; i < batchSize; i++) { + std::vector objectInfo; + int* objectNumPtr = (int*)GetBuffer(tensors[objectInfoTensor_],i); + float* objectInfoPtr = (float*)GetBuffer(tensors[objectInfoTensor_],i); + for (int j = 0; j< *objectNumPtr; j++) { + ObjectInfo objInfo; + /// need write objInfo + } + } + objectInfos.push_back(objectInfo); + } + LogDebug << "VggPostProcess write results successed."; + } + + APP_ERROR VggPostProcess::Process(const std::vector &tensors, + std::vector > &objectInfos, + const std::vector &resizedImageInfos, + const std::map > ¶mMap) { + LogDebug << "Start to Process VggPostProcess."; + APP_ERROR ret = APP_ERR_OK; + if (resizedImageInfos.size() == 0) { + ret = APP_ERR_INPUT_NOT_MATCH; + LogError << GetError(ret) << "resizedImageInfos is not provided which is necessary for VggPostProcess."; + return ret; + } + auto inputs = tensors; + ret = CheckAndMoveTensors(inputs); + if (ret != APP_ERR_OK) { + LogError << GetError(ret) << "CheckAndMoveTensors failed."; + return ret; + } + + ObjectDetectionOutput(inputs, objectInfos, resizedImageInfos); + + for (uint32_t i = 0; i < resizedImageInfos.size(); i++) { + CoordinatesReduction(i, resizedImageInfos[i], objectInfos[i]); + } + LogObjectInfos(objectInfos); + LogDebug << "End to Process VggPostProcess."; + return APP_ERR_OK; + } + + extern "C" { + std::shared_ptr GetObjectInstance() { + LogInfo << "Begin to get VggPostProcess instance."; + auto instance = std::make_shared(); + if (instance - nullptr) { + LogError << "Creat VggPostProcess object failed. Failed to allocate memory."; + } + LogInfo << "End to get VggPostProcess instance."; + return instance; + } + } +} \ No newline at end of file diff --git a/tutorials/SamplePostProcess/src/vggpostprocess/vggPostProcess.h b/tutorials/SamplePostProcess/src/vggpostprocess/vggPostProcess.h new file mode 100644 index 0000000000000000000000000000000000000000..f60f6f9e6bed52eb62ae1620efd9724955086048 --- /dev/null +++ b/tutorials/SamplePostProcess/src/vggpostprocess/vggPostProcess.h @@ -0,0 +1,62 @@ +/* + * Copyright(C) 2020. 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. + */ + +#ifndef VGG_POST_PROCESS_H +#define VGG_POST_PROCESS_H +#include "MxBase/PostProcessBases/ObjectPostProcessBase.h" + +namespace { +const int DEFAULT_OBJECT_NUM_TENSOR = 0; +const int DEFAULT_OBJECT_INFO_TENSOR = 1; +} + +namespace MxBase { + class VggPostProcess{ + + public: + VggPostProcess() = default; + + ~VggPostProcess() = default; + + VggPostProcess(const VggPostProcess &other) = default; + + VggPostProcess &operator=(const VggPostProcess &other); + + APP_ERROR Init(const std::map > &postConfig) override; + + APP_ERROR DeInit() override; + + APP_ERROR Process(const std::vector &tensors, + std::vector > &objectInfos, + const std::vector &resizedImageInfos = {}, + const std::map > ¶mMap = {}) override; + + protected: + bool IsValidTensors(const std::vector &tensors) const override; + + void ObjectDetectionOutput(const std::vector &tensors, + std::vector > &objectInfos, + const std::vector &resizedImageInfos = {}); + private: + uint32_t objectNumTensor_ = DEFAULT_OBJECT_NUM_TENSOR; + uint32_t objectInfoTensor_ = DEFAULT_OBJECT_INFO_TENSOR; + + }; + extern "C" { + std::shared_ptr GetObjectInstance(); + } +} +#endif \ No newline at end of file diff --git a/tutorials/SamplePostProcess/src/yolov3/README.md b/tutorials/SamplePostProcess/src/yolov3/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5f0af5c0c45a0d9df635735b8b23a3b877360e0e --- /dev/null +++ b/tutorials/SamplePostProcess/src/yolov3/README.md @@ -0,0 +1,9 @@ +# yolov3样例 + +本项目(tutorials\SamplePostProcess\src\yolov3)构建了yolov3网络的新版后处理插件。 +## 继承类型 +>MxBase/PostProcessBases/ObjectPostProcessBase.h +## 使用说明 +使用mxpi_objectpostprocessor加载后处理so + +>参考https://support.huawei.com/enterprise/zh/doc/EDOC1100207069/397691d0 \ No newline at end of file diff --git a/tutorials/SamplePostProcess/src/yolov3/Yolov3PostProcess.h b/tutorials/SamplePostProcess/src/yolov3/Yolov3PostProcess.h index 9e7db513caf64b1a01650b16fb692ddb114b1318..30f847794e46a59548757e73f78ccf16a5f38f82 100644 --- a/tutorials/SamplePostProcess/src/yolov3/Yolov3PostProcess.h +++ b/tutorials/SamplePostProcess/src/yolov3/Yolov3PostProcess.h @@ -45,7 +45,7 @@ struct NetInfo { } namespace MxBase { - class Yolov3PostProcess{ + class Yolov3PostProcess: public ObjectPostProcessBase{ public: Yolov3PostProcess() = default;