mirror of
https://github.com/Ascend/ascend_community_projects.git
synced 2025-09-26 20:01:17 +08:00
retinaface submit
This commit is contained in:
40
Retinaface/CMakeLists.txt
Normal file
40
Retinaface/CMakeLists.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(retinaface)
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
include_directories(./RetinafacePostProcess)
|
||||
include_directories(./RetinafaceDetection)
|
||||
include_directories(/usr/local/Ascend/ascend-toolkit/latest/arm64-linux/runtime/include/)
|
||||
file(GLOB_RECURSE Retinaface_POSTPROCESS ${PROJECT_SOURCE_DIR}/RetinafacePostProcess/*cpp)
|
||||
file(GLOB_RECURSE Retinaface_DETECTION ${PROJECT_SOURCE_DIR}/RetinafaceDetection/*cpp)
|
||||
set(TARGET retinaface)
|
||||
add_compile_options(-std=c++11 -fPIE -fstack-protector-all -fPIC -Wl,-z,relro,-z,now,-z,noexecstack -s -pie -Wall)
|
||||
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0 -Dgoogle=mindxsdk_private)
|
||||
|
||||
set(MX_SDK_HOME "$ENV{MX_SDK_HOME}")
|
||||
|
||||
include_directories(
|
||||
${MX_SDK_HOME}/include
|
||||
${MX_SDK_HOME}/opensource/include
|
||||
${MX_SDK_HOME}/opensource/include/opencv4
|
||||
${MX_SDK_HOME}/include/MxBase/postprocess/include
|
||||
/usr/local/Ascend/ascend-toolkit/latest/include
|
||||
)
|
||||
|
||||
link_directories(
|
||||
${MX_SDK_HOME}/lib
|
||||
${MX_SDK_HOME}/opensource/lib
|
||||
${MX_SDK_HOME}/lib/modelpostprocessors
|
||||
/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64
|
||||
/usr/local/Ascend/driver/lib64/
|
||||
)
|
||||
|
||||
add_executable(retinaface main.cpp ${Retinaface_DETECTION} ${Retinaface_POSTPROCESS})
|
||||
target_link_libraries(retinaface
|
||||
glog
|
||||
mxbase
|
||||
cpprest
|
||||
opencv_world
|
||||
boost_filesystem
|
||||
)
|
177
Retinaface/README.md
Normal file
177
Retinaface/README.md
Normal file
@@ -0,0 +1,177 @@
|
||||
## Retinaface目标检测
|
||||
|
||||
## 1 介绍
|
||||
|
||||
本开发样例是基于mxBase开发的端到端推理的C++应用程序,可在昇腾芯片上进行 Retinaface目标检测,并把可视化结果保存到本地。其中包含Retinaface的后处理模块开发。
|
||||
|
||||
### 1.1 支持的产品
|
||||
|
||||
本产品以昇腾310(推理)卡为硬件平台。
|
||||
|
||||
### 1.2 支持的版本
|
||||
|
||||
该项目支持的SDK版本为2.0.4,CANN版本为5.0.4。
|
||||
|
||||
|
||||
|
||||
### 1.3 软件方案介绍
|
||||
|
||||
表1.1 系统方案各子系统功能描述:
|
||||
|
||||
| 序号 | 子系统 | 功能描述 |
|
||||
| ---- | -------------- | ------------------------------------------------------------ |
|
||||
| 1 | 图片输入 | 接收外部调用接口的输入视频路径,对视频进行拉流,并将拉去的裸流存储到缓冲区(buffer)中,并发送到下游插件。 |
|
||||
| 2 | 模型推理插件 | 目标检测。 |
|
||||
| 3 | 模型后处理插件 | 对模型输出的张量进行后处理,得到物体类型数据。 |
|
||||
|
||||
|
||||
|
||||
### 1.4 代码目录结构与说明
|
||||
|
||||
本项目名为Retinaface目标检测,项目目录如下所示:
|
||||
|
||||
````
|
||||
.
|
||||
├── build.sh
|
||||
├── config
|
||||
│ ├── aipp.cfg
|
||||
├── CMakeLists.txt
|
||||
├── main.cpp
|
||||
├── models
|
||||
│ ├── newRetinaface.om
|
||||
│ └── run.sh
|
||||
├── README.md
|
||||
├── RetinafaceDetection
|
||||
│ ├── RetinafaceDetection.cpp
|
||||
│ └── RetinafaceDetection.h
|
||||
├── RetinafacePostProcess
|
||||
│ ├── RetinafacePostProcess.cpp
|
||||
│ └── RetinafacePostProcess.h
|
||||
````
|
||||
|
||||
|
||||
|
||||
### 1.5 技术实现流程图
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### 1.6 特性及适用场景
|
||||
|
||||
本项目根据widerface数据集训练得到,适用于人脸检测,并且将人脸位置与五官位置标出。
|
||||
|
||||
适用于测试图片中有人脸的情况。若测试图片中没有人脸则无法运行
|
||||
|
||||
|
||||
|
||||
|
||||
## 2 环境依赖
|
||||
|
||||
推荐系统为ubuntu 18.04,环境软件和版本如下:
|
||||
|
||||
| 软件名称 | 版本 | 说明 | 获取方式 |
|
||||
| ------------------- | ----- | ----------------------------- | :-------------------------------------------------------- |
|
||||
| MindX SDK | 2.0.4 | mxVision软件包 | [链接](https://www.hiascend.com/software/Mindx-sdk) |
|
||||
| ubuntu | 18.04 | 操作系统 | 请上ubuntu官网获取 |
|
||||
| Ascend-CANN-toolkit | 5.0.4 | Ascend-cann-toolkit开发套件包 | [链接](https://www.hiascend.com/software/cann/commercial) |
|
||||
|
||||
|
||||
|
||||
在编译运行项目前,需要设置环境变量:
|
||||
|
||||
MindSDK 环境变量:
|
||||
|
||||
```
|
||||
. ${SDK-path}/set_env.sh
|
||||
```
|
||||
|
||||
CANN 环境变量:
|
||||
|
||||
```
|
||||
. ${ascend-toolkit-path}/set_env.sh
|
||||
```
|
||||
|
||||
- 环境变量介绍
|
||||
|
||||
```
|
||||
SDK-path: SDK mxVision 安装路径
|
||||
ascend-toolkit-path: CANN 安装路径
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## 3 软件依赖说明
|
||||
|
||||
本项目无特定软件依赖。
|
||||
|
||||
|
||||
|
||||
## 4 模型转化
|
||||
|
||||
本项目中使用的模型是Retinaface模型,onnx模型可以直接[下载](https://www.hiascend.com/zh/software/modelzoo/models/detail/1/7270b02a457d4c4ab262277a646517f9)。下载后解包,得到`Retinaface.onnx`,使用模型转换工具ATC将onnx模型转换为om模型,模型转换工具相关介绍参考[链接](https://support.huaweicloud.com/tg-cannApplicationDev330/atlasatc_16_0005.html)
|
||||
|
||||
模型转换步骤如下:
|
||||
|
||||
1、按照2环境依赖设置环境变量
|
||||
|
||||
2、`cd`到`model`文件夹,运行
|
||||
|
||||
````
|
||||
bash run.sh
|
||||
````
|
||||
|
||||
3、执行该命令后会在指定输出.om模型路径生成项目指定模型文件newRetinaface.om。若模型转换成功则输出:
|
||||
|
||||
```
|
||||
ATC start working now, please wait for a moment.
|
||||
ATC run success, welcome to the next use.
|
||||
```
|
||||
|
||||
aipp文件配置如下:
|
||||
|
||||
```
|
||||
aipp_op {
|
||||
aipp_mode: static
|
||||
|
||||
input_format :RGB888_U8
|
||||
src_image_size_w :1000
|
||||
src_image_size_h :1000
|
||||
|
||||
mean_chn_0 :104
|
||||
mean_chn_1 :117
|
||||
mean_chn_2 :123
|
||||
|
||||
var_reci_chn_0 :1
|
||||
var_reci_chn_1 :1
|
||||
var_reci_chn_2 :1
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 5 编译运行
|
||||
|
||||
**步骤1** 修改`CMakeLists.txt`文件 将`set(MX_SDK_HOME ${SDK安装路径})` 中的`${SDK安装路径}`替换为实际的SDK安装路径
|
||||
|
||||
**步骤2** 按照**2环境依赖**设置环境变量。
|
||||
|
||||
**步骤3** 在项目主目录下执行如下编译命令:
|
||||
|
||||
````
|
||||
bash build.sh
|
||||
````
|
||||
|
||||
**步骤4** 制定jpg图片进行推理,准备一张推理图片放入主目录下。eg:推理图片为test.jpg
|
||||
|
||||
```
|
||||
./Retinaface ./test.jpg
|
||||
```
|
||||
|
||||
得到`result.jpg`即为输出结果。
|
||||
|
||||
## 6 精度测试
|
||||
|
||||
本项目的所用模型和后处理插件编写都和https://gitee.com/bayf3/mindxsdk-referenceapps/tree/master/contrib/Retinaface地址处的一致。详细的精度测试请参考该代码。
|
283
Retinaface/RetinafaceDetection/RetinafaceDetection.cpp
Normal file
283
Retinaface/RetinafaceDetection/RetinafaceDetection.cpp
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* 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 "opencv2/opencv.hpp"
|
||||
#include "RetinafaceDetection.h"
|
||||
#include "MxBase/DeviceManager/DeviceManager.h"
|
||||
#include "MxBase/Log/Log.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "boost/filesystem.hpp"
|
||||
#include <boost/filesystem.hpp>
|
||||
namespace fs = boost::filesystem;
|
||||
using namespace MxBase;
|
||||
|
||||
namespace {
|
||||
const uint32_t IMAGE_SIZE = 1000;
|
||||
const int NETINPUTSIZE = 1000;
|
||||
std::string imagePath;
|
||||
int originImageW;
|
||||
int originImageH;
|
||||
float resize;
|
||||
int padLeft;
|
||||
int padRight;
|
||||
int padTop;
|
||||
int padBottom;
|
||||
const uint32_t YUV_BYTE_NU = 3;
|
||||
const uint32_t YUV_BYTE_DE = 2;
|
||||
const uint32_t VPC_H_ALIGN = 2;
|
||||
}
|
||||
void RetinafaceDetection::SetRetinafacePostProcessConfig(const InitParam &initParam, std::map<std::string, std::shared_ptr<void>> &config)
|
||||
{
|
||||
MxBase::ConfigData configData;
|
||||
const std::string checkTensor = initParam.checkTensor ? "true" : "false";
|
||||
configData.SetJsonValue("CHECK_MODEL", checkTensor);
|
||||
configData.SetJsonValue("CLASS_NUM", std::to_string(initParam.classNum));
|
||||
auto jsonStr = configData.GetCfgJson().serialize();
|
||||
config["postProcessConfigContent"] = std::make_shared<std::string>(jsonStr);
|
||||
config["labelPath"] = std::make_shared<std::string>(initParam.labelPath);
|
||||
}
|
||||
APP_ERROR RetinafaceDetection::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;
|
||||
}
|
||||
// init Retinafacepostprocess
|
||||
std::map<std::string, std::shared_ptr<void>> config;
|
||||
SetRetinafacePostProcessConfig(initParam, config);
|
||||
post_ = std::make_shared<RetinafacePostProcess>();
|
||||
cv::Mat originalImage = cv::imread(initParam.ImagePath);
|
||||
ret = post_->Init(config, originalImage.rows, originalImage.cols);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "Retinafacepostprocess init failed, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR RetinafaceDetection::DeInit() {
|
||||
dvppWrapper_->DeInit();
|
||||
model_->DeInit();
|
||||
post_->DeInit();
|
||||
MxBase::DeviceManager::GetInstance()->DestroyDevices();
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
// 获取图像数据,将数据存入TensorBase中
|
||||
APP_ERROR RetinafaceDetection::ReadImage(const std::string &imgPath, cv::Mat &imageMat) {
|
||||
imageMat = cv::imread(imgPath, cv::IMREAD_COLOR);
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR RetinafaceDetection::CVMatToTensorBase(const cv::Mat &imageMat, MxBase::TensorBase &tensorBase)
|
||||
{
|
||||
const uint32_t dataSize = imageMat.cols * imageMat.rows * YUV444_RGB_WIDTH_NU;
|
||||
LogInfo << "image size " << imageMat.cols << " " << imageMat.rows;
|
||||
MemoryData memoryDataDst(dataSize, MemoryData::MEMORY_DEVICE, deviceId_);
|
||||
MemoryData memoryDataSrc(imageMat.data, dataSize, MemoryData::MEMORY_HOST_MALLOC);
|
||||
|
||||
APP_ERROR ret = MemoryHelper::MxbsMallocAndCopy(memoryDataDst, memoryDataSrc);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << GetError(ret) << "Memory malloc failed.";
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> shape = {imageMat.rows * YUV444_RGB_WIDTH_NU, static_cast<uint32_t>(imageMat.cols)};
|
||||
tensorBase = TensorBase(memoryDataDst, false, shape, TENSOR_DTYPE_UINT8);
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 模型推理
|
||||
APP_ERROR RetinafaceDetection::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);
|
||||
}
|
||||
// print the shape and type of inputs
|
||||
std::cout << "inputs size = "<<inputs[0].GetSize() << "\n";
|
||||
std::cout << "inputs GetByteSize = "<<inputs[0].GetByteSize() << "\n";
|
||||
std::cout << "inputs number = "<< inputs.size() << "\n";
|
||||
std::cout << "inputs shape size = "<< inputs[0].GetShape().size() << "\n";
|
||||
std::cout << "Data type = "<< inputs[0].GetDataType() << "\n";
|
||||
for (size_t i = 0; i<inputs[0].GetShape().size(); i++) {
|
||||
std::cout << "value = ";
|
||||
std::cout << inputs[0].GetShape()[i] << " ";
|
||||
}
|
||||
DynamicInfo dynamicInfo = {};
|
||||
dynamicInfo.dynamicType = DynamicType::STATIC_BATCH;
|
||||
LogInfo << "Ready to infer.";
|
||||
APP_ERROR ret = model_->ModelInference(inputs, outputs, dynamicInfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "ModelInference failed, ret=" << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
LogInfo << "End to model inference.";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
// 后处理
|
||||
APP_ERROR RetinafaceDetection::PostProcess(const std::vector<MxBase::TensorBase>& outputs,
|
||||
std::vector<std::vector<MxBase::ObjectInfo>>& objInfos)
|
||||
{
|
||||
LogInfo << "start postprocess.\n";
|
||||
APP_ERROR ret = post_->Process(outputs, objInfos);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "Process failed, ret=" << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = post_->DeInit();
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "RetinafacePostProcess DeInit failed";
|
||||
return ret;
|
||||
}
|
||||
LogInfo << "End to Retinafacepostprocess.";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR RetinafaceDetection::WriteResult(const std::string& imgPath,
|
||||
const std::vector<std::vector<MxBase::ObjectInfo>>& objInfos)
|
||||
{
|
||||
LogInfo << "start write result.";
|
||||
cv::Mat writeImage = cv::imread(imagePath);
|
||||
uint32_t objInfosSize = objInfos.size();
|
||||
std::vector<MxBase::ObjectInfo> resultInfo;
|
||||
std::cout << "objInfo number = " << objInfosSize << std::endl;
|
||||
for (uint32_t i = 0; i<objInfosSize; i++) {
|
||||
for (uint32_t j = 0; j<objInfos[i].size(); j++) {
|
||||
resultInfo.push_back(objInfos[i][j]);
|
||||
}
|
||||
LogInfo << "result box number is : " << resultInfo.size();
|
||||
for (uint32_t j = 0; j<resultInfo.size(); j++) {
|
||||
/* 打印后处理之后的所有结果 */
|
||||
// std::cout << "resultInfo[j].x0 = " << resultInfo[j].x0 << ", " << "resultInfo[j].x1 = " << resultInfo[j].x1 << ", " << ""
|
||||
const uint32_t thickness = 2;
|
||||
const cv::Scalar black = cv::Scalar(0, 0, 0);
|
||||
int X0 = std::max((int)((resultInfo[j].x0 - padLeft) / resize), 0);
|
||||
int X1 = std::max((int)((resultInfo[j].x1 - padLeft) / resize), 0);
|
||||
int Y0 = std::max((int)((resultInfo[j].y0 - padTop) / resize), 0);
|
||||
int Y1 = std::max((int)((resultInfo[j].y1 - padTop) / resize), 0);
|
||||
cv::Point2i c1(X0, Y0);
|
||||
cv::Point2i c2(X1, Y1);
|
||||
cv::rectangle(writeImage, cv::Rect(X0, Y0, X1-X0, Y1-Y0), black, thickness);
|
||||
}
|
||||
}
|
||||
cv::imwrite("./result.jpg", writeImage);
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR RetinafaceDetection::Process(const std::string& imgPath) {
|
||||
imagePath = imgPath;
|
||||
cv::Mat originImage = cv::imread(imgPath);
|
||||
if (originImage.data == NULL) {
|
||||
LogInfo << "The image is not exist.\n";
|
||||
return 0;
|
||||
}
|
||||
originImageW = originImage.cols;
|
||||
originImageH = originImage.rows;
|
||||
int imgsizeMax = originImageW;
|
||||
if (imgsizeMax < originImageH) {
|
||||
imgsizeMax = originImageH;
|
||||
}
|
||||
resize = (IMAGE_SIZE * 1.0 ) / (imgsizeMax * 1.0);
|
||||
cv::Mat newImg;
|
||||
cv::resize(originImage, newImg, cv::Size(), resize, resize, cv::INTER_NEAREST);
|
||||
padRight = IMAGE_SIZE - newImg.cols;
|
||||
padLeft = 0;
|
||||
padBottom = IMAGE_SIZE - newImg.rows;
|
||||
padTop = 0;
|
||||
cv::Mat nnImage;
|
||||
cv::copyMakeBorder(newImg, nnImage, padTop, padBottom, padLeft, padRight,
|
||||
cv::BORDER_CONSTANT, 0);
|
||||
std::cout<< "nnImage W = " << nnImage.cols << " " << "nnImage H = " << nnImage.rows << "\n";
|
||||
std::string newImagePath = "./ImageforInfer.jpg";
|
||||
cv::imwrite(newImagePath, nnImage);
|
||||
cv::Mat imageMat;
|
||||
APP_ERROR ret = ReadImage(newImagePath, imageMat);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "ReadImage failed, ret=" << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
std::vector<MxBase::TensorBase> inputs = {};
|
||||
std::vector<MxBase::TensorBase> outputs = {};
|
||||
TensorBase tensorBase;
|
||||
ret = CVMatToTensorBase(imageMat, tensorBase);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "CVMatToTensorBase failed, ret=" << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
inputs.push_back(tensorBase);
|
||||
|
||||
ret = Inference(inputs, outputs);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "Inference failed, ret=" << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::vector<MxBase::ObjectInfo>> objInfos;
|
||||
std::cout << std::endl;
|
||||
std::cout << "outputSize = " << outputs.size() << std::endl;
|
||||
for (uint32_t i = 0; i<outputs.size(); i++) {
|
||||
for (uint32_t j = 0; j<outputs[i].GetShape().size(); j++) {
|
||||
std::printf("outputs[%d][%d] = %d. ", i, j, outputs[i].GetShape()[j]);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
ret = PostProcess(outputs, objInfos);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "PostProcess failed, ret=" << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = WriteResult(imgPath, objInfos);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "Save result failed, ret=" << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
57
Retinaface/RetinafaceDetection/RetinafaceDetection.h
Normal file
57
Retinaface/RetinafaceDetection/RetinafaceDetection.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 MXBASE_RetinafaceDETECTION_H
|
||||
#define MXBASE_RetinafaceDETECTION_H
|
||||
|
||||
#include <RetinafacePostProcess.h>
|
||||
#include "MxBase/DvppWrapper/DvppWrapper.h"
|
||||
#include "MxBase/ModelInfer/ModelInferenceProcessor.h"
|
||||
#include "MxBase/Tensor/TensorContext/TensorContext.h"
|
||||
|
||||
struct InitParam {
|
||||
uint32_t deviceId;
|
||||
bool checkTensor;
|
||||
std::string modelPath;
|
||||
std::string labelPath;
|
||||
uint32_t classNum;
|
||||
std::string ImagePath;
|
||||
};
|
||||
|
||||
class RetinafaceDetection {
|
||||
public:
|
||||
APP_ERROR Init(const InitParam& initParam);
|
||||
APP_ERROR DeInit();
|
||||
APP_ERROR Inference(const std::vector<MxBase::TensorBase>& inputs, std::vector<MxBase::TensorBase>& outputs);
|
||||
APP_ERROR PostProcess(const std::vector<MxBase::TensorBase>& outputs, std::vector<std::vector<MxBase::ObjectInfo>>& objInfos);
|
||||
APP_ERROR CVMatToTensorBase(const cv::Mat &imageMat, MxBase::TensorBase &tensorBase);
|
||||
APP_ERROR Process(const std::string& imgPath);
|
||||
APP_ERROR ReadImage(const std::string &imgPath, cv::Mat &imageMat);
|
||||
APP_ERROR WriteResult(const std::string& imgPath,
|
||||
const std::vector<std::vector<MxBase::ObjectInfo>>& objInfos);
|
||||
void SetRetinafacePostProcessConfig(
|
||||
const InitParam &initParam,
|
||||
std::map<std::string, std::shared_ptr<void>> &config
|
||||
);
|
||||
private:
|
||||
std::shared_ptr<MxBase::DvppWrapper> dvppWrapper_;
|
||||
std::shared_ptr<MxBase::ModelInferenceProcessor> model_;
|
||||
std::shared_ptr<RetinafacePostProcess> post_;
|
||||
MxBase::ModelDesc modelDesc_;
|
||||
uint32_t deviceId_ = 0;
|
||||
};
|
||||
|
||||
#endif
|
271
Retinaface/RetinafacePostProcess/RetinafacePostProcess.cpp
Normal file
271
Retinaface/RetinafacePostProcess/RetinafacePostProcess.cpp
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* 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 "RetinafacePostProcess.h"
|
||||
#include "MxBase/Log/Log.h"
|
||||
#include "MxBase/Maths/FastMath.h"
|
||||
#include "MxBase/CV/ObjectDetection/Nms/Nms.h"
|
||||
#include <map>
|
||||
|
||||
namespace {
|
||||
const uint32_t LEFTTOPX = 0;
|
||||
const uint32_t LEFTTOPY = 1;
|
||||
const uint32_t RIGHTTOPX = 2;
|
||||
const uint32_t RIGHTTOPY = 3;
|
||||
const int PRIOR_PARAMETERS[3][2] = {{16, 32}, {64, 128}, {256, 512}};
|
||||
const int PRIOR_PARAMETERS_COUNT = 2;
|
||||
const float IMAGE_WIDTH = 1000.0;
|
||||
const float IMAGE_HEIGHT = 1000.0;
|
||||
const float STEPS[3] = {8.0, 16.0, 32.0};
|
||||
const float VARIANCE[2] = {0.1, 0.2};
|
||||
const uint32_t RECTANGLEPOINT = 4;
|
||||
const uint32_t KEYPOINTNUM = 5;
|
||||
const uint32_t POINT_SIZE = 1;
|
||||
const uint32_t DIM = 2;
|
||||
const uint32_t RECTANGLE_COLOR = 1;
|
||||
const uint32_t KEYPOINT_COLOR = 2;
|
||||
const uint32_t DIV_TWO = 2;
|
||||
uint32_t ORIGIALWIDE;
|
||||
uint32_t ORIGINALHEIGHT;
|
||||
}
|
||||
using namespace MxBase;
|
||||
|
||||
RetinafacePostProcess& RetinafacePostProcess::operator=(const RetinafacePostProcess& other) {
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
ObjectPostProcessBase::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
APP_ERROR RetinafacePostProcess::Init(const std::map<std::string, std::shared_ptr<void>>& postConfig, const int& OriginWide, const int& OriginHeight) {
|
||||
LogDebug << "Start to Init RetinafacePostProcess.";
|
||||
ORIGIALWIDE = OriginWide;
|
||||
ORIGINALHEIGHT = OriginHeight;
|
||||
APP_ERROR ret = ObjectPostProcessBase::Init(postConfig);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << GetError(ret) << "Fail to superInit in ObjectPostProcessBase.";
|
||||
return ret;
|
||||
}
|
||||
LogInfo << "End to Init RetinafacePostprocess.";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR RetinafacePostProcess::DeInit() {
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
void RetinafacePostProcess::ObjectDetectionOutput(const std::vector <TensorBase>& tensors,
|
||||
std::vector <std::vector<ObjectInfo>>& objectInfos,
|
||||
const std::vector <ResizedImageInfo>& resizedImageInfos)
|
||||
{
|
||||
LogInfo << "RetinafacePostProcess start to write results.";
|
||||
std::cout << "\n";
|
||||
std::cout << "tensorsSize =" << tensors.size() << "\n";
|
||||
for (uint32_t i = 0; i<tensors.size(); i++) {
|
||||
for (uint32_t j = 0; j<tensors[i].GetShape().size(); j++) {
|
||||
std::printf("tensors[%d][%d] = %d .", i, j, tensors[i].GetShape()[j]);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
for (auto num : { objectInfoTensor_, objectConfTensor_ }) {
|
||||
if ((num >= tensors.size()) || (num < 0)) {
|
||||
LogError << GetError(APP_ERR_INVALID_PARAM) << "TENSOR(" << num
|
||||
<< ") must ben less than tensors'size(" << tensors.size() << ") and larger than 0.";
|
||||
}
|
||||
}
|
||||
auto shape = tensors[0].GetShape();
|
||||
auto keyshape = tensors[2].GetShape();
|
||||
|
||||
cv::Mat PriorBox;
|
||||
cv::Mat location = cv::Mat(shape[1], shape[2], CV_32FC1, tensors[0].GetBuffer());
|
||||
cv::Mat keylocation = cv::Mat(keyshape[1], keyshape[2], CV_32FC1, tensors[2].GetBuffer());
|
||||
GeneratePriorBox(PriorBox);
|
||||
|
||||
float width_resize = 1000;
|
||||
float height_resize = 1000;
|
||||
float width_original = 1000;
|
||||
float height_original = 1000;
|
||||
float width_resize_scale = width_resize / (width_original * 1.0);
|
||||
float height_resize_scale = height_resize / (height_original * 1.0);
|
||||
float resize_scale_factor = 1.0;
|
||||
if (width_resize_scale >= height_resize_scale) {
|
||||
resize_scale_factor = height_resize_scale;
|
||||
} else {
|
||||
resize_scale_factor = width_resize_scale;
|
||||
}
|
||||
|
||||
cv::Mat res = decode_for_loc(location, PriorBox, keylocation, resize_scale_factor);
|
||||
|
||||
uint32_t batchSize = shape[0];
|
||||
uint32_t VectorNum = shape[1];
|
||||
|
||||
std::map<ObjectInfo, KeyPointDetectionInfo> match;
|
||||
for (uint32_t i = 0; i < batchSize; i++) {
|
||||
std::vector <ObjectInfo> objectInfo;
|
||||
std::vector <ObjectInfo> objectInfoSorted;
|
||||
std::vector <KeyPointDetectionInfo> keypointInfo;
|
||||
std::vector <KeyPointDetectionInfo> keypointInfoSorted;
|
||||
auto dataPtr_Conf = (float *) tensors[1].GetBuffer() + i * tensors[1].GetByteSize() / batchSize;
|
||||
|
||||
for (uint32_t j = 0; j < VectorNum; j++) {
|
||||
float* begin_Conf = dataPtr_Conf + j * 2;
|
||||
float conf = *(begin_Conf + 1);
|
||||
|
||||
if (conf > confThresh_) {
|
||||
ObjectInfo objInfo;
|
||||
objInfo.confidence = j;
|
||||
objInfo.x0 = res.at<float>(j, LEFTTOPX) * IMAGE_WIDTH / width_resize_scale;
|
||||
objInfo.y0 = res.at<float>(j, LEFTTOPY) * IMAGE_HEIGHT / height_resize_scale;
|
||||
objInfo.x1 = res.at<float>(j, RIGHTTOPX) * IMAGE_WIDTH / width_resize_scale;
|
||||
objInfo.y1 = res.at<float>(j, RIGHTTOPY) * IMAGE_HEIGHT / height_resize_scale;
|
||||
objInfo.classId = RECTANGLE_COLOR;
|
||||
|
||||
objectInfo.push_back(objInfo);
|
||||
}
|
||||
}
|
||||
MxBase::NmsSort(objectInfo, iouThresh_);
|
||||
|
||||
for (uint32_t j = 0; j < objectInfo.size(); j++) {
|
||||
ObjectInfo obj = objectInfo[j];
|
||||
KeyPointDetectionInfo kpInfo;
|
||||
int keypoint_Pos = objectInfo[j].confidence;
|
||||
float* begin_Conf = dataPtr_Conf + keypoint_Pos * 2;
|
||||
float conf = *(begin_Conf + 1);
|
||||
objectInfo[j].confidence = conf;
|
||||
objectInfoSorted.push_back(objectInfo[j]);
|
||||
|
||||
for (uint32_t k = 0; k < KEYPOINTNUM; k++)
|
||||
{
|
||||
float x = res.at<float>(keypoint_Pos, RECTANGLEPOINT + k * DIM) * IMAGE_WIDTH / width_resize_scale;
|
||||
float y = res.at<float>(keypoint_Pos, RECTANGLEPOINT + k * DIM + 1) * IMAGE_HEIGHT / height_resize_scale;
|
||||
ObjectInfo objInfo;
|
||||
|
||||
objInfo.x0= x - POINT_SIZE;
|
||||
objInfo.x1= x + POINT_SIZE;
|
||||
objInfo.y0= y - POINT_SIZE;
|
||||
objInfo.y1= y + POINT_SIZE;
|
||||
objInfo.confidence = 0;
|
||||
objInfo.classId = KEYPOINT_COLOR;
|
||||
objectInfoSorted.push_back(objInfo);
|
||||
}
|
||||
}
|
||||
|
||||
objectInfos.push_back(objectInfoSorted);
|
||||
}
|
||||
LogInfo << "Retinaface write results successed.";
|
||||
}
|
||||
APP_ERROR RetinafacePostProcess::Process(const std::vector<TensorBase>& tensors,
|
||||
std::vector<std::vector<ObjectInfo>>& objectInfos,
|
||||
const std::vector<ResizedImageInfo>& resizedImageInfos,
|
||||
const std::map<std::string, std::shared_ptr<void>>& configParamMap)
|
||||
{
|
||||
LogInfo << "Start to Process RetinafacePostProcess.";
|
||||
APP_ERROR ret = APP_ERR_OK;
|
||||
auto inputs = tensors;
|
||||
ret = CheckAndMoveTensors(inputs);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "CheckAndMoveTensors failed. ret=" << ret;
|
||||
return ret;
|
||||
}
|
||||
ObjectDetectionOutput(inputs, objectInfos, resizedImageInfos);
|
||||
LogInfo << "End to Process RetinafacePostProcess.";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
void RetinafacePostProcess::GeneratePriorBox(cv::Mat& anchors)
|
||||
{
|
||||
std::vector<std::vector<int>>feature_maps(RIGHTTOPY, std::vector<int>(DIM));
|
||||
for (uint32_t i = 0; i < feature_maps.size(); i++) {
|
||||
feature_maps[i][0] = ceil(IMAGE_HEIGHT / STEPS[i]);
|
||||
feature_maps[i][1] = ceil(IMAGE_WIDTH / STEPS[i]);
|
||||
}
|
||||
for (uint32_t k = 0; k < feature_maps.size(); k++) {
|
||||
auto f = feature_maps[k];
|
||||
|
||||
float step = (float)STEPS[k];
|
||||
for (int i = 0; i < f[0]; i++) {
|
||||
for (int j = 0; j < f[1]; j++) {
|
||||
for (int l = 0; l < PRIOR_PARAMETERS_COUNT && PRIOR_PARAMETERS[k][l] != -1; l++) {
|
||||
float min_size = PRIOR_PARAMETERS[k][l];
|
||||
cv::Mat anchor(1, RECTANGLEPOINT * DIM, CV_32F);
|
||||
float center_x = (j + 0.5f) * step;
|
||||
float center_y = (i + 0.5f) * step;
|
||||
|
||||
float xmin = (center_x - min_size / 2.f) / IMAGE_WIDTH;
|
||||
float ymin = (center_y - min_size / 2.f) / IMAGE_HEIGHT;
|
||||
float xmax = (center_x + min_size / 2.f) / IMAGE_WIDTH;
|
||||
float ymax = (center_y + min_size / 2.f) / IMAGE_HEIGHT;
|
||||
|
||||
float prior_width = xmax - xmin;
|
||||
float prior_height = ymax - ymin;
|
||||
float prior_center_x = (xmin + xmax) / 2;
|
||||
float prior_center_y = (ymin + ymax) / 2;
|
||||
|
||||
anchor.at<float>(0, LEFTTOPX) = center_x / IMAGE_WIDTH;
|
||||
anchor.at<float>(0, LEFTTOPY) = center_y / IMAGE_HEIGHT;
|
||||
anchor.at<float>(0, RIGHTTOPX) = min_size / IMAGE_WIDTH;
|
||||
anchor.at<float>(0, RIGHTTOPY) = min_size / IMAGE_HEIGHT;
|
||||
|
||||
anchor.at<float>(0, LEFTTOPX + RECTANGLEPOINT) = prior_width;
|
||||
anchor.at<float>(0, LEFTTOPY + RECTANGLEPOINT) = prior_height;
|
||||
anchor.at<float>(0, RIGHTTOPX + RECTANGLEPOINT) = prior_center_x;
|
||||
anchor.at<float>(0, RIGHTTOPY + RECTANGLEPOINT) = prior_center_y;
|
||||
|
||||
anchors.push_back(anchor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat RetinafacePostProcess::decode_for_loc(cv::Mat& loc, cv::Mat& prior, cv::Mat& key, float resize_scale_factor) {
|
||||
LogInfo << loc.rows;
|
||||
LogInfo << loc.cols;
|
||||
LogInfo << prior.rows;
|
||||
LogInfo << prior.cols;
|
||||
LogInfo << key.rows;
|
||||
LogInfo << key.cols;
|
||||
cv::Mat loc_first = loc.colRange(0, 2);
|
||||
cv::Mat loc_last = loc.colRange(2, 4);
|
||||
cv::Mat prior_first = prior.colRange(0, 2);
|
||||
cv::Mat prior_last = prior.colRange(2, 4);
|
||||
cv::Mat prior_first2 = prior.colRange(4, 6);
|
||||
cv::Mat prior_last2 = prior.colRange(6, 8);
|
||||
cv::Mat facepoint = key.colRange(0, 10);
|
||||
cv::Mat boxes1 = prior_first + (loc_first * VARIANCE[0]).mul(prior_last);
|
||||
cv::Mat boxes2;
|
||||
cv::exp(loc_last * VARIANCE[1], boxes2);
|
||||
boxes2 = boxes2.mul(prior_last);
|
||||
boxes1 = boxes1 - boxes2 / DIV_TWO;
|
||||
boxes2 = boxes2 + boxes1;
|
||||
cv::Mat boxes3;
|
||||
for (uint32_t i = 0; i < KEYPOINTNUM; i++)
|
||||
{
|
||||
cv::Mat singlepoint = facepoint.colRange(i * 2, (i + 1) * 2);
|
||||
singlepoint = prior_last2 + (singlepoint * VARIANCE[0]).mul(prior_first2);
|
||||
if (i == 0) boxes3 = singlepoint;
|
||||
else cv::hconcat(boxes3, singlepoint, boxes3);
|
||||
}
|
||||
|
||||
cv::Mat boxes;
|
||||
cv::hconcat(boxes1, boxes2, boxes);
|
||||
cv::hconcat(boxes, boxes3, boxes);
|
||||
if (resize_scale_factor == 0) {
|
||||
LogError << "resize_scale_factor is 0.";
|
||||
}
|
||||
return boxes;
|
||||
}
|
58
Retinaface/RetinafacePostProcess/RetinafacePostProcess.h
Normal file
58
Retinaface/RetinafacePostProcess/RetinafacePostProcess.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 Retinaface_POST_PROCESS_H
|
||||
#define Retinaface_POST_PROCESS_H
|
||||
#include "MxBase/PostProcessBases/ObjectPostProcessBase.h"
|
||||
#include "MxBase/CV/ObjectDetection/Nms/Nms.h"
|
||||
#include "opencv2/opencv.hpp"
|
||||
|
||||
#define DEFAULT_OBJECT_CONF_TENSOR 1
|
||||
#define DEFAULT_OBJECT_INFO_TENSOR 0
|
||||
#define DEFAULT_IOU_THRESH 0.4
|
||||
#define DEFAULT_CONFIDENCE_THRESH 0.40
|
||||
|
||||
class RetinafacePostProcess : public MxBase::ObjectPostProcessBase {
|
||||
public:
|
||||
RetinafacePostProcess() = default;
|
||||
|
||||
~RetinafacePostProcess() = default;
|
||||
|
||||
RetinafacePostProcess(const RetinafacePostProcess& other);
|
||||
|
||||
RetinafacePostProcess& operator=(const RetinafacePostProcess& other);
|
||||
|
||||
APP_ERROR Init(const std::map<std::string, std::shared_ptr<void>>& postConfig, const int& OriginWide, const int& OriginHeight);
|
||||
|
||||
APP_ERROR DeInit() override;
|
||||
|
||||
APP_ERROR Process(const std::vector<MxBase::TensorBase>& tensors, std::vector<std::vector<MxBase::ObjectInfo>>& objectInfos,
|
||||
const std::vector<MxBase::ResizedImageInfo>& resizedImageInfos = {},
|
||||
const std::map<std::string, std::shared_ptr<void>>& paramMap = {}) override;
|
||||
protected:
|
||||
|
||||
void ObjectDetectionOutput(const std::vector<MxBase::TensorBase>& tensors,
|
||||
std::vector<std::vector<MxBase::ObjectInfo>>& objectInfos,
|
||||
const std::vector<MxBase::ResizedImageInfo>& resizedImageInfos = {});
|
||||
void GeneratePriorBox(cv::Mat& anchors);
|
||||
cv::Mat decode_for_loc(cv::Mat& loc, cv::Mat& prior, cv::Mat& key, float resize_scale_factor);
|
||||
private:
|
||||
uint32_t objectConfTensor_ = DEFAULT_OBJECT_CONF_TENSOR;
|
||||
uint32_t objectInfoTensor_ = DEFAULT_OBJECT_INFO_TENSOR;
|
||||
float iouThresh_ = DEFAULT_IOU_THRESH;
|
||||
float confThresh_ = DEFAULT_CONFIDENCE_THRESH;
|
||||
};
|
||||
#endif
|
35
Retinaface/build.sh
Normal file
35
Retinaface/build.sh
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 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.
|
||||
|
||||
path_cur="$(dirname "$0")"
|
||||
|
||||
function build_retinaface()
|
||||
{
|
||||
cd "$path_cur" || exit
|
||||
rm -rf build
|
||||
mkdir -p build
|
||||
cd build || exit
|
||||
cmake ..
|
||||
make
|
||||
ret=$?
|
||||
if [ ${ret} -ne 0 ]; then
|
||||
echo "Failed to build retinaface."
|
||||
exit ${ret}
|
||||
fi
|
||||
make install
|
||||
}
|
||||
|
||||
build_retinaface
|
15
Retinaface/config/aipp.cfg
Normal file
15
Retinaface/config/aipp.cfg
Normal file
@@ -0,0 +1,15 @@
|
||||
aipp_op {
|
||||
aipp_mode: static
|
||||
|
||||
input_format :RGB888_U8
|
||||
src_image_size_w :1000
|
||||
src_image_size_h :1000
|
||||
|
||||
mean_chn_0 :104
|
||||
mean_chn_1 :117
|
||||
mean_chn_2 :123
|
||||
|
||||
var_reci_chn_0 :1
|
||||
var_reci_chn_1 :1
|
||||
var_reci_chn_2 :1
|
||||
}
|
0
Retinaface/images/.keep
Normal file
0
Retinaface/images/.keep
Normal file
BIN
Retinaface/images/process.png
Normal file
BIN
Retinaface/images/process.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
60
Retinaface/main.cpp
Normal file
60
Retinaface/main.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 <iostream>
|
||||
#include <vector>
|
||||
#include <RetinafaceDetection.h>
|
||||
#include "MxBase/Log/Log.h"
|
||||
|
||||
std::string imgPath;
|
||||
void InitRetinafaceParam(InitParam& initParam)
|
||||
{
|
||||
initParam.deviceId = 0;
|
||||
initParam.checkTensor = true;
|
||||
initParam.modelPath = "./model/newRetinaface.om";
|
||||
initParam.classNum = 1;
|
||||
initParam.labelPath = "";
|
||||
initParam.ImagePath = imgPath;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc <= 1) {
|
||||
LogWarn << "Please input image path, such as './RetinafacePostProcess test.jpg'.";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
imgPath = argv[1];
|
||||
|
||||
InitParam initParam;
|
||||
InitRetinafaceParam(initParam);
|
||||
auto Retinaface = std::make_shared<RetinafaceDetection>();
|
||||
|
||||
APP_ERROR ret = Retinaface->Init(initParam);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "RetinafaceDetection init failed, ret=" << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ret = Retinaface->Process(imgPath);
|
||||
if (ret != APP_ERR_OK) {
|
||||
LogError << "RetinafaceDetection process failed, ret=" << ret << ".";
|
||||
Retinaface->DeInit();
|
||||
return ret;
|
||||
}
|
||||
Retinaface->DeInit();
|
||||
return APP_ERR_OK;
|
||||
}
|
Reference in New Issue
Block a user