Initial commit

This commit is contained in:
2020-10-17 15:44:27 +02:00
commit 39e08c139e
15 changed files with 1095 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
{
"type": "Ascend ACL App",
"project_type": "Custom",
"project_desc": "",
"target": "",
"target_id": "",
"adk_version": "1.73.T5.0.B050"
}
+9
View File
@@ -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")
+14
View File
@@ -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
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

+109
View File
@@ -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_;
};
+71
View File
@@ -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
View File
@@ -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);
};
View File
+65
View File
@@ -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})
+1
View File
@@ -0,0 +1 @@
{}
+52
View File
@@ -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;
}
+269
View File
@@ -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_;
}
+178
View File
@@ -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
View File
@@ -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;
}