Commit cfaa9eb1 authored by shizhm's avatar shizhm
Browse files

修改yolov5示例为动态shape推理

parent ca5fdd93
# YOLOV5检测器
YOLOV5模型是目前工业界使用较多的算法,官方提供了多个不同版本的预训练模型,本份文档主要介绍了如何将MIGraphX推理结果进行模型初始化、预处理以及后处理,该示例推理流程对YOLOV5其他版本的模型同样适用。
YOLOV5模型是目前工业界使用较多的算法,官方提供了多个不同版本的预训练模型,本份文档主要介绍了如何基于migraphx构建YOLOV5动态shape推理,该示例推理流程对YOLOV5其他版本的模型同样适用。
## 模型简介
......@@ -21,7 +21,7 @@ samples工程中的Resource/Configuration.xml文件的DetectorYOLOV5节点表示
- ObjectThreshold:用于判断anchor内部是否有物体
```
<ModelPath>"../Resource/Models/YOLOV5s.onnx"</ModelPath>
<ModelPath>"../Resource/Models/YOLOV5s_Nx3xNxN.onnx"</ModelPath>
<ClassNameFile>"../Resource/Models/coco.names"</ClassNameFile>
<UseFP16>0</UseFP16><!--是否使用FP16-->
<NumberOfClasses>80</NumberOfClasses><!--类别数(不包括背景类),COCO:80,VOC:20-->
......@@ -32,21 +32,22 @@ samples工程中的Resource/Configuration.xml文件的DetectorYOLOV5节点表示
## 模型初始化
模型初始化首先通过parse_onnx()函数加载YOLOV5的onnx模型,并可以通过program的get_parameter_shapes()函数获取网络的输入属性。完成模型加载之后需要使用compile()方法编译模型,编译模式使用migraphx::gpu::target{}设为GPU模式,编译过程主要基于MIGraphX IR完成各种优化。同时如果需要使用低精度量化进行推理,可以使用quantize_fp16()函数实现。
模型初始化首先通过parse_onnx()函数加载YOLOV5的onnx模型,本示例构建YOLOV5动态shape推理,所以需要设置模型输入的最大shape,本示例设为{1,3,800,800},并可以通过program的get_parameter_shapes()函数获取网络的输入属性。完成模型加载之后需要使用compile()方法编译模型,编译模式使用migraphx::gpu::target{}设为GPU模式,编译过程主要基于MIGraphX IR完成各种优化。同时如果需要使用低精度量化进行推理,可以使用quantize_fp16()函数实现。
```
ErrorCode DetectorYOLOV5::Initialize(InitializationParameterOfDetector initializationParameterOfDetector)
{
...
//模型加载
net = migraphx::parse_onnx(modelPath);
migraphx::onnx_options onnx_options;
onnx_options.map_input_dims["images"]={1,3,800,800};
net = migraphx::parse_onnx(modelPath, onnx_options);
LOG_INFO(stdout,"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;
std::unordered_map<std::string, migraphx::shape> inputMap=net.get_parameter_shapes();
inputName=inputMap.begin()->first;
inputShape=inputMap.begin()->second;
int N=inputShape.lens()[0];
int C=inputShape.lens()[1];
int H=inputShape.lens()[2];
......@@ -64,11 +65,12 @@ ErrorCode DetectorYOLOV5::Initialize(InitializationParameterOfDetector initializ
// 编译模型
migraphx::compile_options options;
options.device_id=0; // 设置GPU设备,默认为0号设备
options.offload_copy=true; // 设置offload_copy
options.device_id=0;
options.offload_copy=true;
net.compile(gpuTarget,options);
LOG_INFO(stdout,"succeed to compile model: %s\n",GetFileName(modelPath).c_str());
...
}
```
......@@ -79,19 +81,20 @@ ErrorCode DetectorYOLOV5::Initialize(InitializationParameterOfDetector initializ
1. 转换数据排布为NCHW
2. 归一化[0.0, 1.0]
3. 将输入数据的尺寸变换到YOLOV5输入大小(1,3,608,608)
3. 将输入数据的尺寸变换到YOLOV5动态输入大小,relInputShape为每次实际inputshape
```
ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<ResultOfDetection> &resultsOfDetection)
ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<std::size_t> &relInputShape, std::vector<ResultOfDetection> &resultsOfDetection)
{
...
inputSize = cv::Size(relInputShape[3], relInputShape[2]);
// 预处理并转换为NCHW
cv::Mat inputBlob;
blobFromImage(srcImage, // 输入数据
inputBlob, // 输出数据
1 / 255.0, //归一化
inputSize, //YOLOV5输入尺寸,本示例为608x608
inputSize, //YOLOV5输入尺寸
Scalar(0, 0, 0), //未减去均值
true, //转换RB通道
false);
......@@ -105,13 +108,13 @@ ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<ResultOfDe
完成图像预处理以及YOLOV5目标检测相关参数设置之后开始执行推理,利用migraphx推理计算得到YOLOV5模型的输出。
```
ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<ResultOfDetection> &resultsOfDetection)
ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<std::size_t> &relInputShape, std::vector<ResultOfDetection> &resultsOfDetection)
{
...
// 创建输入数据
std::unordered_map<std::string, migraphx::shape> inputData;
inputData[inputName]= migraphx::argument{inputShape, (float*)inputBlob.data};
migraphx::parameter_map inputData;
inputData[inputName]= migraphx::argument{migraphx::shape(inputShape.type(), relInputShape), (float*)inputBlob.data};
// 推理
std::vector<migraphx::argument> inferenceResults = net.eval(inputData);
......@@ -137,20 +140,20 @@ YOLOV5的MIGraphX推理结果inferenceResults是一个std::vector< migraphx::arg
- 第二步根据confidenceThreshold阈值进行筛选,当满足第一步阈值anchor的最大置信度得分maxClassScore大于该阈值,则进一步获取当前anchor的坐标信息和预测物体类别信息,小于该阈值则不做处理。
```
ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<ResultOfDetection> &resultsOfDetection)
ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<std::size_t> &relInputShape, std::vector<ResultOfDetection> &resultsOfDetection)
{
...
//获取先验框的个数numProposal=22743
numProposal = outs[0].size[1];
//每个anchor的预测信息数量numOut=85
numOut = outs[0].size[2];
//获取先验框的个数
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
......@@ -158,32 +161,22 @@ ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<ResultOfDe
float* pdata = (float*)outs[0].data;
for (n = 0; n < numProposal; n++)
{
//获取当前anchor是否包含物体的概率值
float boxScores = pdata[4];
//第一次筛选,判断anchor内是否包含物体
if (boxScores > yolov5Parameter.objectThreshold)
{
//获取每个anchor内部预测的80个类别概率信息
cv::Mat scores = outs[0].row(rowInd).colRange(5, numOut);
cv::Point classIdPoint;
double maxClassScore;
//获取80个类别中最大概率值和对应的类别ID
cv::minMaxLoc(scores, 0, &maxClassScore, 0, &classIdPoint);
maxClassScore *= boxScores;
//第二次筛选,判断当前anchor的最大置信度得分是否满足阈值
if (maxClassScore > yolov5Parameter.confidenceThreshold)
{
const int classIdx = classIdPoint.x;
//将每个anchor坐标按缩放比例映射到原图
float cx = pdata[0] * ratiow;
float cy = pdata[1] * ratioh;
float w = pdata[2] * ratiow;
float h = pdata[3] * ratioh;
//获取anchor的左上角坐标
int left = int(cx - 0.5 * w);
int top = int(cy - 0.5 * h);
......@@ -203,7 +196,7 @@ ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<ResultOfDe
为了消除重叠锚框,输出最终的YOLOV5目标检测结果,执行非极大值抑制对筛选之后的anchor进行处理,最后保存检测结果到resultsOfDetection中。
```
ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<ResultOfDetection> &resultsOfDetection)
ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<std::size_t> &relInputShape, std::vector<ResultOfDetection> &resultsOfDetection)
{
...
......
# YOLOV5检测器
本份文档主要介绍如何基于MIGraphX构建YOLOV5的Python推理示例,根据文档描述可以了解怎样运行该Python示例得到YOLOV5的目标检测结果。
本份文档主要介绍如何基于MIGraphX构建YOLOV5的动态shape推理Python示例,根据文档描述可以了解怎样运行该Python示例得到YOLOV5的目标检测结果。
## 模型简介
......@@ -14,7 +14,7 @@ YOLOV5是一种单阶段目标检测算法,该算法在YOLOV4的基础上添
1. 转换数据排布为NCHW
2. 归一化[0.0, 1.0]
3. 调整输入数据的尺寸为(1,3,608,608)
3. 调整输入数据的尺寸
```
def prepare_input(self, image):
......@@ -34,7 +34,11 @@ def prepare_input(self, image):
return input_img
```
其中模型输入的inputWidth、inputHeight通过migraphx对输入模型进行解析获取,代码位置见YOLOV5类初始化位置。
其中模型输入的inputWidth、inputHeight为每次动态输入shape。
## 推理
执行YOLOV5动态输入推理,首先需要对YOLOV5的动态模型进行解析、编译,与静态推理不同的是,动态shape推理需要设置模型输入的最大shape,本示例设为[1,3,800,800]。
```
class YOLOv5:
......@@ -47,31 +51,33 @@ class YOLOv5:
self.classNames = list(map(lambda x: x.strip(), open('../Resource/Models/coco.names', 'r').readlines()))
# 解析推理模型
self.model = migraphx.parse_onnx(path)
maxInput={"images":[1,3,800,800]}
self.model = migraphx.parse_onnx(path, map_input_dims=maxInput)
# 获取模型的输入name
self.inputName = self.model.get_parameter_names()[0]
# 获取模型的输入尺寸
inputShape = self.model.get_parameter_shapes()[self.inputName].lens()
self.inputHeight = int(inputShape[2])
self.inputWidth = int(inputShape[3])
print("inputName:{0} \ninputMaxShape:{1}".format(self.inputName, inputShape))
# 模型编译
self.model.compile(t=migraphx.get_target("gpu"), device_id=0) # device_id: 设置GPU设备,默认为0号设备
print("Success to compile")
...
```
## 推理
输入图像预处理完成之后开始进行推理,首先需要利用migraphx进行编译,然后对输入数据进行前向计算得到模型的输出result,在detect函数中调用定义的process_output函数对result进行后处理,得到图像中含有物体的anchor坐标信息、类别置信度、类别ID。
模型初始化完成之后开始进行推理,对输入数据进行前向计算得到模型的输出result,在detect函数中调用定义的process_output函数对result进行后处理,得到图像中含有物体的anchor坐标信息、类别置信度、类别ID。
```
def detect(self, image):
# 输入图像预处理
def detect(self, image, input_shape):
self.inputWidth = input_shape[3]
self.inputHeight = input_shape[2]
# 输入图片预处理
input_img = self.prepare_input(image)
# 模型编译
self.model.compile(t=migraphx.get_target("gpu"), device_id=0) # device_id: 设置GPU设备,默认为0号设备
print("Success to compile")
# 执行推理
print("Start to inference")
start = time.time()
result = self.model.run({self.model.get_parameter_names()[0]: input_img})
print('net forward time: {:.4f}'.format(time.time() - start))
......@@ -110,6 +116,19 @@ def process_output(self, output):
return boxes[indices], scores[indices], class_ids[indices]
def extract_boxes(self, predictions):
# 获取anchor的坐标信息
boxes = predictions[:, :4]
# 将anchor的坐标信息映射到输入image
boxes = self.rescale_boxes(boxes)
# 格式转换
boxes_ = np.copy(boxes)
boxes_[..., 0] = boxes[..., 0] - boxes[..., 2] * 0.5
boxes_[..., 1] = boxes[..., 1] - boxes[..., 3] * 0.5
return boxes_
def rescale_boxes(self, boxes):
# 对anchor尺寸进行变换
input_shape = np.array([self.inputWidth, self.inputHeight, self.inputWidth, self.inputHeight])
......
......@@ -17,26 +17,27 @@ class YOLOv5:
self.classNames = list(map(lambda x: x.strip(), open('../Resource/Models/coco.names', 'r').readlines()))
# 解析推理模型
self.model = migraphx.parse_onnx(path)
maxInput={"images":[1,3,800,800]}
self.model = migraphx.parse_onnx(path, map_input_dims=maxInput)
# 获取模型的输入name
self.inputName = self.model.get_parameter_names()[0]
# 获取模型的输入尺寸
inputShape = self.model.get_parameter_shapes()[self.inputName].lens()
self.inputHeight = int(inputShape[2])
self.inputWidth = int(inputShape[3])
print("inputName:{0} \ninputShape:{1}".format(self.inputName, inputShape))
print("inputName:{0} \ninputMaxShape:{1}".format(self.inputName, inputShape))
# 模型编译
self.model.compile(t=migraphx.get_target("gpu"), device_id=0) # device_id: 设置GPU设备,默认为0号设备
print("Success to compile")
def detect(self, image):
def detect(self, image, input_shape):
self.inputWidth = input_shape[3]
self.inputHeight = input_shape[2]
# 输入图片预处理
input_img = self.prepare_input(image)
# 模型编译
self.model.compile(t=migraphx.get_target("gpu"), device_id=0) # device_id: 设置GPU设备,默认为0号设备
print("Success to compile")
# 执行推理
print("Start to inference")
start = time.time()
result = self.model.run({self.model.get_parameter_names()[0]: input_img})
print('net forward time: {:.4f}'.format(time.time() - start))
......@@ -114,28 +115,50 @@ class YOLOv5:
labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
cv2.putText(image, label, (cx, cy - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), thickness=2)
return image
def read_images(image_path):
image_lists = []
for image_name in os.listdir(image_path):
image = cv2.imread(image_path +"/" + image_name, 1)
image_lists.append(image)
image_lists.reverse()
return image_lists
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--imgpath', type=str, default='../Resource/Images/bus.jpg', help="image path")
parser.add_argument('--modelpath', type=str, default='../Resource/Models/yolov5s.onnx', help="onnx filepath")
parser.add_argument('--imgpath', type=str, default='../Resource/Images/DynamicPics', help="image path")
parser.add_argument('--modelpath', type=str, default='../Resource/Models/yolov5s_Nx3xNxN.onnx', help="onnx filepath")
parser.add_argument('--objectThreshold', default=0.5, type=float, help='class confidence')
parser.add_argument('--confThreshold', default=0.25, type=float, help='class confidence')
parser.add_argument('--nmsThreshold', default=0.5, type=float, help='nms iou thresh')
args = parser.parse_args()
yolov5_detector = YOLOv5(args.modelpath, obj_thres=args.objectThreshold, conf_thres=args.confThreshold,
iou_thres=args.nmsThreshold)
srcimg = cv2.imread(args.imgpath, 1)
boxes, scores, class_ids = yolov5_detector.detect(srcimg)
dstimg = yolov5_detector.draw_detections(srcimg, boxes, scores, class_ids)
# 保存检测结果
cv2.imwrite("./Result.jpg", dstimg)
print("Success to save result")
# 设置动态输入shape
input_shapes = []
input_shapes.append([1,3,416,416])
input_shapes.append([1,3,608,608])
# 读取测试图像
image_lists = read_images(args.imgpath)
# 推理
yolov5_detector = YOLOv5(args.modelpath, obj_thres=args.objectThreshold,
conf_thres=args.confThreshold, iou_thres=args.nmsThreshold)
for i, image in enumerate(image_lists):
print("Start to inference image{}".format(i))
boxes, scores, class_ids = yolov5_detector.detect(image, input_shapes[i])
dstimg = yolov5_detector.draw_detections(image, boxes, scores, class_ids)
# 保存检测结果
result_name = "Result{}.jpg".format(i)
cv2.imwrite(result_name, dstimg)
print("Success to save results")
......
......@@ -43,9 +43,13 @@ pip install -r requirements.txt
### 运行示例
YoloV5模型的推理示例程序是YoloV5_infer_migraphx.py,在Python目录下使用如下命令运行该推理示例:
YoloV5模型的推理示例程序是YoloV5_infer_migraphx.py,本示例执行YOLOV5动态shape推理,在Python目录下使用如下命令运行该推理示例:
```
# 开启环境变量
export MIGRAPHX_DYNAMIC_SHAPE=1
# 运行示例
python YoloV5_infer_migraphx.py \
--imgpath 测试图像路径 \
--modelpath onnx模型路径 \
......@@ -56,7 +60,9 @@ python YoloV5_infer_migraphx.py \
程序运行结束会在当前目录生成YoloV5检测结果图像。
<img src="./Resource/Images/Result.jpg" alt="Result_2" style="zoom: 50%;" />
<img src="./Resource/Images/Result0.jpg" alt="Result_2" style="zoom: 50%;" />
<img src="./Resource/Images/Result1.jpg" alt="Result1" style="zoom: 50%;" />
## C++版本推理
......@@ -115,7 +121,7 @@ source ~/.bashrc
### 运行示例
成功编译YoloV5工程后,执行如下命令运行该示例:
成功编译YoloV5工程后,执行如下命令运行动态shape推理该示例:
```
# 进入yolov5 migraphx工程根目录
......@@ -124,13 +130,18 @@ cd <path_to_yolov5_migraphx>
# 进入build目录
cd ./build/
# 开启环境变量
export MIGRAPHX_DYNAMIC_SHAPE=1
# 执行示例程序
./YOLOV5
```
程序运行结束会在build目录生成YoloV5检测结果图像。
程序运行结束会在build目录生成YoloV5动态shape推理检测结果图像。
<img src="./Resource/Images/Result0.jpg" alt="Result" style="zoom:50%;" />
<img src="./Resource/Images/Result.jpg" alt="Result" style="zoom:50%;" />
<img src="./Resource/Images/Result1.jpg" alt="Result" style="zoom:50%;" />
## 源码仓库及问题反馈
......
......@@ -3,7 +3,7 @@
<!--YOLOV5检测器 -->
<DetectorYOLOV5>
<ModelPath>"../Resource/Models/yolov5s.onnx"</ModelPath>
<ModelPath>"../Resource/Models/yolov5s_Nx3xNxN.onnx"</ModelPath>
<ClassNameFile>"../Resource/Models/coco.names"</ClassNameFile>
<UseFP16>0</UseFP16><!--是否使用FP16-->
<NumberOfClasses>80</NumberOfClasses><!--类别数(不包括背景类),COCO:80,VOC:20-->
......
......@@ -53,7 +53,10 @@ ErrorCode DetectorYOLOV5::Initialize(InitializationParameterOfDetector initializ
LOG_ERROR(stdout,"%s not exist!\n",modelPath.c_str());
return MODEL_NOT_EXIST;
}
net = migraphx::parse_onnx(modelPath);
migraphx::onnx_options onnx_options;
onnx_options.map_input_dims["images"]={1,3,800,800};//
net = migraphx::parse_onnx(modelPath, onnx_options);
LOG_INFO(stdout,"succeed to load model: %s\n",GetFileName(modelPath).c_str());
// 获取模型输入属性
......@@ -77,7 +80,7 @@ ErrorCode DetectorYOLOV5::Initialize(InitializationParameterOfDetector initializ
// 编译模型
migraphx::compile_options options;
options.device_id=0; // 设置GPU设备,默认为0号设备
options.device_id=0;
options.offload_copy=true;
net.compile(gpuTarget,options);
LOG_INFO(stdout,"succeed to compile model: %s\n",GetFileName(modelPath).c_str());
......@@ -103,7 +106,7 @@ ErrorCode DetectorYOLOV5::Initialize(InitializationParameterOfDetector initializ
}
// log
LOG_INFO(stdout,"InputSize:%dx%d\n",inputSize.width,inputSize.height);
LOG_INFO(stdout,"InputMaxSize:%dx%d\n",inputSize.width,inputSize.height);
LOG_INFO(stdout,"InputName:%s\n",inputName.c_str());
LOG_INFO(stdout,"ConfidenceThreshold:%f\n",yolov5Parameter.confidenceThreshold);
LOG_INFO(stdout,"NMSThreshold:%f\n",yolov5Parameter.nmsThreshold);
......@@ -114,7 +117,7 @@ ErrorCode DetectorYOLOV5::Initialize(InitializationParameterOfDetector initializ
}
ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<ResultOfDetection> &resultsOfDetection)
ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<std::size_t> &relInputShape, std::vector<ResultOfDetection> &resultsOfDetection)
{
if(srcImage.empty()||srcImage.type()!=CV_8UC3)
{
......@@ -122,6 +125,8 @@ ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<ResultOfDe
return IMAGE_ERROR;
}
inputSize = cv::Size(relInputShape[3], relInputShape[2]);
// 数据预处理并转换为NCHW格式
cv::Mat inputBlob;
cv::dnn::blobFromImage(srcImage,
......@@ -133,8 +138,8 @@ ErrorCode DetectorYOLOV5::Detect(const cv::Mat &srcImage, std::vector<ResultOfDe
false);
// 创建输入数据
std::unordered_map<std::string, migraphx::argument> inputData;
inputData[inputName]= migraphx::argument{inputShape, (float*)inputBlob.data};
migraphx::parameter_map inputData;
inputData[inputName]= migraphx::argument{migraphx::shape(inputShape.type(), relInputShape), (float*)inputBlob.data};
// 推理
std::vector<migraphx::argument> inferenceResults = net.eval(inputData);
......
......@@ -25,7 +25,7 @@ public:
ErrorCode Initialize(InitializationParameterOfDetector initializationParameterOfDetector);
ErrorCode Detect(const cv::Mat &srcImage, std::vector<ResultOfDetection> &resultsOfDetection);
ErrorCode Detect(const cv::Mat &srcImage, std::vector<std::size_t> &relInputShape, std::vector<ResultOfDetection> &resultsOfDetection);
private:
cv::FileStorage configurationFile;
......
......@@ -19,38 +19,55 @@ int main()
}
LOG_INFO(stdout, "succeed to initialize detector\n");
// 读取测试图片
cv::Mat srcImage = cv::imread("../Resource/Images/bus.jpg",1);
// 推理
std::vector<migraphxSamples::ResultOfDetection> predictions;
double time1 = cv::getTickCount();
detector.Detect(srcImage,predictions);
double time2 = cv::getTickCount();
double elapsedTime = (time2 - time1)*1000 / cv::getTickFrequency();
LOG_INFO(stdout, "inference time:%f ms\n", elapsedTime);
// 获取推理结果
LOG_INFO(stdout,"========== Detection Results ==========\n");
for(int i=0;i<predictions.size();++i)
// 读取测试图像
std::vector<cv::Mat> srcImages;
cv::String folder = "../Resource/Images/DynamicPics";
std::vector<cv::String> imagePathList;
cv::glob(folder,imagePathList);
for (int i = 0; i < imagePathList.size(); ++i)
{
migraphxSamples::ResultOfDetection result=predictions[i];
cv::rectangle(srcImage,result.boundingBox,cv::Scalar(0,255,255),2);
std::string label = cv::format("%.2f", result.confidence);
label = result.className + " " + label;
int left = predictions[i].boundingBox.x;
int top = predictions[i].boundingBox.y;
int baseLine;
cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
top = max(top, labelSize.height);
cv::putText(srcImage, label, cv::Point(left, top-10), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255), 2);
LOG_INFO(stdout,"box:%d %d %d %d,label:%d,confidence:%f\n",predictions[i].boundingBox.x,
predictions[i].boundingBox.y,predictions[i].boundingBox.width,predictions[i].boundingBox.height,predictions[i].classID,predictions[i].confidence);
cv:: Mat srcImage=cv::imread(imagePathList[i], 1);
srcImages.push_back(srcImage);
}
// 设置动态推理shape
std::vector<std::vector<std::size_t>> inputShapes;
inputShapes.push_back({1,3,416,416});
inputShapes.push_back({1,3,608,608});
for (int i = 0; i < srcImages.size(); ++i)
{
// 推理
std::vector<migraphxSamples::ResultOfDetection> predictions;
double time1 = cv::getTickCount();
detector.Detect(srcImages[i], inputShapes[i], predictions);
double time2 = cv::getTickCount();
double elapsedTime = (time2 - time1)*1000 / cv::getTickFrequency();
LOG_INFO(stdout, "inference image%d time:%f ms\n", i, elapsedTime);
// 获取推理结果
LOG_INFO(stdout,"========== Detection Image%d Results ==========\n", i);
for(int j=0;j<predictions.size();++j)
{
migraphxSamples::ResultOfDetection result=predictions[j];
cv::rectangle(srcImages[i],result.boundingBox,cv::Scalar(0,255,255),2);
std::string label = cv::format("%.2f", result.confidence);
label = result.className + " " + label;
int left = predictions[j].boundingBox.x;
int top = predictions[j].boundingBox.y;
int baseLine;
cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
top = max(top, labelSize.height);
cv::putText(srcImages[i], label, cv::Point(left, top-10), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255), 2);
LOG_INFO(stdout,"box:%d %d %d %d,label:%d,confidence:%f\n",predictions[j].boundingBox.x,
predictions[j].boundingBox.y,predictions[j].boundingBox.width,predictions[j].boundingBox.height,predictions[j].classID,predictions[j].confidence);
}
std::string imgName = cv::format("Result%d.jpg", i);
cv::imwrite(imgName, srcImages[i]);
LOG_INFO(stdout,"Detection results have been saved to ./Result%d.jpg\n", i);
}
cv::imwrite("Result.jpg",srcImage);
LOG_INFO(stdout,"Detection results have been saved to ./Result.jpg\n");
return 0;
}
\ No newline at end of file
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