Commit 01c4f6f1 authored by Your Name's avatar Your Name
Browse files

提交yolov3 C++示例

parent 08485b69
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
build/*
depend/*
.vscode/*
core.*
# qtcreator generated files
*.pro.user*
# VS
*.sdf
*.opensdf
*.ilk
*.pdb
*.exp
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
# Executables
*.exe
*.out
*.app
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# others
*.avi
*.pyc
*.egg
#! /bin/sh
############### Ubuntu ###############
# 参考:https://docs.opencv.org/3.4.11/d7/d9f/tutorial_linux_install.html
# apt-get install build-essential -y
# apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev -y
# apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev -y # 处理图像所需的包,可选
############### CentOS ###############
yum install gcc gcc-c++ gtk2-devel gimp-devel gimp-devel-tools gimp-help-browser zlib-devel libtiff-devel libjpeg-devel libpng-devel gstreamer-devel libavc1394-devel libraw1394-devel libdc1394-devel jasper-devel jasper-utils swig python libtool nasm -y
\ No newline at end of file
############################ 在线安装依赖 ###############################
#cd ./3rdParty
#pip install rbuild-master.tar.gz
############################ 离线安装依赖 ###############################
# 安装依赖
cd ./3rdParty/rbuild_depend
pip install click-6.6-py2.py3-none-any.whl
pip install six-1.15.0-py2.py3-none-any.whl
pip install subprocess32-3.5.4.tar.gz
pip install cget-0.1.9.tar.gz
# 安装rbuild
cd ../
pip install rbuild-master.tar.gz
# 设置cmake的最低版本
cmake_minimum_required(VERSION 3.5)
# 设置项目名
project(MIGraphX_Samples)
# 设置编译器
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -std=c++17) # 2.2版本以上需要c++17
set(CMAKE_BUILD_TYPE release)
# 添加头文件路径
set(INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Src/
${CMAKE_CURRENT_SOURCE_DIR}/Src/Utility/
${CMAKE_CURRENT_SOURCE_DIR}/Src/Detector/
$ENV{DTKROOT}/include/
${CMAKE_CURRENT_SOURCE_DIR}/depend/include/)
include_directories(${INCLUDE_PATH})
# 添加依赖库路径
set(LIBRARY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/depend/lib64/
$ENV{DTKROOT}/lib/)
link_directories(${LIBRARY_PATH})
# 添加依赖库
set(LIBRARY opencv_core
opencv_imgproc
opencv_imgcodecs
opencv_dnn
migraphx_ref
migraphx
migraphx_c
migraphx_device
migraphx_gpu
migraphx_onnx)
link_libraries(${LIBRARY})
# 添加源文件
set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/Src/main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Src/Sample.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Src/Detector/DetectorYOLOV3.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Src/Utility/CommonUtility.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Src/Utility/Filesystem.cpp)
# 添加可执行目标
add_executable(MIGraphX_Samples ${SOURCE_FILES})
......@@ -14,7 +14,7 @@ class YOLOv3:
self.nmsThreshold = iou_thres
# 获取模型检测的类别信息
self.classNames = list(map(lambda x: x.strip(), open('./weights/coco.names', 'r').readlines()))
self.classNames = list(map(lambda x: x.strip(), open('../Resource/Models/Detector/YOLOV3/coco.names', 'r').readlines()))
# 解析推理模型
self.model = migraphx.parse_onnx(path)
......@@ -118,8 +118,8 @@ class YOLOv3:
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--imgpath', type=str, default='./images/dog.jpg', help="image path")
parser.add_argument('--modelpath', type=str, default='./weights/yolov3-tiny.onnx', help="onnx filepath")
parser.add_argument('--imgpath', type=str, default='../Resource/Models/images/dog.jpg', help="image path")
parser.add_argument('--modelpath', type=str, default='../Resource/Models/Detector/YOLOV3/yolov3-tiny.onnx', help="onnx filepath")
parser.add_argument('--objectThreshold', default=0.4, type=float, help='class confidence')
parser.add_argument('--confThreshold', default=0.2, type=float, help='class confidence')
parser.add_argument('--nmsThreshold', default=0.4, type=float, help='nms iou thresh')
......
opencv-contrib-python
numpy
os
argparse
time
\ No newline at end of file
......@@ -8,27 +8,83 @@ YOLOV3是由Joseph Redmon和Ali Farhadi在2018年提出的单阶段目标检测
算法基本思想首先通过特征提取网络对输入提取特征,backbone部分由YOLOV2时期的Darknet19进化至Darknet53加深了网络层数,引入了Resnet中的跨层加和操作;然后结合不同卷积层的特征实现多尺度训练,一共有13x13、26x26、52x52三种分辨率,分别用来预测大、中、小的物体;每种分辨率的特征图将输入图像分成不同数量的格子,每个格子预测B个bounding box,每个bounding box预测内容包括: Location(x, y, w, h)、Confidence Score和C个类别的概率,因此YOLOv3输出层的channel数为B*(5 + C)。YOLOv3的loss函数也有三部分组成:Location误差,Confidence误差和分类误差。参考论文地址:https://arxiv.org/abs/1804.02767
## 推理
## 构建安装
在光源可拉取推理的docker镜像,YoloV3工程推荐的镜像如下:
### 环境配置
```python
docker pull image.sourcefind.cn:5000/dcu/admin/base/custom:ort1.14.0_migraphx3.0.0-dtk22.10.1
```
[光源](https://www.sourcefind.cn/#/image/dcu/custom)可拉取用于推理的docker镜像,YoloV3模型推理推荐的镜像如下:
### 安装Opencv依赖
```python
cd <path_to_migraphx_samples>
sh ./3rdParty/InstallOpenCVDependences.sh
```
docker pull image.sourcefind.cn:5000/dcu/admin/base/custom:ort_dcu_1.14.0_migraphx2.5.2_dtk22.10.1
### 修改CMakeLists.txt
- 如果使用ubuntu系统,需要修改CMakeLists.txt中依赖库路径:
将"${CMAKE_CURRENT_SOURCE_DIR}/depend/lib64/"修改为"${CMAKE_CURRENT_SOURCE_DIR}/depend/lib/"
- **MIGraphX2.3.0及以上版本需要c++17**
### 安装OpenCV并构建工程
```
rbuild build -d depend
```
### 设置环境变量
[光合开发者社区](https://cancon.hpccube.com:65024/4/main/)可下载MIGraphX安装包,python依赖安装:
将依赖库依赖加入环境变量LD_LIBRARY_PATH,在~/.bashrc中添加如下语句:
**Centos**:
```
pip install -r requirements.txt
export LD_LIBRARY_PATH=<path_to_migraphx_samples>/depend/lib64/:$LD_LIBRARY_PATH
```
**Ubuntu**:
```
export LD_LIBRARY_PATH=<path_to_migraphx_samples>/depend/lib/:$LD_LIBRARY_PATH
```
### 运行示例
然后执行:
```
source ~/.bashrc
```
## 推理
### C++版本推理
成功编译YoloV3工程后,在build目录下输入如下命令运行该示例:
```
./MIGraphX_Samples 0
```
程序运行结束会在build目录生成YoloV3检测结果图像。
<img src="./Resource/Images/Result.jpg" alt="Result" style="zoom:50%;" />
### python版本推理
YoloV3模型的推理示例程序是YoloV3_infer_migraphx.py,使用如下命令运行该推理示例:
```
# 进入python示例目录
cd ./Python
# 安装依赖
pip install -r requirements.txt
# 运行程序
python YoloV3_infer_migraphx.py \
--imgpath 测试图像路径 \
--modelpath onnx模型路径 \
......@@ -37,9 +93,9 @@ python YoloV3_infer_migraphx.py \
--nmsThreshold nms阈值,默认0.4 \
```
程序运行结束会在当前目录生成YOLOV3检测结果图像。
程序运行结束会在当前目录生成YoloV3检测结果图像。
<img src="./images/Result.jpg" alt="Result" style="zoom: 67%;" />
<img src="./Resource/Images/Result.jpg" alt="Result_2" style="zoom: 50%;" />
## 历史版本
......
<?xml version="1.0" encoding="GB2312"?>
<opencv_storage>
<!--分类器-->
<Classifier>
<ModelPath>"../Resource/Models/Classifier/mnist-12.onnx"</ModelPath>
<Scale>0.003922</Scale><!--缩放尺度-->
<MeanValue1>0.0</MeanValue1><!--均值-->
<MeanValue2>0.0</MeanValue2>
<MeanValue3>0.0</MeanValue3>
<SwapRB>0</SwapRB>
<Crop>0</Crop>
<UseInt8>0</UseInt8><!--是否使用int8,不支持-->
<UseFP16>0</UseFP16><!--是否使用FP16-->
<AddSoftmax>1</AddSoftmax><!--是否需要添加Softmax计算(如果onnx模型中包含了softmax,则设置为0)-->
</Classifier>
<!--超分辨率重建-->
<Espcn>
<ModelPath>"../Resource/Models/Super_Resolution/super.onnx"</ModelPath>
</Espcn>
<!--Unet-->
<Unet>
<ModelPath>"../Resource/Models/Segmentation/unet_13_256.onnx"</ModelPath>
</Unet>
<!--Bert-->
<Bert>
<ModelPath>"../Resource/Models/NLP/Bert/bertsquad-10.onnx"</ModelPath>
</Bert>
<!--GPT2-->
<GPT2>
<ModelPath>"../Resource/Models/NLP/GPT2/GPT2_shici.onnx"</ModelPath>
</GPT2>
<!--SSD检测器-->
<DetectorSSD>
<ModelPath>"../Resource/Models/Detector/SSD/yufacedetectnet-open-v2.onnx"</ModelPath>
<Scale>1.0</Scale><!--缩放尺度-->
<MeanValue1>0</MeanValue1><!--均值,顺序为bgr-->
<MeanValue2>0</MeanValue2>
<MeanValue3>0</MeanValue3>
<SwapRB>0</SwapRB>
<Crop>0</Crop>
<UseInt8>0</UseInt8><!--是否使用int8,不支持-->
<UseFP16>0</UseFP16><!--是否使用FP16-->
<!--////////////////// SSD网络结构参数 ////////////////// -->
<!--priorbox层的个数-->
<PriorBoxLayerNumber>4</PriorBoxLayerNumber>
<!--每个priorbox层的minisize和maxSize(需要与输出检测层顺序保持一致,下面涉及每个priorbox层参数的都需要保持顺序一致)-->
<MinSize11>10</MinSize11>
<MinSize12>16</MinSize12>
<MinSize13>24</MinSize13>
<MinSize21>32</MinSize21>
<MinSize22>48</MinSize22>
<MinSize31>64</MinSize31>
<MinSize32>96</MinSize32>
<MinSize41>128</MinSize41>
<MinSize42>192</MinSize42>
<MinSize43>256</MinSize43>
<!--每个priorbox层的Flip和Clip(使用0,1表示)-->
<Flip1>0</Flip1>
<Flip2>0</Flip2>
<Flip3>0</Flip3>
<Flip4>0</Flip4>
<Clip1>0</Clip1>
<Clip2>0</Clip2>
<Clip3>0</Clip3>
<Clip4>0</Clip4>
<!--每个priorbox层的宽高比(不包括1,且忽略flip,比如宽高比设置为0.3333和0.25且flip为true,则只需要写0.3333和0.25,如果宽高比只有1,则不用填写该项)-->
<!-- <AspectRatio11>0.3333</AspectRatio11>
<AspectRatio12>0.25</AspectRatio12>
<AspectRatio21>0.3333</AspectRatio21>
<AspectRatio22>0.25</AspectRatio22>
<AspectRatio31>0.3333</AspectRatio31>
<AspectRatio32>0.25</AspectRatio32>
<AspectRatio41>0.3333</AspectRatio41>
<AspectRatio42>0.25</AspectRatio42> -->
<!--每个priorbox层的step-->
<PriorBoxStepWidth1>8</PriorBoxStepWidth1><!--第一个priorbox层的step的width-->
<PriorBoxStepWidth2>16</PriorBoxStepWidth2>
<PriorBoxStepWidth3>32</PriorBoxStepWidth3>
<PriorBoxStepWidth4>64</PriorBoxStepWidth4>
<PriorBoxStepHeight1>8</PriorBoxStepHeight1><!--第一个priorbox层的step的height-->
<PriorBoxStepHeight2>16</PriorBoxStepHeight2>
<PriorBoxStepHeight3>32</PriorBoxStepHeight3>
<PriorBoxStepHeight4>64</PriorBoxStepHeight4>
<!--priorbox层中的offset-->
<Offset>0.5</Offset>
<!--DetectionOutput参数-->
<ClassNumber>2</ClassNumber>
<TopK>400</TopK>
<KeepTopK>200</KeepTopK>
<NMSThreshold>0.3</NMSThreshold>
<ConfidenceThreshold>0.9</ConfidenceThreshold>
</DetectorSSD>
<!--RetinaFace检测器-->
<DetectorRetinaFace>
<ModelPath>"../Resource/Models/Detector/RetinaFace/mobilenet0.25_Final.onnx"</ModelPath>
<Scale>1.0</Scale><!--缩放尺度-->
<MeanValue1>104</MeanValue1><!--均值,顺序为bgr-->
<MeanValue2>117</MeanValue2>
<MeanValue3>123</MeanValue3>
<SwapRB>0</SwapRB>
<Crop>0</Crop>
<UseInt8>0</UseInt8><!--是否使用int8,不支持-->
<UseFP16>0</UseFP16><!--是否使用FP16-->
<!--////////////////// RetinaFace检测器参数 ////////////////// -->
<!--priorbox层的个数-->
<PriorBoxLayerNumber>3</PriorBoxLayerNumber>
<!--每个priorbox层的minisize和maxSize(需要与输出检测层顺序保持一致,下面涉及每个priorbox层参数的都需要保持顺序一致)-->
<MinSize11>16</MinSize11>
<MinSize12>32</MinSize12>
<MinSize21>64</MinSize21>
<MinSize22>128</MinSize22>
<MinSize31>256</MinSize31>
<MinSize32>512</MinSize32>
<!--每个priorbox层的Flip和Clip(使用0,1表示)-->
<Flip1>0</Flip1>
<Flip2>0</Flip2>
<Flip3>0</Flip3>
<Clip1>0</Clip1>
<Clip2>0</Clip2>
<Clip3>0</Clip3>
<!--每个priorbox层的宽高比(由于RetinaFace只包含宽高比为1的anchor,所以这里不需要设置宽高比)-->
<!-- <AspectRatio11>0.3333</AspectRatio11>
<AspectRatio12>0.25</AspectRatio12>
<AspectRatio21>0.3333</AspectRatio21>
<AspectRatio22>0.25</AspectRatio22>
<AspectRatio31>0.3333</AspectRatio31>
<AspectRatio32>0.25</AspectRatio32>
<AspectRatio41>0.3333</AspectRatio41>
<AspectRatio42>0.25</AspectRatio42> -->
<!--每个priorbox层的step-->
<PriorBoxStepWidth1>8</PriorBoxStepWidth1><!--第一个priorbox层的step的width-->
<PriorBoxStepWidth2>16</PriorBoxStepWidth2>
<PriorBoxStepWidth3>32</PriorBoxStepWidth3>
<PriorBoxStepHeight1>8</PriorBoxStepHeight1><!--第一个priorbox层的step的height-->
<PriorBoxStepHeight2>16</PriorBoxStepHeight2>
<PriorBoxStepHeight3>32</PriorBoxStepHeight3>
<!--priorbox层中的offset-->
<Offset>0.5</Offset>
<!--DetectionOutput参数-->
<ClassNumber>2</ClassNumber>
<TopK>400</TopK>
<KeepTopK>200</KeepTopK>
<NMSThreshold>0.3</NMSThreshold>
<ConfidenceThreshold>0.9</ConfidenceThreshold>
</DetectorRetinaFace>
<!--YOLOV3检测器 -->
<DetectorYOLOV3>
<ModelPath>"../Resource/Models/Detector/YOLOV3/yolov3-tiny.onnx"</ModelPath>
<ClassNameFile>"../Resource/Models/Detector/YOLOV3/coco.names"</ClassNameFile>
<UseFP16>0</UseFP16><!--是否使用FP16-->
<NumberOfClasses>80</NumberOfClasses><!--类别数(不包括背景类),COCO:80,VOC:20-->
<ConfidenceThreshold>0.2</ConfidenceThreshold>
<NMSThreshold>0.4</NMSThreshold>
<ObjectThreshold>0.4</ObjectThreshold>
</DetectorYOLOV3>
<!--YOLOV5检测器 -->
<DetectorYOLOV5>
<ModelPath>"../Resource/Models/Detector/YOLOV5/yolov5s.onnx"</ModelPath>
<ClassNameFile>"../Resource/Models/Detector/YOLOV5/coco.names"</ClassNameFile>
<UseFP16>0</UseFP16><!--是否使用FP16-->
<NumberOfClasses>80</NumberOfClasses><!--类别数(不包括背景类),COCO:80,VOC:20-->
<ConfidenceThreshold>0.25</ConfidenceThreshold>
<NMSThreshold>0.5</NMSThreshold>
<ObjectThreshold>0.5</ObjectThreshold>
</DetectorYOLOV5>
<!--MTCNN检测器 -->
<DetectorMTCNN>
<PNet>
<ModelPath>"../Resource/Models/Detector/MTCNN/PNet.onnx"</ModelPath>
<MaxHeight>512</MaxHeight>
<MaxWidth>512</MaxWidth>
<ConfidenceThreshold>0.90</ConfidenceThreshold>
<UseFP16>0</UseFP16>
</PNet>
</DetectorMTCNN>
<!--YOLOV7检测器 -->
<DetectorYOLOV7>
<ModelPath>"../Resource/Models/Detector/YOLOV7/yolov7-tiny.onnx"</ModelPath>
<ClassNameFile>"../Resource/Models/Detector/YOLOV7/coco.names"</ClassNameFile>
<UseFP16>0</UseFP16><!--是否使用FP16-->
<NumberOfClasses>80</NumberOfClasses><!--类别数(不包括背景类),COCO:80,VOC:20-->
<ConfidenceThreshold>0.25</ConfidenceThreshold>
<NMSThreshold>0.5</NMSThreshold>
<ObjectThreshold>0.5</ObjectThreshold>
</DetectorYOLOV7>
<!--CRNN动态文本识别 -->
<CrnnDynamic>
<ModelPath>"../Resource/Models/Ocr/CRNN/crnn_dynamic.onnx"</ModelPath>
</CrnnDynamic>
<!--PaddleOCR车牌检测 -->
<OcrDB>
<ModelPath>"../Resource/Models/PaddleOCR/VLPR/db.onnx"</ModelPath>
<BinaryThreshold>0.3</BinaryThreshold>
<BoxThreshold>0.5</BoxThreshold>
<UnclipRatio>1.6</UnclipRatio>
<LimitSideLen>2500</LimitSideLen>
<ScoreMode>"fast"</ScoreMode>
</OcrDB>
<!--PaddleOCR车牌识别 -->
<OcrSVTR>
<ModelPath>"../Resource/Models/PaddleOCR/VLPR/svtr.onnx"</ModelPath>
<DictPath>"../Resource/Models/PaddleOCR/VLPR/ppocr_keys_v1.txt"</DictPath>
</OcrSVTR>
</opencv_storage>
#include <DetectorYOLOV3.h>
#include <migraphx/onnx.hpp>
#include <migraphx/gpu/target.hpp>
#include <migraphx/gpu/hip.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/quantization.hpp>
#include <opencv2/dnn.hpp>
#include <CommonUtility.h>
#include <Filesystem.h>
#include <SimpleLog.h>
using namespace cv::dnn;
namespace migraphxSamples
{
DetectorYOLOV3::DetectorYOLOV3():logFile(NULL)
{
}
DetectorYOLOV3::~DetectorYOLOV3()
{
configurationFile.release();
}
ErrorCode DetectorYOLOV3::Initialize(InitializationParameterOfDetector initializationParameterOfDetector)
{
// 初始化(获取日志文件,加载配置文件等)
ErrorCode errorCode=DoCommonInitialization(initializationParameterOfDetector);
if(errorCode!=SUCCESS)
{
LOG_ERROR(logFile,"fail to DoCommonInitialization\n");
return errorCode;
}
LOG_INFO(logFile,"succeed to DoCommonInitialization\n");
// 获取配置文件参数
FileNode netNode = configurationFile["DetectorYOLOV3"];
string modelPath=initializationParameter.parentPath+(string)netNode["ModelPath"];
string pathOfClassNameFile=(string)netNode["ClassNameFile"];
yolov3Parameter.confidenceThreshold = (float)netNode["ConfidenceThreshold"];
yolov3Parameter.nmsThreshold = (float)netNode["NMSThreshold"];
yolov3Parameter.objectThreshold = (float)netNode["ObjectThreshold"];
yolov3Parameter.numberOfClasses=(int)netNode["NumberOfClasses"];
useFP16=(bool)(int)netNode["UseFP16"];
// 加载模型
if(Exists(modelPath)==false)
{
LOG_ERROR(logFile,"%s not exist!\n",modelPath.c_str());
return MODEL_NOT_EXIST;
}
net = migraphx::parse_onnx(modelPath);
LOG_INFO(logFile,"succeed to load model: %s\n",GetFileName(modelPath).c_str());
// 获取模型输入属性
std::pair<std::string, migraphx::shape> inputAttribute=*(net.get_parameter_shapes().begin());
inputName=inputAttribute.first;
inputShape=inputAttribute.second;
inputSize=cv::Size(inputShape.lens()[3],inputShape.lens()[2]);
// 设置模型为GPU模式
migraphx::target gpuTarget = migraphx::gpu::target{};
// 量化
if(useFP16)
{
migraphx::quantize_fp16(net);
}
// 编译模型
migraphx::compile_options options;
options.device_id=0; // 设置GPU设备,默认为0号设备
options.offload_copy=true; // 设置offload_copy
net.compile(gpuTarget,options);
LOG_INFO(logFile,"succeed to compile model: %s\n",GetFileName(modelPath).c_str());
// Run once by itself
migraphx::parameter_map inputData;
inputData[inputName]=migraphx::generate_argument(inputShape);
net.eval(inputData);
// 读取类别名
if(!pathOfClassNameFile.empty())
{
ifstream classNameFile(pathOfClassNameFile);
string line;
while (getline(classNameFile, line))
{
classNames.push_back(line);
}
}
else
{
classNames.resize(yolov3Parameter.numberOfClasses);
}
// log
LOG_INFO(logFile,"InputSize:%dx%d\n",inputSize.width,inputSize.height);
LOG_INFO(logFile,"InputName:%s\n",inputName.c_str());
LOG_INFO(logFile,"ConfidenceThreshold:%f\n",yolov3Parameter.confidenceThreshold);
LOG_INFO(logFile,"NMSThreshold:%f\n",yolov3Parameter.nmsThreshold);
LOG_INFO(logFile,"objectThreshold:%f\n",yolov3Parameter.objectThreshold);
LOG_INFO(logFile,"NumberOfClasses:%d\n",yolov3Parameter.numberOfClasses);
return SUCCESS;
}
ErrorCode DetectorYOLOV3::Detect(const cv::Mat &srcImage, std::vector<ResultOfDetection> &resultsOfDetection)
{
if(srcImage.empty()||srcImage.type()!=CV_8UC3)
{
LOG_ERROR(logFile, "image error!\n");
return IMAGE_ERROR;
}
// 预处理并转换为NCHW
cv::Mat inputBlob;
blobFromImage(srcImage,
inputBlob,
1 / 255.0,
inputSize,
Scalar(0, 0, 0),
true,
false);
// 输入数据
migraphx::parameter_map inputData;
inputData[inputName]= migraphx::argument{inputShape, (float*)inputBlob.data};
// 推理
std::vector<migraphx::argument> inferenceResults = net.eval(inputData);
// 获取推理结果
std::vector<cv::Mat> outs;
migraphx::argument result = inferenceResults[0];
// 转换为cv::Mat
migraphx::shape outputShape = result.get_shape();
int shape[]={outputShape.lens()[0],outputShape.lens()[1],outputShape.lens()[2]};
cv::Mat out(3,shape,CV_32F);
memcpy(out.data,result.data(),sizeof(float)*outputShape.elements());
outs.push_back(out);
//获取先验框的个数
int numProposal = outs[0].size[1];
int numOut = outs[0].size[2];
//变换输出的维度
outs[0] = outs[0].reshape(0, numProposal);
//生成先验框
std::vector<float> confidences;
std::vector<cv::Rect> boxes;
std::vector<int> classIds;
float ratioh = (float)srcImage.rows / inputSize.height, ratiow = (float)srcImage.cols / inputSize.width;
//计算cx,cy,w,h,box_sore,class_sore
int n = 0, rowInd = 0;
float* pdata = (float*)outs[0].data;
for (n = 0; n < numProposal; n++)
{
float boxScores = pdata[4];
if (boxScores > yolov3Parameter.objectThreshold)
{
cv::Mat scores = outs[0].row(rowInd).colRange(5, numOut);
cv::Point classIdPoint;
double maxClassScore;
cv::minMaxLoc(scores, 0, &maxClassScore, 0, &classIdPoint);
maxClassScore *= boxScores;
if (maxClassScore > yolov3Parameter.confidenceThreshold)
{
const int classIdx = classIdPoint.x;
float cx = pdata[0] * ratiow;
float cy = pdata[1] * ratioh;
float w = pdata[2] * ratiow;
float h = pdata[3] * ratioh;
int left = int(cx - 0.5 * w);
int top = int(cy - 0.5 * h);
confidences.push_back((float)maxClassScore);
boxes.push_back(cv::Rect(left, top, (int)(w), (int)(h)));
classIds.push_back(classIdx);
}
}
rowInd++;
pdata += numOut;
}
//执行non maximum suppression消除冗余重叠boxes
std::vector<int> indices;
dnn::NMSBoxes(boxes, confidences, yolov3Parameter.confidenceThreshold, yolov3Parameter.nmsThreshold, indices);
for (size_t i = 0; i < indices.size(); ++i)
{
int idx = indices[i];
int classID=classIds[idx];
string className=classNames[classID];
float confidence=confidences[idx];
cv::Rect box = boxes[idx];
ResultOfDetection result;
result.boundingBox=box;
result.confidence=confidence;// confidence
result.classID=classID; // label
result.className=className;
resultsOfDetection.push_back(result);
}
return SUCCESS;
}
ErrorCode DetectorYOLOV3::DoCommonInitialization(InitializationParameterOfDetector initializationParameterOfDetector)
{
initializationParameter=initializationParameterOfDetector;
// 获取日志文件
logFile=LogManager::GetInstance()->GetLogFile(initializationParameter.logName);
// 加载配置文件
std::string configFilePath=initializationParameter.configFilePath;
if(!Exists(configFilePath))
{
LOG_ERROR(logFile, "no configuration file!\n");
return CONFIG_FILE_NOT_EXIST;
}
if(!configurationFile.open(configFilePath, FileStorage::READ))
{
LOG_ERROR(logFile, "fail to open configuration file\n");
return FAIL_TO_OPEN_CONFIG_FILE;
}
LOG_INFO(logFile, "succeed to open configuration file\n");
// 修改父路径
std::string &parentPath = initializationParameter.parentPath;
if (!parentPath.empty())
{
if(!IsPathSeparator(parentPath[parentPath.size() - 1]))
{
parentPath+=PATH_SEPARATOR;
}
}
return SUCCESS;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment