Skip to content
Snippets Groups Projects
Commit 9cbc637d authored by i-robot's avatar i-robot Committed by Gitee
Browse files

!313 [南开大学][高校贡献][Mindspore][openpose]-高性能预训练模型提交

Merge pull request !313 from dengqian06/mindx_openpose
parents 683aa26c a996ccba
No related branches found
No related tags found
No related merge requests found
Showing
with 2612 additions and 0 deletions
ARG FROM_IMAGE_NAME
FROM ${FROM_IMAGE_NAME}
RUN ln -s /usr/local/python3.7.5/bin/python3.7 /usr/bin/python
COPY sdk/requirements.txt .
RUN pip3.7 install
aipp_op {
related_input_rank: 0
src_image_size_w: 560
src_image_size_h: 560
crop: false
input_format: YUV420SP_U8
aipp_mode: static
csc_switch: true
rbuv_swap_switch: false
matrix_r0c0: 256
matrix_r0c1: 454
matrix_r0c2: 0
matrix_r1c0: 256
matrix_r1c1: -88
matrix_r1c2: -183
matrix_r2c0: 256
matrix_r2c1: 0
matrix_r2c2: 359
input_bias_0: 0
input_bias_1: 128
input_bias_2: 128
mean_chn_0: 128
mean_chn_1: 128
mean_chn_2: 128
min_chn_0: 0.0
min_chn_1: 0.0
min_chn_2: 0.0
var_reci_chn_0: 0.00390625
var_reci_chn_1: 0.00390625
var_reci_chn_2: 0.00390625
}
\ No newline at end of file
#!/bin/bash
# Copyright 2021 Huawei Technologies Co., Ltd
#
# 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.
# ============================================================================
if [ $# -ne 3 ]
then
echo "Wrong parameter format."
echo "Usage:"
echo " bash $0 [INPUT_AIR_PATH] [AIPP_PATH] [OUTPUT_OM_PATH_NAME]"
echo "Example: "
echo " bash convert_om.sh xxx.air ./aipp.cfg xx"
exit 1
fi
input_air_path=$1
aipp_cfg_file=$2
output_om_path=$3
echo "Input AIR file path: ${input_air_path}"
echo "Output OM file path: ${output_om_path}"
atc --input_format=NCHW \
--framework=1 \
--model="${input_air_path}" \
--output="${output_om_path}" \
--insert_op_conf="${aipp_cfg_file}" \
--soc_version=Ascend310
\ No newline at end of file
#!/bin/bash
# Copyright 2021 Huawei Technologies Co., Ltd
#
# 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.
docker_image=$1
share_dir=$2
echo "$1"
echo "$2"
if [ -z "${docker_image}" ]; then
echo "please input docker_image"
exit 1
fi
if [ ! -d "${share_dir}" ]; then
echo "please input share directory that contains dataset, models and codes"
exit 1
fi
docker run -it \
--device=/dev/davinci0 \
--device=/dev/davinci_manager \
--device=/dev/devmm_svm \
--device=/dev/hisi_hdc \
--privileged \
-v //usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v ${share_dir}:${share_dir} \
${docker_image} \
/bin/bash
cmake_minimum_required(VERSION 3.5.2)
project(openposepost)
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
set(TARGET_LIBRARY openpose_mindspore_post)
set(TARGET_MAIN openpose_mindspore)
set(ACL_LIB_PATH $ENV{ASCEND_HOME}/nnrt/latest/acllib)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories($ENV{MX_SDK_HOME}/include)
include_directories($ENV{MX_SDK_HOME}/opensource/include)
include_directories($ENV{MX_SDK_HOME}/opensource/include/opencv4)
include_directories($ENV{MX_SDK_HOME}/opensource/include/boost)
include_directories($ENV{MX_SDK_HOME}/opensource/include/gstreamer-1.0)
include_directories($ENV{MX_SDK_HOME}/opensource/include/glib-2.0)
include_directories($ENV{MX_SDK_HOME}/opensource/lib)
include_directories($ENV{MX_SDK_HOME}/opensource/lib/glib-2.0/include)
include_directories(${PROJECT_SOURCE_DIR}/../proto)
link_directories($ENV{MX_SDK_HOME}/lib)
link_directories($ENV{MX_SDK_HOME}/opensource/lib/)
link_directories(${PROJECT_SOURCE_DIR}/../proto/lib)
add_compile_options(-std=c++11 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations)
add_compile_options("-DPLUGIN_NAME=${PLUGIN_NAME}")
add_compile_options("-Dgoogle=mindxsdk_private")
add_definitions(-DENABLE_DVPP_INTERFACE)
include_directories(${ACL_LIB_PATH}/include)
link_directories(${ACL_LIB_PATH}/lib64/)
add_library(${TARGET_LIBRARY} SHARED src/PostProcess/OpenPoseMindsporePost.cpp)
target_link_libraries(${TARGET_LIBRARY} glib-2.0 gstreamer-1.0 gobject-2.0 gstbase-1.0 gmodule-2.0)
target_link_libraries(${TARGET_LIBRARY} plugintoolkit mxpidatatype mxbase mxpiopenposeproto)
target_link_libraries(${TARGET_LIBRARY} -Wl,-z,relro,-z,now,-z,noexecstack -s)
message("TARGET_LIBRARY:${TARGET_LIBRARY}.")
add_executable(${TARGET_MAIN} src/main.cpp src/OpenPose.cpp)
target_link_libraries(${TARGET_MAIN} ${TARGET_LIBRARY} glog cpprest opencv_world mxbase libascendcl.so)
#!/bin/bash
# Copyright 2021 Huawei Technologies Co., Ltd
#
# 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.
# ============================================================================
# env
mkdir -p build
cd build || exit
function make_plugin() {
if ! cmake ..;
then
echo "cmake failed."
return 1
fi
if ! (make);
then
echo "make failed."
return 1
fi
return 0
}
if make_plugin;
then
echo "INFO: Build successfully."
else
echo "ERROR: Build failed."
fi
cd - || exit
/*
* Copyright (c) 2021. 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 <memory>
#include <algorithm>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <opencv4/opencv2/core.hpp>
#include <opencv4/opencv2/opencv.hpp>
#include <opencv4/opencv2/highgui.hpp>
#include <opencv4/opencv2/imgproc.hpp>
#include "acl/acl.h"
#include "MxBase/DeviceManager/DeviceManager.h"
#include "MxBase/Log/Log.h"
#include "OpenPose.h"
using namespace MxBase;
namespace {
const uint32_t YUV_BYTE_NU = 3;
const uint32_t YUV_BYTE_DE = 2;
const uint32_t MODEL_HEIGHT = 560;
const uint32_t MODEL_WIDTH = 560;
const int NPOINTS = 18;
} // namespace
void PrintTensorShape(const std::vector<TensorDesc> &tensorDescVec, const std::string &tensorName) {
LogInfo << "The shape of " << tensorName << " is as follows:";
for (size_t i = 0; i < tensorDescVec.size(); ++i) {
LogInfo << " Tensor " << i << ":";
for (size_t j = 0; j < tensorDescVec[i].tensorDims.size(); ++j) {
LogInfo << " dim: " << j << ": " << tensorDescVec[i].tensorDims[j];
}
}
}
APP_ERROR OpenPose::Init(const InitParam &initParam) {
deviceId_ = initParam.deviceId;
APP_ERROR ret = MxBase::DeviceManager::GetInstance()->InitDevices();
if (ret != APP_ERR_OK) {
LogError << "Init devices failed, ret=" << ret << ".";
return ret;
}
ret = MxBase::TensorContext::GetInstance()->SetContext(initParam.deviceId);
if (ret != APP_ERR_OK) {
LogError << "Set context failed, ret=" << ret << ".";
return ret;
}
dvppWrapper_ = std::make_shared<MxBase::DvppWrapper>();
ret = dvppWrapper_->Init();
if (ret != APP_ERR_OK) {
LogError << "DvppWrapper init failed, ret=" << ret << ".";
return ret;
}
model_ = std::make_shared<MxBase::ModelInferenceProcessor>();
ret = model_->Init(initParam.modelPath, modelDesc_);
if (ret != APP_ERR_OK) {
LogError << "ModelInferenceProcessor init failed, ret=" << ret << ".";
return ret;
}
PrintTensorShape(modelDesc_.inputTensors, "Model Input Tensors");
PrintTensorShape(modelDesc_.outputTensors, "Model Output Tensors");
post_ = std::make_shared<MxBase::OpenPoseMindsporePost>();
return APP_ERR_OK;
}
APP_ERROR OpenPose::DeInit() {
dvppWrapper_->DeInit();
model_->DeInit();
MxBase::DeviceManager::GetInstance()->DestroyDevices();
return APP_ERR_OK;
}
APP_ERROR OpenPose::ReadImage(const std::string &imgPath, MxBase::DvppDataInfo *output, ImageShape *imgShape) {
APP_ERROR ret = dvppWrapper_->DvppJpegDecode(imgPath, *output);
if (ret != APP_ERR_OK) {
LogError << "DvppWrapper DvppJpegDecode failed, ret=" << ret << ".";
return ret;
}
imgShape->width = output->width;
imgShape->height = output->height;
return APP_ERR_OK;
}
APP_ERROR OpenPose::Resize(const MxBase::DvppDataInfo &input, MxBase::TensorBase *outputTensor) {
MxBase::CropRoiConfig cropRoi = {0, input.width, input.height, 0};
float ratio =
std::min(static_cast<float>(MODEL_WIDTH) / input.width, static_cast<float>(MODEL_HEIGHT) / input.height);
MxBase::CropRoiConfig pasteRoi = {0, 0, 0, 0};
pasteRoi.x1 = input.width * ratio;
pasteRoi.y1 = input.height * ratio;
MxBase::MemoryData memoryData(MODEL_WIDTH * MODEL_HEIGHT * YUV_BYTE_NU / YUV_BYTE_DE,
MemoryData::MemoryType::MEMORY_DVPP, deviceId_);
APP_ERROR ret = MxBase::MemoryHelper::MxbsMalloc(memoryData);
if (ret != APP_ERR_OK) {
LogError << "Fail to allocate dvpp memory.";
MemoryHelper::MxbsFree(memoryData);
return APP_ERR_COMM_INVALID_PARAM;
}
ret = MxBase::MemoryHelper::MxbsMemset(memoryData, 0, memoryData.size);
if (ret != APP_ERR_OK) {
LogError << "Fail to set 0.";
MemoryHelper::MxbsFree(memoryData);
return APP_ERR_COMM_INVALID_PARAM;
}
MxBase::DvppDataInfo output = {};
output.dataSize = memoryData.size;
output.width = MODEL_WIDTH;
output.height = MODEL_HEIGHT;
output.widthStride = MODEL_WIDTH;
output.heightStride = MODEL_HEIGHT;
output.format = input.format;
output.data = static_cast<uint8_t *>(memoryData.ptrData);
ret = dvppWrapper_->VpcCropAndPaste(input, output, pasteRoi, cropRoi);
if (ret != APP_ERR_OK) {
LogError << "VpcCropAndPaste failed, ret=" << ret << ".";
return ret;
}
std::vector<uint32_t> shape = {output.heightStride * YUV_BYTE_NU / YUV_BYTE_DE, output.widthStride};
*outputTensor = TensorBase(memoryData, false, shape, TENSOR_DTYPE_UINT8);
return APP_ERR_OK;
}
APP_ERROR OpenPose::Inference(const std::vector<MxBase::TensorBase> &inputs,
std::vector<MxBase::TensorBase> *outputs) {
auto dtypes = model_->GetOutputDataType();
for (size_t i = 0; i < modelDesc_.outputTensors.size(); ++i) {
std::vector<uint32_t> shape = {};
for (size_t j = 0; j < modelDesc_.outputTensors[i].tensorDims.size(); ++j) {
shape.push_back((uint32_t)modelDesc_.outputTensors[i].tensorDims[j]);
}
TensorBase tensor(shape, dtypes[i], MemoryData::MemoryType::MEMORY_DEVICE, deviceId_);
APP_ERROR ret = TensorBase::TensorBaseMalloc(tensor);
if (ret != APP_ERR_OK) {
LogError << "TensorBaseMalloc failed, ret=" << ret << ".";
return ret;
}
outputs->push_back(tensor);
}
DynamicInfo dynamicInfo = {};
dynamicInfo.dynamicType = DynamicType::STATIC_BATCH;
dynamicInfo.batchSize = 1;
APP_ERROR ret = model_->ModelInference(inputs, *outputs, dynamicInfo);
if (ret != APP_ERR_OK) {
LogError << "ModelInference failed, ret=" << ret << ".";
return ret;
}
return APP_ERR_OK;
}
APP_ERROR OpenPose::PostProcess(const std::vector<MxBase::TensorBase> &inputs,
const std::vector<int> &vision_infos,
std::vector<std::vector<PartPair> > *person_list) {
APP_ERROR ret = post_->selfProcess(inputs, vision_infos, person_list);
if (ret != APP_ERR_OK) {
LogError << "Process failed, ret=" << ret << ".";
return ret;
}
return APP_ERR_OK;
}
APP_ERROR OpenPose::GetInferResults(const std::string &imgPath, const std::vector<std::vector<PartPair> > &person_list,
const std::string &resultPath) {
std::string fileName = imgPath.substr(imgPath.find_last_of("/") + 1);
size_t dot = fileName.find_last_of(".");
std::string resFileName = resultPath + fileName.substr(0, dot) + "_1.txt";
std::ofstream outfile(resFileName);
if (outfile.fail()) {
LogError << "Failed to open result file: ";
return APP_ERR_COMM_FAILURE;
}
std::vector<std::vector<float> > coco_keypoints;
std::vector<float> scores;
float coor_bias = 0.5;
float float_equal_zero_bias = 0.000001;
for (int k = 0; k < person_list.size(); k++) {
float person_score = post_->PersonScore(person_list[k]);
// Ignore person with score 0
if (fabs(person_score - 0) < float_equal_zero_bias) {
continue;
}
person_score = person_score - 1;
std::vector<float> keypoints(17*3, 0.0);
int to_coco_map[] = {0, -1, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3};
std::set<int> seen_idx = {1};
for (int j = 0; j < person_list[k].size(); j++) {
PartPair skele = person_list[k][j];
int part_idx1 = skele.partIdx1;
// two end points of a skeleton
int part_idx2 = skele.partIdx2;
if (seen_idx.count(part_idx1) == 0) {
float center_x = skele.coord1[0] + coor_bias;
float center_y = skele.coord1[1] + coor_bias;
keypoints[to_coco_map[part_idx1] * 3 + 0] = center_x;
keypoints[to_coco_map[part_idx1] * 3 + 1] = center_y;
keypoints[to_coco_map[part_idx1] * 3 + 2] = 1;
seen_idx.insert(part_idx1);
}
if (seen_idx.count(part_idx2) == 0) {
float center_x = skele.coord2[0] + coor_bias;
float center_y = skele.coord2[1] + coor_bias;
keypoints[to_coco_map[part_idx2] * 3 + 0] = center_x;
keypoints[to_coco_map[part_idx2] * 3 + 1] = center_y;
keypoints[to_coco_map[part_idx2] * 3 + 2] = 1;
seen_idx.insert(part_idx2);
}
}
coco_keypoints.push_back(keypoints);
scores.push_back(person_score);
std::string resultStr;
resultStr += "[";
std::cout << "keypoints: [";
int i = 0;
for (i = 0; i < keypoints.size()-1; i++) {
resultStr += std::to_string(keypoints[i]) + ",";
}
resultStr += "]";
outfile << resultStr << std::endl;
resultStr = "person_score: ";
resultStr += std::to_string(person_score);
outfile << resultStr << std::endl;
}
outfile.close();
return APP_ERR_OK;
}
void OpenPose::DrawPoseBbox(const std::string &imgPath, const std::vector<std::vector<PartPair> > &person_list,
const std::string &resultPath) {
std::vector<std::vector<int> > COCO_PAIRS_RENDER = {std::vector<int>{1, 2}, std::vector<int>{1, 5},
std::vector<int>{2, 3}, std::vector<int>{3, 4}, std::vector<int>{5, 6}, std::vector<int>{6, 7},
std::vector<int>{1, 8}, std::vector<int>{8, 9}, std::vector<int>{9, 10}, std::vector<int>{1, 11},
std::vector<int>{11, 12}, std::vector<int>{12, 13}, std::vector<int>{1, 0}, std::vector<int>{0, 14},
std::vector<int>{14, 16}, std::vector<int>{0, 15}, std::vector<int>{15, 17}}; // = 19
std::vector<cv::Scalar> COCO_COLORS = {cv::Scalar(255, 0, 0), cv::Scalar(255, 85, 0), cv::Scalar(255, 170, 0),
cv::Scalar(255, 255, 0), cv::Scalar(170, 255, 0), cv::Scalar(85, 255, 0), cv::Scalar(0, 255, 0),
cv::Scalar(0, 255, 85), cv::Scalar(0, 255, 170), cv::Scalar(0, 255, 255), cv::Scalar(0, 170, 255),
cv::Scalar(0, 85, 255), cv::Scalar(0, 0, 255), cv::Scalar(85, 0, 255), cv::Scalar(170, 0, 255),
cv::Scalar(255, 0, 255), cv::Scalar(255, 0, 170), cv::Scalar(255, 0, 85)};
cv::Mat imageMat = cv::imread(imgPath, cv::IMREAD_COLOR);
for (int k = 0; k < person_list.size(); k++) {
std::map<int, cv::Point> centers;
std::set<int> seen_idx;
for (int j = 0; j < person_list[k].size(); j++) {
PartPair skele = person_list[k][j];
// two end points of a skeleton
int part_idx1 = skele.partIdx1;
int part_idx2 = skele.partIdx2;
if (seen_idx.count(part_idx1) == 0) {
cv::Point center;
center.x = static_cast<int>(skele.coord1[0]);
center.y = static_cast<int>(skele.coord1[1]);
centers[part_idx1] = center;
cv::circle(imageMat, center, 3, COCO_COLORS[part_idx1], -1, cv::LINE_AA);
seen_idx.insert(part_idx1);
}
if (seen_idx.count(part_idx2) == 0) {
cv::Point center;
center.x = static_cast<int>(skele.coord2[0]);
center.y = static_cast<int>(skele.coord2[1]);
centers[part_idx2] = center;
cv::circle(imageMat, center, 3, COCO_COLORS[part_idx2], -1, cv::LINE_AA);
seen_idx.insert(part_idx2);
}
}
for (int i = 0; i < COCO_PAIRS_RENDER.size(); i++) {
std::vector<int> pair = COCO_PAIRS_RENDER[i];
if ((seen_idx.count(pair[0]) != 0) && (seen_idx.count(pair[1]) != 0))
cv::line(imageMat, centers[pair[0]], centers[pair[1]], COCO_COLORS[i], 2, cv::LINE_AA);
}
}
std::string fileName = imgPath.substr(imgPath.find_last_of("/") + 1);
size_t dot = fileName.find_last_of(".");
std::string resFileName = resultPath + fileName.substr(0, dot) + "_detect_result.jpg";
cv::imwrite(resFileName, imageMat);
}
APP_ERROR OpenPose::Process(const std::string &imgPath, const std::string &resultPath) {
ImageShape imageShape{};
MxBase::DvppDataInfo dvppData = {};
APP_ERROR ret = ReadImage(imgPath, &dvppData, &imageShape);
if (ret != APP_ERR_OK) {
LogError << "ReadImage failed, ret=" << ret << ".";
return ret;
}
TensorBase resizeImage;
ret = Resize(dvppData, &resizeImage);
if (ret != APP_ERR_OK) {
LogError << "Resize failed, ret=" << ret << ".";
return ret;
}
std::vector<int> vision_infos;
vision_infos.push_back(imageShape.height);
vision_infos.push_back(imageShape.width);
vision_infos.push_back(MODEL_HEIGHT);
vision_infos.push_back(MODEL_WIDTH);
std::vector<MxBase::TensorBase> inputs = {};
std::vector<MxBase::TensorBase> outputs = {};
inputs.push_back(resizeImage);
ret = Inference(inputs, &outputs);
if (ret != APP_ERR_OK) {
LogError << "Inference failed, ret=" << ret << ".";
return ret;
}
LogInfo << "Inference success, ret=" << ret << ".";
std::vector<std::vector<PartPair> > person_list {};
ret = PostProcess(outputs, vision_infos, &person_list);
if (ret != APP_ERR_OK) {
LogError << "PostProcess failed, ret=" << ret << ".";
return ret;
}
// Get keypoints and person_score info.
ret = GetInferResults(imgPath, person_list, resultPath);
if (ret != APP_ERR_OK) {
LogError << "Save infer results into file failed. ret = " << ret << ".";
return ret;
}
// Visualize the postprocess results.
DrawPoseBbox(imgPath, person_list, resultPath);
return APP_ERR_OK;
}
/*
* Copyright (c) 2021. 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 OPENPOSEPOST_OPENPOSE_H
#define OPENPOSEPOST_OPENPOSE_H
#include <vector>
#include <string>
#include <memory>
#include "MxBase/DvppWrapper/DvppWrapper.h"
#include "MxBase/ModelInfer/ModelInferenceProcessor.h"
#include "MxBase/PostProcessBases/ObjectPostProcessBase.h"
#include "MxBase/Tensor/TensorContext/TensorContext.h"
#include "PostProcess/OpenPoseMindsporePost.h"
#include "MxBase/DeviceManager/DeviceManager.h"
struct InitParam {
uint32_t deviceId;
std::string labelPath;
uint32_t classNum;
bool checkTensor;
std::string modelPath;
};
struct ImageShape {
int width;
int height;
};
class OpenPose {
public:
APP_ERROR Init(const InitParam &initParam);
APP_ERROR DeInit();
APP_ERROR ReadImage(const std::string &imgPath, MxBase::DvppDataInfo *output, ImageShape *imgShape);
APP_ERROR Resize(const MxBase::DvppDataInfo &input, MxBase::TensorBase *outputTensor);
APP_ERROR Inference(const std::vector<MxBase::TensorBase> &inputs, std::vector<MxBase::TensorBase> *outputs);
APP_ERROR PostProcess(const std::vector<MxBase::TensorBase> &inputs, const std::vector<int> &vision_infos,
std::vector<std::vector<PartPair> > *person_list);
APP_ERROR Process(const std::string &imgPath, const std::string &resultPath);
APP_ERROR GetInferResults(const std::string &imgPath, const std::vector<std::vector<PartPair> > &person_list,
const std::string &resultPath);
void DrawPoseBbox(const std::string &imgPath, const std::vector<std::vector<PartPair> > &person_list,
const std::string &resultPath);
private:
std::shared_ptr<MxBase::DvppWrapper> dvppWrapper_;
std::shared_ptr<MxBase::ModelInferenceProcessor> model_;
std::shared_ptr<MxBase::OpenPoseMindsporePost> post_;
MxBase::ModelDesc modelDesc_;
uint32_t deviceId_ = 1;
};
#endif // FASTERRCNNPOST_FASTERRCNN_H
/*
* Copyright (c) 2021. 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 OPENPOSEPOSTPROCESS_OPENPOSEPOSTPROCESS_H
#define OPENPOSEPOSTPROCESS_OPENPOSEPOSTPROCESS_H
#include <vector>
#include "MxTools/PluginToolkit/base/MxPluginGenerator.h"
#include "MxTools/PluginToolkit/base/MxPluginBase.h"
#include "MxTools/PluginToolkit/metadata/MxpiMetadataManager.h"
#include "MxTools/Proto/MxpiDataType.pb.h"
#include "MxBase/ErrorCode/ErrorCode.h"
#include "MxBase/PostProcessBases/PostProcessBase.h"
#include "MxBase/PostProcessBases/ObjectPostProcessBase.h"
#include "mxpiOpenposeProto.pb.h"
#include "opencv4/opencv2/opencv.hpp"
struct PartPair {
float score;
int partIdx1;
int partIdx2;
int idx1;
int idx2;
std::vector<float> coord1;
std::vector<float> coord2;
float score1;
float score2;
};
namespace MxBase {
class OpenPoseMindsporePost : public ObjectPostProcessBase {
public:
OpenPoseMindsporePost() = default;
~OpenPoseMindsporePost() = default;
OpenPoseMindsporePost(const OpenPoseMindsporePost &other) = default;
OpenPoseMindsporePost &operator=(const OpenPoseMindsporePost &other);
APP_ERROR selfProcess(const std::vector<TensorBase> &tensors,
const std::vector<int> &vision_infos, std::vector<std::vector<PartPair> > *person_list);
void GeneratePersonList(const std::vector<TensorBase> &tensors,
const std::vector<int> &vision_infos, std::vector<std::vector<PartPair> > *person_list);
void ResizeHeatmaps(const std::vector<int> &vision_infos, std::vector<cv::Mat> *keypoint_heatmap,
std::vector<cv::Mat > *paf_heatmap);
void ExtractKeypoints(const std::vector<cv::Mat> &keypoint_heatmap,
std::vector<std::vector<cv::Point> > *coor, std::vector<std::vector<float> > *coor_score);
void GroupKeypoints(const std::vector<cv::Mat>& paf_heatmap, const std::vector<std::vector<cv::Point> > &coor,
const std::vector<std::vector<float> > &coor_score, std::vector<std::vector<PartPair> > *person_list);
void ScoreSkeletons(const int part_idx, const std::vector<std::vector<cv::Point> > &coor,
const std::vector<std::vector<float> > &coor_score, const std::vector<cv::Mat> &paf_heatmap,
std::vector<PartPair> *connections);
std::vector<float> OneSkeletonScore(const cv::Mat &paf_x, const cv::Mat &paf_y,
const std::vector<cv::Point> &endpoints);
void ConntectionNms(std::vector<PartPair> *src, std::vector<PartPair> *dst);
bool MergeSkeletonToPerson(std::vector<std::vector<PartPair> > *person_list, PartPair current_pair);
float PersonScore(const std::vector<PartPair> &person);
};
#endif // OpenPose_MINSPORE_PORT_H
} // namespace MxBase
/*
* Copyright (c) 2021. 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 "OpenPose.h"
#include "MxBase/Log/Log.h"
namespace {
const uint32_t DEVICE_ID = 0;
const char *RESULT_PATH = "infer_results/";
// parameters of post process
const uint32_t CLASS_NUM = 80;
const float SCORE_THRESH = 0.7;
const float IOU_THRESH = 0.5;
} // namespace
int main(int argc, char *argv[]) {
if (argc <= 2) {
LogWarn << "Please input image path, such as './openpose_mindspore [om_file_path] [img_path]'.";
return APP_ERR_OK;
}
InitParam initParam = {};
initParam.deviceId = DEVICE_ID;
initParam.classNum = CLASS_NUM;
initParam.checkTensor = true;
initParam.modelPath = argv[1];
auto inferOpenPose = std::make_shared<OpenPose>();
APP_ERROR ret = inferOpenPose->Init(initParam);
if (ret != APP_ERR_OK) {
LogError << "OpenPose init failed, ret=" << ret << ".";
return ret;
}
std::string imgPath = argv[2];
ret = inferOpenPose->Process(imgPath, RESULT_PATH);
if (ret != APP_ERR_OK) {
LogError << "OpenPose process failed, ret=" << ret << ".";
inferOpenPose->DeInit();
return ret;
}
inferOpenPose->DeInit();
return APP_ERR_OK;
}
cmake_minimum_required(VERSION 3.5.1)
project(ProtoFile)
set(TARGET_LIBRARY mxpiopenposeproto)
# Compile options
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
add_definitions(-Dgoogle=mindxsdk_private)
add_compile_options(-std=c++11 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations)
set(MX_SDK_HOME "$ENV{MX_SDK_HOME}")
if(EXISTS ${MX_SDK_HOME})
set(PROTOBUF_FOUND TRUE)
set(PROTOBUF_PROTOC_EXECUTABLE ${MX_SDK_HOME}/opensource/bin/protoc)
set(PROTOBUF_INCLUDE_DIRS ${MX_SDK_HOME}/opensource/include)
include_directories(${PROTOBUF_INCLUDE_DIRS})
link_directories(${MX_SDK_HOME}/opensource/lib)
endif()
if(PROTOBUF_FOUND)
message(STATUS "protobuf library found")
else()
message(FATAL_ERROR "protobuf library is needed but cant be found")
endif()
LIST(APPEND PROTO_FLAGS -I${PROJECT_SOURCE_DIR})
EXECUTE_PROCESS(
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} ${PROTO_FLAGS} --cpp_out=${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/mxpiOpenposeProto.proto
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} ${PROTO_FLAGS} --python_out=${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/mxpiOpenposeProto.proto
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
file(GLOB_RECURSE SOURCE_FILES ${PROJECT_SOURCE_DIR}/*.cc)
add_library(${TARGET_LIBRARY} SHARED ${SOURCE_FILES})
target_link_libraries(${TARGET_LIBRARY} mindxsdk_protobuf)
#target_link_libraries(${TARGET_LIBRARY} -Wl,-z,relro,-z,now,-z,noexecstack -s)
if(ENABLE_TEST)
target_link_libraries(${TARGET_LIBRARY} gcov)
endif()
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
install(TARGETS ${TARGET_LIBRARY} LIBRARY DESTINATION ${PROJECT_SOURCE_DIR}/lib)
#!/bin/bash
# Copyright 2021 Huawei Technologies Co., Ltd
#
# 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.mitations under the License.
set -e
current_folder="$( cd "$(dirname "$0")" ;pwd -P )"
function build_plugin() {
build_path=$current_folder/build
if [ -d "$build_path" ]; then
rm -rf "$build_path"
else
echo "file $build_path is not exist."
fi
mkdir -p "$build_path"
cd "$build_path"
cmake ..
make -j
cd ..
exit 0
}
build_plugin
exit 0
syntax = "proto3";
package mxpiopenposeproto;
message MxpiMetaHeader
{
string parentName = 1;
int32 memberId = 2;
string dataSource = 3;
}
message MxpiSkeletonInfo
{
int32 cocoSkeletonIndex1 = 1;
int32 cocoSkeletonIndex2 = 2;
float x0 = 3;
float y0 = 4;
float point1Score = 5;
float x1 = 6;
float y1 = 7;
float point2Score = 8;
float skeletonScore = 9;
}
message MxpiPersonInfo
{
repeated MxpiMetaHeader headerVec = 1;
repeated MxpiSkeletonInfo skeletonInfoVec = 2;
float score = 3;
}
message MxpiPersonList
{
repeated MxpiPersonInfo personInfoVec = 1;
}
\ No newline at end of file
cmake_minimum_required(VERSION 3.5.2)
project(OpenposePlugin)
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0 -Dgoogle=mindxsdk_private)
set(PLUGIN_NAME "mxpi_openposepostprocess")
set(TARGET_LIBRARY ${PLUGIN_NAME})
set(MX_SDK_HOME "$ENV{MX_SDK_HOME}")
include_directories(${CMAKE_CURRENT_BINARY_DIR})
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)
include_directories(${MX_SDK_HOME}/opensource/include/opencv4)
include_directories(${PROJECT_SOURCE_DIR}/../proto)
link_directories(${MX_SDK_HOME}/lib)
link_directories(${MX_SDK_HOME}/opensource/lib)
link_directories(${PROJECT_SOURCE_DIR}/../proto/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 MxpiOpenposePostProcess.cpp)
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} mxpidatatype plugintoolkit mxbase mindxsdk_protobuf mxpiopenposeproto)
\ No newline at end of file
This diff is collapsed.
/*
* Copyright(C) 2021. Huawei Technologies Co.,Ltd.
*
* 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 OPENPOSEPOSTPROCESS_MXPIOPENPOSEPOSTPROCESS_H
#define OPENPOSEPOSTPROCESS_MXPIOPENPOSEPOSTPROCESS_H
#include <vector>
#include <map>
#include <memory>
#include <string>
#include "MxTools/PluginToolkit/base/MxPluginGenerator.h"
#include "MxTools/PluginToolkit/base/MxPluginBase.h"
#include "MxTools/PluginToolkit/metadata/MxpiMetadataManager.h"
#include "MxTools/Proto/MxpiDataType.pb.h"
#include "MxBase/ErrorCode/ErrorCode.h"
#include "mxpiOpenposeProto.pb.h"
#include "opencv2/opencv.hpp"
/**
* @api
* @brief Definition of MxpiOpenposePostProcess class.
*/
namespace MxPlugins {
struct PartPair {
float score;
int partIdx1;
int partIdx2;
int idx1;
int idx2;
std::vector<float> coord1;
std::vector<float> coord2;
float score1;
float score2;
};
class MxpiOpenposePostProcess : public MxTools::MxPluginBase {
public:
MxpiOpenposePostProcess() = default;
~MxpiOpenposePostProcess() = default;
/**
* @brief Initialize configure parameter.
* @param config_param_map
* @return APP_ERROR
*/
APP_ERROR Init(std::map<std::string, std::shared_ptr<void>> &config_param_map) override;
/**
* @brief DeInitialize configure parameter.
* @return APP_ERROR
*/
APP_ERROR DeInit() override;
/**
* @brief Process the data of MxpiBuffer.
* @param mxpi_buffer
* @return APP_ERROR
*/
APP_ERROR Process(std::vector<MxTools::MxpiBuffer*> &mxpi_buffer) override;
/**
* @brief Definition the parameter of configure properties.
* @return std::vector<std::shared_ptr<void>>
*/
static std::vector<std::shared_ptr<void>> DefineProperties();
/**
* Overall process to generate all person skeleton information
* @param image_decoder_visionListSptr - Source MxpiVisionList containing vision data about input and aligned image
* @param src_mxpi_tensor_package - Source MxpiTensorPackage containing heatmap data
* @param dst_mxpi_person_list - Target MxpiPersonList containing detection result list
* @return APP_ERROR
*/
APP_ERROR GeneratePersonList(const MxTools::MxpiVisionList image_decoder_visionListSptr,
const MxTools::MxpiTensorPackageList src_mxpi_tensor_package,
mxpiopenposeproto::MxpiPersonList *dst_mxpi_person_list);
/**
* @brief Resize output heatmaps to the size of the origin image
* @param keypoint_heatmap - Keypoint heatmap, each channel of the heatmap is stored as a Mat
* @param paf_heatmap - PAF heatmap, each channel of the heatmap is stored as a Mat
* @param vision_infos - Vision infos of origin image and aligned image
* @return APP_ERROR
*/
APP_ERROR ResizeHeatmaps(const std::vector<int> &vision_infos, std::vector<cv::Mat> *keypoint_heatmap,
std::vector<cv::Mat > *paf_heatmap);
/**
* @brief Extract candidate keypoints from output heatmap
* @param keypoint_heatmap - Keypoint heatmap stored in vector
* @param coor - Keep coor for candidate keypoints by category
* @param coor_score - Keep coor score for candidate keypoints by category
* @return APP_ERROR
*/
APP_ERROR ExtractKeypoints(const std::vector<cv::Mat> &keypoint_heatmap,
std::vector<std::vector<cv::Point> > *coor, std::vector<std::vector<float> > *coor_score);
/**
* @brief Group keypoints to skeletons and assemble them to person
* @param paf_heatmap - PAF heatmap
* @param coor - Coordinates of all the candidate keypoints
* @param coor_score - Corresponding score of coordinates
* @param person_list - Target vector to store person, each person is stored as a vector of skeletons
* @return APP_ERROR
*/
APP_ERROR GroupKeypoints(const std::vector<cv::Mat>& paf_heatmap,
const std::vector<std::vector<cv::Point> > &coor, const std::vector<std::vector<float> > &coor_score,
std::vector<std::vector<PartPair> > *person_list);
/**
* @brief Calculate expected confidence of each possible skeleton and choose candidates
* @param part_idx - Index of skeleton in kPoseBodyPartSkeletons
* @param coor - Candidate positions of endpoints
* @param coor_score - Corresponding score of coor
* @param paf_heatmap - PAF heatmap
* @param connections - Target vector that collects candidate skeletons
* @return APP_ERROR
*/
APP_ERROR ScoreSkeletons(const int part_idx, const std::vector<std::vector<cv::Point> > &coor,
const std::vector<std::vector<float> > &coor_score, const std::vector<cv::Mat> &paf_heatmap,
std::vector<PartPair> *connections);
/**
* @brief Compute expected confidence for each candidate skeleton
* @param endpoints - Coordinates of the two end points of a skeleton
* @param paf_x - PAF heatmap of x coordinate
* @param paf_y - PAF heatmap of y coordinate
* @return result - Keep confidence information of this skeleton in the form:
* [confidence score, number of successfully hit sub points]
*/
std::vector<float> OneSkeletonScore(const cv::Mat &paf_x, const cv::Mat &paf_y,
const std::vector<cv::Point> &endpoints);
/**
* @brief Remove duplicate skeletons
* @param src - Source vector that stores skeletons to be processed
* @param dst - Target vector that collects filter skeletons
* @return APP_ERROR
*/
APP_ERROR ConntectionNms(std::vector<PartPair> *src, std::vector<PartPair> *dst);
/**
* @brief Merge a skeleton to an existed person
* @param person_list - Currently existed person list
* @param current_pair - Skeleton to be merged
* @return True if merged successfully, otherwise false
*/
bool MergeSkeletonToPerson(std::vector<std::vector<PartPair> > *person_list, PartPair current_pair);
/**
* @brief Calculate score of a person according to its skeletons
* @param person - Target person
* @return Score value
*/
float PersonScore(const std::vector<PartPair> &person);
/**
* @brief Prepare output in the format of MxpiPersonList
* @param person_list - Source data in the format of std::vector<std::vector<PartPair> >
* @param dst_mxpi_person_list - Target data in the format of MxpiPersonList
* @return
*/
APP_ERROR GenerateMxpiOutput(const std::vector<std::vector<PartPair> > &person_list,
mxpiopenposeproto::MxpiPersonList *dst_mxpi_person_list);
private:
APP_ERROR SetMxpiErrorInfo(const std::string &plugin_name,
const MxTools::MxpiErrorInfo &mxpi_error_info, MxTools::MxpiBuffer *buffer);
std::string parentName_;
std::string imageDecoderName_;
std::uint32_t inputHeight_;
std::uint32_t inputWidth_;
std::ostringstream ErrorInfo_;
};
} // namespace MxPlugins
#endif // OPENPOSEPOSTPROCESS_MXPIOPENPOSEPOSTPROCESS_H
#!/bin/bash
# Copyright 2021 Huawei Technologies Co., Ltd
#
# 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.mitations under the License.
set -e
current_folder="$( cd "$(dirname "$0")" ;pwd -P )"
function build_plugin() {
build_path=$current_folder/build
if [ -d "$build_path" ]; then
rm -rf "$build_path"
else
echo "file $build_path is not exist."
fi
mkdir -p "$build_path"
cd "$build_path"
cmake ..
make -j
cd ..
exit 0
}
build_plugin
exit 0
cmake_minimum_required(VERSION 3.5.1)
project(ProtoFile)
set(TARGET_LIBRARY mxpiopenposeproto)
# Compile options
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
add_definitions(-Dgoogle=mindxsdk_private)
add_compile_options(-std=c++11 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations)
set(MX_SDK_HOME "$ENV{MX_SDK_HOME}")
if(EXISTS ${MX_SDK_HOME})
set(PROTOBUF_FOUND TRUE)
set(PROTOBUF_PROTOC_EXECUTABLE ${MX_SDK_HOME}/opensource/bin/protoc)
set(PROTOBUF_INCLUDE_DIRS ${MX_SDK_HOME}/opensource/include)
include_directories(${PROTOBUF_INCLUDE_DIRS})
link_directories(${MX_SDK_HOME}/opensource/lib)
endif()
if(PROTOBUF_FOUND)
message(STATUS "protobuf library found")
else()
message(FATAL_ERROR "protobuf library is needed but cant be found")
endif()
LIST(APPEND PROTO_FLAGS -I${PROJECT_SOURCE_DIR})
EXECUTE_PROCESS(
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} ${PROTO_FLAGS} --cpp_out=${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/mxpiOpenposeProto.proto
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} ${PROTO_FLAGS} --python_out=${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/mxpiOpenposeProto.proto
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
file(GLOB_RECURSE SOURCE_FILES ${PROJECT_SOURCE_DIR}/*.cc)
add_library(${TARGET_LIBRARY} SHARED ${SOURCE_FILES})
target_link_libraries(${TARGET_LIBRARY} mindxsdk_protobuf)
if(ENABLE_TEST)
target_link_libraries(${TARGET_LIBRARY} gcov)
endif()
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
install(TARGETS ${TARGET_LIBRARY} LIBRARY DESTINATION ${PROJECT_SOURCE_DIR}/lib)
#!/bin/bash
# Copyright 2021 Huawei Technologies Co., Ltd
#
# 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.mitations under the License.
set -e
current_folder="$( cd "$(dirname "$0")" ;pwd -P )"
function build_plugin() {
build_path=$current_folder/build
if [ -d "$build_path" ]; then
rm -rf "$build_path"
else
echo "file $build_path is not exist."
fi
mkdir -p "$build_path"
cd "$build_path"
cmake ..
make -j
cd ..
exit 0
}
build_plugin
exit 0
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment