Initial commit
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "Ascend ACL App",
|
||||
"project_type": "Custom",
|
||||
"project_desc": "",
|
||||
"target": "",
|
||||
"target_id": "",
|
||||
"adk_version": "1.73.T5.0.B050"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
|
||||
|
||||
# CMake lowest version requirement
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
# project information
|
||||
project(sample-objectdetection)
|
||||
|
||||
add_subdirectory("./src")
|
||||
@@ -0,0 +1,14 @@
|
||||
aipp_op{
|
||||
aipp_mode:static
|
||||
input_format : RGB888_U8
|
||||
csc_switch : false
|
||||
rbuv_swap_switch:true
|
||||
|
||||
var_reci_chn_0 :0.003921568627451
|
||||
var_reci_chn_1 :0.003921568627451
|
||||
var_reci_chn_2 :0.003921568627451
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Copyright 2020 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.
|
||||
|
||||
* File model_process.h
|
||||
* Description: handle model process
|
||||
*/
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include "utils.h"
|
||||
#include "acl/acl.h"
|
||||
|
||||
/**
|
||||
* ModelProcess
|
||||
*/
|
||||
class ModelProcess {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
ModelProcess();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~ModelProcess();
|
||||
|
||||
/**
|
||||
* @brief load model from file with mem
|
||||
* @param [in] modelPath: model path
|
||||
* @return result
|
||||
*/
|
||||
Result LoadModelFromFileWithMem(const char *modelPath);
|
||||
|
||||
/**
|
||||
* @brief unload model
|
||||
*/
|
||||
void Unload();
|
||||
|
||||
/**
|
||||
* @brief create model desc
|
||||
* @return result
|
||||
*/
|
||||
Result CreateDesc();
|
||||
|
||||
/**
|
||||
* @brief destroy desc
|
||||
*/
|
||||
void DestroyDesc();
|
||||
|
||||
/**
|
||||
* @brief create model input
|
||||
* @param [in] inputDataBuffer: input buffer
|
||||
* @param [in] bufferSize: input buffer size
|
||||
* @return result
|
||||
*/
|
||||
Result CreateInput(void *inputDataBuffer, size_t bufferSize);
|
||||
|
||||
/**
|
||||
* @brief destroy input resource
|
||||
*/
|
||||
void DestroyInput();
|
||||
|
||||
/**
|
||||
* @brief create output buffer
|
||||
* @return result
|
||||
*/
|
||||
Result CreateOutput();
|
||||
|
||||
/**
|
||||
* @brief destroy output resource
|
||||
*/
|
||||
void DestroyOutput();
|
||||
|
||||
/**
|
||||
* @brief model execute
|
||||
* @return result
|
||||
*/
|
||||
Result Execute();
|
||||
|
||||
/**
|
||||
* @brief get model output data
|
||||
* @return output dataset
|
||||
*/
|
||||
aclmdlDataset *GetModelOutputData();
|
||||
|
||||
private:
|
||||
bool loadFlag_; // model load flag
|
||||
uint32_t modelId_;
|
||||
void *modelMemPtr_;
|
||||
size_t modelMemSize_;
|
||||
void *modelWeightPtr_;
|
||||
size_t modelWeightSize_;
|
||||
aclmdlDesc *modelDesc_;
|
||||
aclmdlDataset *input_;
|
||||
aclmdlDataset *output_;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright 2020 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.
|
||||
|
||||
* File sample_process.h
|
||||
* Description: handle acl resource
|
||||
*/
|
||||
#pragma once
|
||||
#include "utils.h"
|
||||
#include "acl/acl.h"
|
||||
#include <memory>
|
||||
|
||||
template<class Type>
|
||||
std::shared_ptr<Type> MakeSharedNoThrow() {
|
||||
try {
|
||||
return std::make_shared<Type>();
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAKE_SHARED_NO_THROW(memory, memory_type) \
|
||||
memory = MakeSharedNoThrow<memory_type>();
|
||||
|
||||
/**
|
||||
* SampleProcess
|
||||
*/
|
||||
class SampleProcess {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
SampleProcess();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~SampleProcess();
|
||||
|
||||
/**
|
||||
* @brief init reousce
|
||||
* @return result
|
||||
*/
|
||||
Result InitResource();
|
||||
|
||||
/**
|
||||
* @brief encode sample process
|
||||
* @param [in] dvpptype: dvpp type
|
||||
* @return result
|
||||
*/
|
||||
Result MainProcess(std::string input_path);
|
||||
|
||||
private:
|
||||
void DestroyResource();
|
||||
|
||||
int32_t deviceId_;
|
||||
aclrtContext context_;
|
||||
aclrtStream stream_;
|
||||
};
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright 2020 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.
|
||||
|
||||
* File utils.h
|
||||
* Description: handle file operations
|
||||
*/
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "acl/acl.h"
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include "opencv2/imgcodecs/legacy/constants_c.h"
|
||||
#include "opencv2/imgproc/types_c.h"
|
||||
|
||||
#define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO] " fmt "\n", ##args)
|
||||
#define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN] " fmt "\n", ##args)
|
||||
#define ERROR_LOG(fmt, args...) fprintf(stdout, "[ERROR] " fmt "\n", ##args)
|
||||
#define MODEL_INPUT_WIDTH 416
|
||||
#define MODEL_INPUT_HEIGHT 416
|
||||
|
||||
typedef enum Result {
|
||||
SUCCESS = 0,
|
||||
FAILED = 1
|
||||
} Result;
|
||||
|
||||
struct ConsoleParams {
|
||||
uint32_t img_width = 0;
|
||||
uint32_t img_height = 0;
|
||||
int32_t size = 0;
|
||||
std::string input_path = "";
|
||||
std::shared_ptr<u_int8_t> data;
|
||||
};
|
||||
|
||||
const std::string kImagePathSeparator = ",";
|
||||
const int kStatSuccess = 0;
|
||||
const std::string kFileSperator = "/";
|
||||
const std::string kPathSeparator = "/";
|
||||
// output image prefix
|
||||
const std::string kOutputFilePrefix = "out_";
|
||||
|
||||
/**
|
||||
* Utils
|
||||
*/
|
||||
class Utils {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief create device buffer of pic
|
||||
* @param [in] picDesc: pic desc
|
||||
* @param [in] PicBufferSize: aligned pic size
|
||||
* @return device buffer of pic
|
||||
*/
|
||||
|
||||
static Result Postprocess(const std::string &path, aclmdlDataset *modelOutput);
|
||||
|
||||
static bool IsDirectory(const std::string &path);
|
||||
|
||||
static bool IsPathExist(const std::string &path);
|
||||
|
||||
static void SplitPath(const std::string &path, std::vector<std::string> &path_vec);
|
||||
|
||||
static void GetAllFiles(const std::string &path, std::vector<std::string> &file_vec);
|
||||
|
||||
static void GetPathFiles(const std::string &path, std::vector<std::string> &file_vec);
|
||||
|
||||
static bool Preprocess(std::shared_ptr<ConsoleParams> &image_path,
|
||||
const std::string &path);
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
# Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.
|
||||
|
||||
# CMake lowest version requirement
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
# project information
|
||||
project(objectdetection_pic)
|
||||
|
||||
# Compile options
|
||||
add_compile_options(-std=c++11)
|
||||
|
||||
add_definitions(-DENABLE_DVPP_INTERFACE)
|
||||
|
||||
# Specify target generation path
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../../../out")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-fPIC -O0 -g -Wall")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-fPIC -O2 -Wall")
|
||||
|
||||
set(INC_PATH $ENV{DDK_PATH})
|
||||
|
||||
if (NOT DEFINED ENV{DDK_PATH})
|
||||
set(INC_PATH "/usr/local/Ascend")
|
||||
message(STATUS "set default INC_PATH: ${INC_PATH}")
|
||||
else ()
|
||||
message(STATUS "env INC_PATH: ${INC_PATH}")
|
||||
endif()
|
||||
|
||||
set(LIB_PATH $ENV{NPU_HOST_LIB})
|
||||
set(OPENCV_PATH "/usr/local")
|
||||
|
||||
if (NOT DEFINED ENV{NPU_HOST_LIB})
|
||||
set(LIB_PATH "/usr/local/Ascend/acllib/lib64/stub/")
|
||||
message(STATUS "set default LIB_PATH: ${LIB_PATH}")
|
||||
else ()
|
||||
message(STATUS "env LIB_PATH: ${LIB_PATH}")
|
||||
endif()
|
||||
|
||||
# Header path
|
||||
include_directories(
|
||||
$ENV{HOME}/ascend_ddk/include/
|
||||
$ENV{HOME}/ascend_ddk/include/ascenddk/
|
||||
${INC_PATH}/acllib/include/
|
||||
../inc/
|
||||
${OPENCV_PATH}/include/opencv4
|
||||
)
|
||||
|
||||
|
||||
# add host lib path
|
||||
link_directories(
|
||||
${LIB_PATH}
|
||||
$ENV{HOME}/ascend_ddk/host/lib/
|
||||
${OPENCV_PATH}/lib
|
||||
${INC_PATH}/atc/lib64
|
||||
)
|
||||
|
||||
add_executable(main
|
||||
utils.cpp
|
||||
model_process.cpp
|
||||
sample_process.cpp
|
||||
main.cpp)
|
||||
|
||||
target_link_libraries(main
|
||||
ascendcl acl_dvpp stdc++ opencv_highgui opencv_core opencv_imgproc opencv_imgcodecs opencv_calib3d opencv_features2d)
|
||||
|
||||
install(TARGETS main DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright 2020 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.
|
||||
|
||||
* File main.cpp
|
||||
* Description: dvpp sample main func
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include "sample_process.h"
|
||||
#include "utils.h"
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
if(argc<2){
|
||||
ERROR_LOG("please input: ./main path");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
SampleProcess processSample;
|
||||
Result ret = processSample.InitResource();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("sample init resource failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
//input path
|
||||
string input_path = string(argv[1]);
|
||||
|
||||
ret = processSample.MainProcess(input_path);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("sample model process failed");
|
||||
return FAILED;
|
||||
}
|
||||
INFO_LOG("execute sample success");
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* Copyright 2020 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.
|
||||
|
||||
* File model_process.cpp
|
||||
* Description: handle model process
|
||||
*/
|
||||
#include "model_process.h"
|
||||
#include <iostream>
|
||||
#include "utils.h"
|
||||
using namespace std;
|
||||
|
||||
ModelProcess::ModelProcess():loadFlag_(false), modelId_(0), modelMemPtr_(nullptr), modelMemSize_(0),
|
||||
modelWeightPtr_(nullptr),modelWeightSize_(0), modelDesc_(nullptr), input_(nullptr), output_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ModelProcess::~ModelProcess()
|
||||
{
|
||||
Unload();
|
||||
DestroyDesc();
|
||||
DestroyInput();
|
||||
DestroyOutput();
|
||||
}
|
||||
|
||||
Result ModelProcess::LoadModelFromFileWithMem(const char *modelPath)
|
||||
{
|
||||
if (loadFlag_) {
|
||||
ERROR_LOG("has already loaded a model");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlQuerySize(modelPath, &modelMemSize_, &modelWeightSize_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("query model failed, model file is %s", modelPath);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclrtMalloc(&modelMemPtr_, modelMemSize_, ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc buffer for weight failed, require size is %zu", modelWeightSize_);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_,
|
||||
modelMemSize_, modelWeightPtr_, modelWeightSize_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("load model from file failed, model file is %s", modelPath);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
loadFlag_ = true;
|
||||
INFO_LOG("load model %s success", modelPath);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Result ModelProcess::CreateDesc()
|
||||
{
|
||||
modelDesc_ = aclmdlCreateDesc();
|
||||
if (modelDesc_ == nullptr) {
|
||||
ERROR_LOG("create model description failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlGetDesc(modelDesc_, modelId_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("get model description failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
INFO_LOG("create model description success");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void ModelProcess::DestroyDesc()
|
||||
{
|
||||
if (modelDesc_ != nullptr) {
|
||||
(void)aclmdlDestroyDesc(modelDesc_);
|
||||
modelDesc_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const float ModelInput2[4]={416,416,416,416};
|
||||
|
||||
Result ModelProcess::CreateInput(void *inputDataBuffer, size_t bufferSize)
|
||||
{
|
||||
input_ = aclmdlCreateDataset();
|
||||
if (input_ == nullptr) {
|
||||
ERROR_LOG("can't create dataset, create input failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclDataBuffer* inputData = aclCreateDataBuffer(inputDataBuffer, bufferSize);
|
||||
if (inputData == nullptr) {
|
||||
ERROR_LOG("can't create data buffer, create input failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlAddDatasetBuffer(input_, inputData);
|
||||
if (inputData == nullptr) {
|
||||
ERROR_LOG("can't add data buffer, create input failed");
|
||||
aclDestroyDataBuffer(inputData);
|
||||
inputData = nullptr;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
void *dataDev;
|
||||
uint32_t dataSize=sizeof(ModelInput2);
|
||||
aclrtMalloc(&dataDev, dataSize,ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
aclrtMemcpy(dataDev, dataSize, ModelInput2, sizeof(ModelInput2), ACL_MEMCPY_DEVICE_TO_DEVICE);
|
||||
aclDataBuffer* inputData2 = aclCreateDataBuffer(dataDev, dataSize);
|
||||
if (inputData == nullptr) {
|
||||
ERROR_LOG("can't create data buffer, create input failed");
|
||||
return FAILED;
|
||||
}
|
||||
ret = aclmdlAddDatasetBuffer(input_, inputData2);
|
||||
if (inputData == nullptr) {
|
||||
ERROR_LOG("can't add data buffer, create input failed");
|
||||
aclDestroyDataBuffer(inputData2);
|
||||
inputData = nullptr;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void ModelProcess::DestroyInput()
|
||||
{
|
||||
if (input_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(input_); ++i) {
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(input_, i);
|
||||
aclDestroyDataBuffer(dataBuffer);
|
||||
}
|
||||
aclmdlDestroyDataset(input_);
|
||||
input_ = nullptr;
|
||||
}
|
||||
|
||||
Result ModelProcess::CreateOutput()
|
||||
{
|
||||
if (modelDesc_ == nullptr) {
|
||||
ERROR_LOG("no model description, create ouput failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
output_ = aclmdlCreateDataset();
|
||||
if (output_ == nullptr) {
|
||||
ERROR_LOG("can't create dataset, create output failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
size_t outputSize = aclmdlGetNumOutputs(modelDesc_);
|
||||
for (size_t i = 0; i < outputSize; ++i) {
|
||||
size_t buffer_size = aclmdlGetOutputSizeByIndex(modelDesc_, i);
|
||||
|
||||
void *outputBuffer = nullptr;
|
||||
aclError ret = aclrtMalloc(&outputBuffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("can't malloc buffer, size is %zu, create output failed", buffer_size);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclDataBuffer* outputData = aclCreateDataBuffer(outputBuffer, buffer_size);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("can't create data buffer, create output failed");
|
||||
aclrtFree(outputBuffer);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclmdlAddDatasetBuffer(output_, outputData);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("can't add data buffer, create output failed");
|
||||
aclrtFree(outputBuffer);
|
||||
aclDestroyDataBuffer(outputData);
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
INFO_LOG("create model output success");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void ModelProcess::DestroyOutput()
|
||||
{
|
||||
if (output_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) {
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
|
||||
void* data = aclGetDataBufferAddr(dataBuffer);
|
||||
(void)aclrtFree(data);
|
||||
(void)aclDestroyDataBuffer(dataBuffer);
|
||||
}
|
||||
|
||||
(void)aclmdlDestroyDataset(output_);
|
||||
output_ = nullptr;
|
||||
}
|
||||
|
||||
Result ModelProcess::Execute()
|
||||
{
|
||||
aclError ret = aclmdlExecute(modelId_, input_, output_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("execute model failed, modelId is %u", modelId_);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
INFO_LOG("model execute success");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void ModelProcess::Unload()
|
||||
{
|
||||
if (!loadFlag_) {
|
||||
WARN_LOG("no model had been loaded, unload failed");
|
||||
return;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlUnload(modelId_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("unload model failed, modelId is %u", modelId_);
|
||||
}
|
||||
|
||||
if (modelDesc_ != nullptr) {
|
||||
(void)aclmdlDestroyDesc(modelDesc_);
|
||||
modelDesc_ = nullptr;
|
||||
}
|
||||
|
||||
if (modelMemPtr_ != nullptr) {
|
||||
aclrtFree(modelMemPtr_);
|
||||
modelMemPtr_ = nullptr;
|
||||
modelMemSize_ = 0;
|
||||
}
|
||||
|
||||
if (modelWeightPtr_ != nullptr) {
|
||||
aclrtFree(modelWeightPtr_);
|
||||
modelWeightPtr_ = nullptr;
|
||||
modelWeightSize_ = 0;
|
||||
}
|
||||
|
||||
loadFlag_ = false;
|
||||
INFO_LOG("unload model success, modelId is %u", modelId_);
|
||||
}
|
||||
|
||||
aclmdlDataset *ModelProcess::GetModelOutputData()
|
||||
{
|
||||
return output_;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* Copyright 2020 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.
|
||||
|
||||
* File sample_process.cpp
|
||||
* Description: handle acl resource
|
||||
*/
|
||||
#include "sample_process.h"
|
||||
#include <iostream>
|
||||
#include "model_process.h"
|
||||
#include "acl/acl.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
SampleProcess::SampleProcess():deviceId_(0), context_(nullptr), stream_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
SampleProcess::~SampleProcess()
|
||||
{
|
||||
DestroyResource();
|
||||
}
|
||||
|
||||
Result SampleProcess::InitResource()
|
||||
{
|
||||
// ACL init
|
||||
const char *aclConfigPath = "../src/acl.json";
|
||||
aclError ret = aclInit(aclConfigPath);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("acl init failed");
|
||||
return FAILED;
|
||||
}
|
||||
INFO_LOG("acl init success");
|
||||
|
||||
// open device
|
||||
ret = aclrtSetDevice(deviceId_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("acl open device %d failed", deviceId_);
|
||||
return FAILED;
|
||||
}
|
||||
INFO_LOG("open device %d success", deviceId_);
|
||||
|
||||
// create context (set current)
|
||||
ret = aclrtCreateContext(&context_, deviceId_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("acl create context failed");
|
||||
return FAILED;
|
||||
}
|
||||
INFO_LOG("create context success");
|
||||
|
||||
// create stream
|
||||
ret = aclrtCreateStream(&stream_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("acl create stream failed");
|
||||
return FAILED;
|
||||
}
|
||||
INFO_LOG("create stream success");
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Result SampleProcess::MainProcess(string input_path)
|
||||
{
|
||||
const char* omModelPath = "../model/yolov3_BGR.om";
|
||||
|
||||
vector<string> file_vec;
|
||||
Utils::GetAllFiles(input_path, file_vec);
|
||||
if (file_vec.empty()) {
|
||||
ERROR_LOG("Failed to deal all empty path=%s.", input_path.c_str());
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
// model init
|
||||
ModelProcess processModel;
|
||||
aclError ret = processModel.LoadModelFromFileWithMem(omModelPath);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute LoadModelFromFileWithMem failed");
|
||||
return FAILED;
|
||||
}
|
||||
ret = processModel.CreateDesc();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateDesc failed");
|
||||
return FAILED;
|
||||
}
|
||||
ret = processModel.CreateOutput();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateOutput failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
for (string path : file_vec) {
|
||||
shared_ptr<ConsoleParams> image_path = nullptr;
|
||||
MAKE_SHARED_NO_THROW(image_path, ConsoleParams);
|
||||
if (image_path == nullptr) {
|
||||
ERROR_LOG("Failed to deal file=%s. Reason: new EngineTrans failed.",
|
||||
path.c_str());
|
||||
continue;
|
||||
}
|
||||
// arrange image information, if failed, skip this image
|
||||
if (!Utils::Preprocess(image_path, path)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = processModel.CreateInput((void*) image_path->data.get(), image_path->size);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateInput failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.Execute();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute inference failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
// release model input buffer
|
||||
processModel.DestroyInput();
|
||||
|
||||
aclmdlDataset *modelOutput = processModel.GetModelOutputData();
|
||||
if (modelOutput == nullptr) {
|
||||
ERROR_LOG("get model output data failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = Utils::Postprocess(path, modelOutput);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("pull model output data failed");
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void SampleProcess::DestroyResource()
|
||||
{
|
||||
aclError ret;
|
||||
if (stream_ != nullptr) {
|
||||
ret = aclrtDestroyStream(stream_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("destroy stream failed");
|
||||
}
|
||||
stream_ = nullptr;
|
||||
}
|
||||
INFO_LOG("end to destroy stream");
|
||||
|
||||
if (context_ != nullptr) {
|
||||
ret = aclrtDestroyContext(context_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("destroy context failed");
|
||||
}
|
||||
context_ = nullptr;
|
||||
}
|
||||
INFO_LOG("end to destroy context");
|
||||
|
||||
ret = aclrtResetDevice(deviceId_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("reset device failed");
|
||||
}
|
||||
INFO_LOG("end to reset device is %d", deviceId_);
|
||||
|
||||
ret = aclFinalize();
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("finalize acl failed");
|
||||
}
|
||||
INFO_LOG("end to finalize acl");
|
||||
}
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* Copyright 2020 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.
|
||||
|
||||
* File utils.cpp
|
||||
* Description: handle file operations
|
||||
*/
|
||||
#include "utils.h"
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <dirent.h>
|
||||
#include <vector>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include "acl/acl.h"
|
||||
#include "acl/ops/acl_dvpp.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
const static std::vector<std::string> yolov3Label = {"person", "bicycle", "car", "motorbike",
|
||||
"aeroplane","bus", "train", "truck", "boat",
|
||||
"traffic light", "fire hydrant", "stop sign", "parking meter",
|
||||
"bench", "bird", "cat", "dog", "horse",
|
||||
"sheep", "cow", "elephant", "bear", "zebra",
|
||||
"giraffe", "backpack", "umbrella", "handbag","tie",
|
||||
"suitcase", "frisbee", "skis", "snowboard", "sports ball",
|
||||
"kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
|
||||
"tennis racket", "bottle", "wine glass", "cup",
|
||||
"fork", "knife", "spoon", "bowl", "banana",
|
||||
"apple", "sandwich", "orange", "broccoli", "carrot",
|
||||
"hot dog", "pizza", "donut", "cake", "chair",
|
||||
"sofa", "potted plant", "bed", "dining table", "toilet",
|
||||
"TV monitor", "laptop", "mouse", "remote", "keyboard",
|
||||
"cell phone", "microwave", "oven", "toaster", "sink",
|
||||
"refrigerator", "book", "clock", "vase","scissors",
|
||||
"teddy bear", "hair drier", "toothbrush"};
|
||||
|
||||
enum BBoxIndex {TOPLEFTX=0,TOPLEFTY,BOTTOMRIGHTX,BOTTOMRIGHTY,SCORE,LABEL};
|
||||
|
||||
Result Utils::Postprocess(const string &path, aclmdlDataset *modelOutput)
|
||||
{
|
||||
size_t outDatasetNum = aclmdlGetDatasetNumBuffers(modelOutput);
|
||||
if (outDatasetNum != 2) {
|
||||
return FAILED;
|
||||
}
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(modelOutput, 1);
|
||||
if (dataBuffer == nullptr) {
|
||||
ERROR_LOG("get model output aclmdlGetDatasetBuffer failed");
|
||||
return FAILED;
|
||||
}
|
||||
void* data = aclGetDataBufferAddr(dataBuffer);
|
||||
if (data == nullptr) {
|
||||
ERROR_LOG("aclGetDataBufferAddr from dataBuffer failed.");
|
||||
}
|
||||
uint32_t count;
|
||||
aclrtMemcpy(&count, sizeof(count), data, sizeof(count), ACL_MEMCPY_DEVICE_TO_DEVICE);
|
||||
INFO_LOG("box count=%d",count);
|
||||
dataBuffer = aclmdlGetDatasetBuffer(modelOutput, 0);
|
||||
if (dataBuffer == nullptr) {
|
||||
ERROR_LOG("get model output aclmdlGetDatasetBuffer failed");
|
||||
return FAILED;
|
||||
}
|
||||
data = aclGetDataBufferAddr(dataBuffer);
|
||||
if (data == nullptr) {
|
||||
ERROR_LOG("aclGetDataBufferAddr from dataBuffer failed.");
|
||||
}
|
||||
float outInfo[count*6];
|
||||
aclrtMemcpy(&outInfo, sizeof(outInfo), data, sizeof(outInfo), ACL_MEMCPY_DEVICE_TO_DEVICE);
|
||||
cv::Rect rect;
|
||||
int font_face = 0;
|
||||
double font_scale = 1;
|
||||
int thickness = 2;
|
||||
int baseline;
|
||||
cv::Mat resultImage = cv::imread(path, CV_LOAD_IMAGE_COLOR);
|
||||
for(uint32_t b=0;b<count;b++){
|
||||
uint32_t score=uint32_t(outInfo[count*SCORE+b]*100);
|
||||
if(score<90)continue;
|
||||
rect.x=outInfo[count*TOPLEFTX+b]*resultImage.cols/416;
|
||||
rect.y=outInfo[count*TOPLEFTY+b]*resultImage.rows/416;
|
||||
rect.width=outInfo[count*BOTTOMRIGHTX+b]*resultImage.cols/416-rect.x;
|
||||
rect.height=outInfo[count*BOTTOMRIGHTY+b]*resultImage.rows/416-rect.y;
|
||||
uint32_t objIndex = (uint32_t)outInfo[count*LABEL+b];
|
||||
string text = yolov3Label[objIndex]+std::to_string(score)+"\%";
|
||||
cv::Point origin;
|
||||
origin.x = rect.x;
|
||||
origin.y = rect.y;
|
||||
cv::putText(resultImage, text, origin, font_face, font_scale, cv::Scalar(0, 255, 255), thickness, 4, 0);
|
||||
cv::rectangle(resultImage, rect, cv::Scalar(0, 255, 255),1, 8,0);
|
||||
}
|
||||
// generate colorized image
|
||||
int pos = path.find_last_of(kFileSperator);
|
||||
string file_name(path.substr(pos + 1));
|
||||
stringstream sstream;
|
||||
sstream.str("");
|
||||
sstream << "./output" << kFileSperator
|
||||
<< kOutputFilePrefix << file_name;
|
||||
|
||||
string outputPath = sstream.str();
|
||||
cv::imwrite(outputPath, resultImage);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
bool Utils::IsDirectory(const string &path) {
|
||||
// get path stat
|
||||
struct stat buf;
|
||||
if (stat(path.c_str(), &buf) != kStatSuccess) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check
|
||||
if (S_ISDIR(buf.st_mode)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Utils::IsPathExist(const string &path) {
|
||||
ifstream file(path);
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Utils::SplitPath(const string &path, vector<string> &path_vec) {
|
||||
char *char_path = const_cast<char*>(path.c_str());
|
||||
const char *char_split = kImagePathSeparator.c_str();
|
||||
char *tmp_path = strtok(char_path, char_split);
|
||||
while (tmp_path) {
|
||||
path_vec.emplace_back(tmp_path);
|
||||
tmp_path = strtok(nullptr, char_split);
|
||||
}
|
||||
}
|
||||
|
||||
void Utils::GetAllFiles(const string &path, vector<string> &file_vec) {
|
||||
// split file path
|
||||
vector<string> path_vector;
|
||||
SplitPath(path, path_vector);
|
||||
|
||||
for (string every_path : path_vector) {
|
||||
// check path exist or not
|
||||
if (!IsPathExist(path)) {
|
||||
ERROR_LOG("Failed to deal path=%s. Reason: not exist or can not access.",
|
||||
every_path.c_str());
|
||||
continue;
|
||||
}
|
||||
// get files in path and sub-path
|
||||
GetPathFiles(every_path, file_vec);
|
||||
}
|
||||
}
|
||||
|
||||
void Utils::GetPathFiles(const string &path, vector<string> &file_vec) {
|
||||
struct dirent *dirent_ptr = nullptr;
|
||||
DIR *dir = nullptr;
|
||||
if (IsDirectory(path)) {
|
||||
dir = opendir(path.c_str());
|
||||
while ((dirent_ptr = readdir(dir)) != nullptr) {
|
||||
// skip . and ..
|
||||
if (dirent_ptr->d_name[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// file path
|
||||
string full_path = path + kPathSeparator + dirent_ptr->d_name;
|
||||
// directory need recursion
|
||||
if (IsDirectory(full_path)) {
|
||||
GetPathFiles(full_path, file_vec);
|
||||
} else {
|
||||
// put file
|
||||
file_vec.emplace_back(full_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
file_vec.emplace_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
bool Utils::Preprocess(shared_ptr<ConsoleParams> &image_path,
|
||||
const string &path) {
|
||||
// read image using OPENCV
|
||||
cv::Mat mat = cv::imread(path, CV_LOAD_IMAGE_COLOR);
|
||||
//resize
|
||||
cv::Mat mat_rs;
|
||||
cv::resize(mat, mat_rs, cv::Size(MODEL_INPUT_WIDTH, MODEL_INPUT_HEIGHT));
|
||||
|
||||
if (mat.empty()) {
|
||||
ERROR_LOG("read image failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// set property
|
||||
image_path->input_path = path;
|
||||
image_path->img_width = mat_rs.cols;
|
||||
image_path->img_height = mat_rs.rows;
|
||||
|
||||
// set image data
|
||||
uint32_t size = mat_rs.rows * mat_rs.cols*3;
|
||||
void *image_buf_ptr = nullptr;
|
||||
aclrtMalloc(&image_buf_ptr, (size_t)(size), ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
|
||||
if (image_buf_ptr == nullptr) {
|
||||
ERROR_LOG("new image buffer failed.");
|
||||
return false;
|
||||
}
|
||||
aclError mem_ret = aclrtMemcpy(image_buf_ptr, size, mat_rs.ptr<u_int8_t>(), size, ACL_MEMCPY_DEVICE_TO_DEVICE);
|
||||
|
||||
if (mem_ret != 0) {
|
||||
aclrtFree(image_buf_ptr);
|
||||
delete[] (u_int8_t *)image_buf_ptr;
|
||||
ERROR_LOG("memcpy_s failed.");
|
||||
image_buf_ptr = nullptr;
|
||||
return false;
|
||||
}
|
||||
image_path->size = size;
|
||||
image_path->data.reset((u_int8_t *)image_buf_ptr,
|
||||
[](u_int8_t* p){
|
||||
aclrtFree(p);});
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user