同步模式推理流程
OpenVINO2023版本的SDK支持同步与异步推理模式相比之前OpenVINO2021版本更加的简洁,易用。同时支持创建多个Requst然后基于多个Requst实现流水线方式的推理从而提升CPU推理的吞吐率。同步模式下OpenVINO2023 SDK的推理方式如下:

推理的流程如下:
while(true) {
// capture frame
// populate CURRENT InferRequest
// Infer CURRENT InferRequest
//this call is synchronous
// display CURRENT result
}
以YOLOv5s的模型为例,在OpenVINO C++上同步推理的代码实现如下:
// 创建IE插件, 查询支持硬件设备 ov::Core core; std::string model_onnx = "D:/python/yolov5-7.0/yolov5s.onnx"; auto model = core.read_model(model_onnx); ov::CompiledModel cmodel = core.compile_model(model, "CPU"); // create infer request auto request = cmodel.create_infer_request(); cv::Mat frame; while (true) { bool ret = cap.read(frame); if (frame.empty()) { break; } image_detect(frame, request); char c = cv::waitKey(1); if (c == 27) { // ESC break; } }其中image_detect方法包含模型的图像前处理、同步推理、后处理。其中同步推理:
// 前处理 // 开启同步 request.infer(); // 后处理运行结果如下:
异步模式推理流程
当使用OpenVINO2023提供的Request对象的回调功能以后,我们可以把模型的后处理直接放到回调中去,这样异步推理方式就变成只有图像前处理+模型推两个步骤了,然后通过创建两个Request基于流水线方式,实现异步流水线模式推理方式,这个时候推理流程如下:

推理的流程如下:
while(true) {
// capture frame
// populate NEXT InferRequest
// start NEXT InferRequest
// this call is async and returns immediately
// wait for the CURRENT InferRequest
// display CURRENT result
// swap CURRENT and NEXT InferRequests
}
首先需要创建两个Request,然后分别设置它们的Callback部分代码,主要是在Callback中完成后处理操作。这部分的代码如下:
1//创建IE插件,查询支持硬件设备
2ov::Corecore;
3std::stringmodel_onnx="D:/python/yolov5-7.0/yolov5s.onnx";
4automodel=core.read_model(model_onnx);
5ov::CompiledModelcmodel=core.compile_model(model,"AUTO");
6
7//createinferrequest
8autorequest=cmodel.create_infer_request();
9autonext_request=cmodel.create_infer_request();
10std::exception_ptrexception_var;
11request.set_callback([&](std::exception_ptrex){
12if(ex){
13exception_var=ex;
14return;
15}
16det_boxes.clear();
17det_ids.clear();
18ov::Tensoroutput=request.get_output_tensor();
19constfloat*prob=(float*)output.data();
20constov::ShapeoutputDims=output.get_shape();
21size_tnumRows=outputDims[1];
22size_tnumCols=outputDims[2];
23
24//后处理,1x25200x85
25std::vectorboxes;
26std::vectorclassIds;
27std::vectorconfidences;
28cv::Matdet_output(numRows,numCols,CV_32F,(float*)prob);
29for(inti=0;i< det_output.rows; i++) {
30 float confidence = det_output.at(i,4);
31if(confidence< 0.45) {
32 continue;
33 }
34 cv::Mat classes_scores = det_output.row(i).colRange(5, numCols);
35 cv::Point classIdPoint;
36 double score;
37 minMaxLoc(classes_scores, 0, &score, 0, &classIdPoint);
38
39 // 置信度 0~1之间
40 if (score >0.25)
41{
42floatcx=det_output.at(i,0);
43floatcy=det_output.at(i,1);
44floatow=det_output.at(i,2);
45floatoh=det_output.at(i,3);
46intx=static_cast((cx-0.5*ow)*x_factor);
47inty=static_cast((cy-0.5*oh)*y_factor);
48intwidth=static_cast(ow*x_factor);
49intheight=static_cast(oh*y_factor);
50cv::Rectbox;
51box.x=x;
52box.y=y;
53box.width=width;
54box.height=height;
55
56boxes.push_back(box);
57classIds.push_back(classIdPoint.x);
58confidences.push_back(score);
59}
60}
61
62//NMS
63std::vectorindexes;
64cv::NMSBoxes(boxes,confidences,0.25,0.45,indexes);
65for(size_ti=0;i< indexes.size(); i++) {
66 int index = indexes[i];
67 det_ids.emplace_back(classIds[index]);
68 det_boxes.emplace_back(boxes[index]);
69 }
70});
依据上述的推理流程,最终调用执行的代码如下:
1cv::Matframe,next_frame; 2//dofirstframe 3cap.read(frame); 4async_image_detect(frame,request); 5std::millisecondstout{50}; 6intcnt=0; 7while(true){ 8boolret=cap.read(next_frame); 9if(next_frame.empty()){ 10break; 11} 12 13int64start=cv::getTickCount(); 14//继续异步 15if(cnt%2==0){ 16async_image_detect(next_frame,next_request); 17request.wait_for(tout); 18} 19if(cnt%2==1){ 20async_image_detect(next_frame,request); 21next_request.wait_for(tout); 22} 23for(size_tt=0;t< det_boxes.size(); t++) { 24 int idx = det_ids[t]; 25 cv::rectangle(frame, det_boxes[t], colors_table[idx % 6], 2, 8, 0); 26 putText(frame, classNames[idx].c_str(), det_boxes[t].tl(), cv::FONT_HERSHEY_PLAIN, 1.0, cv::Scalar(255, 0, 0), 1, 8); 27 } 28 29 // 计算FPS render it 30 float t = (cv::getTickCount() - start) / static_cast其中async_image_detect方法中实现了YOLOv5模型推理的图像前处理与启动异步推理模式(cv::getTickFrequency()); 31putText(frame,cv::format("FPS:%.2f",1.0/t),cv::Point(20,40),cv::FONT_HERSHEY_PLAIN,2.0,cv::Scalar(255,0,0),2,8); 32cv::imshow("OpenVINO2023-YOLOv57.0异步推理",frame); 33charc=cv::waitKey(1); 34if(c==27){//ESC 35break; 36} 37next_frame.copyTo(frame); 38cnt++; 39} 40cv::waitKey(0); 41cv::destroyAllWindows(); 42return0;
preprocess(frame) // 开启异步 request.start_async();
审核编辑:汤梓红
-
流水线
+关注
关注
0文章
127浏览量
27125 -
C++
+关注
关注
22文章
2122浏览量
76720 -
代码
+关注
关注
30文章
4942浏览量
73176 -
SDK
+关注
关注
3文章
1094浏览量
51220 -
OpenVINO
+关注
关注
0文章
117浏览量
718
原文标题:OpenVINO2023异步回调流水线提升推理吞吐率
文章出处:【微信号:CVSCHOOL,微信公众号:OpenCV学堂】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
为什么无法在运行时C++推理中读取OpenVINO™模型?
为什么深度学习中的Frame per Second高于OpenVINO™演示推理脚本?
使用Python API在OpenVINO™中创建了用于异步推理的自定义代码,输出张量的打印结果会重复,为什么?
使用OpenVINO运行C++ API创建输入tensor并执行推理遇到的问题求解
在Raspberry Pi上从源代码构建OpenVINO 2021.3收到错误怎么解决?
在英特尔开发者套件上用OpenVINO™ 2023.0加速YOLOv8-Pose姿态估计模型
OpenVINO场景文字检测与文字识别教程
NNCF压缩与量化YOLOv8模型与OpenVINO部署测试
如何快速下载OpenVINO Notebooks中的AI大模型

同步模式下OpenVINO2023 SDK的推理方式
评论