InferRequest调用
OpenVINO中的推断引擎(Inference Engine-IE)在加载网络权重与配置文件,生成一个可执行网络以后,通过下面两个API可以获取InferRequest对象
// 获取对象指针InferRequest::Ptr request = executable_network.CreateInferRequestPtr();// 获取对象InferRequest request = executable_network.CreateInferRequest();
得到的InferRequest对象有两种执行方式
// 同步request.Infer()// 异步request.StartAsync()
在同步模式下推断函数Infer会一直阻塞,直到执行结束;在异步模式下推断调用函数StartAsync会立即返回,通过检查
IInferRequest::WaitMode::RESULT_READY
来实现数据接收与数据解析。对于视频分析、视频中对象检测,OpenVINO官方建议通过异步方式可以实现更快的帧率处理,在请求推断图阶段可以请求两个InferRequest对象,进行异步处理。其处理流程图示如下:
行人检测模型
使用OpenVINO模型库中pedestrian-detection-adas-0002模型实现行人检测。该模型是基于SSD MobileNet V1版本上进行优化生成的,其主要的性能指标如下:
代码语言:javascript复制1Average Precision (AP) 88%
2Target pedestrian size 60 x 120 pixels on Full HD image
3Max objects to detect 200
4GFlops 2.836
5MParams 1.165
6Source framework Caffe*
模型要求的输入图像格式:
NxCxHxW = [1x3x384x672]
通道顺序为: BGR
步骤与代码解释
获取推断请求
代码语言:javascript复制// 创建可执行网络对象
auto executable_network = plugin.LoadNetwork(network, {});
// 请求推断图
InferRequest::Ptr async_infer_request_next = executable_network.CreateInferRequestPtr();
InferRequest::Ptr async_infer_request_curr = executable_network.CreateInferRequestPtr();
加载视频文件并读取第一帧
代码语言:javascript复制// 读取第一帧
Mat curr_frame;
Mat next_frame;
cap.read(curr_frame);
int width = curr_frame.cols;
int height = curr_frame.rows;
// 设置当前infer request
frameToBlob(curr_frame, async_infer_request_curr, inputName);
bool isLastFrame = false;
bool isFirstFrame = true;
开启异步执行模式推断
代码语言:javascript复制// 开启异步模式
if (isFirstFrame) { // run once
async_infer_request_curr->StartAsync();
async_infer_request_next->StartAsync();
isFirstFrame = false;
} else {
if (!isLastFrame) {
async_infer_request_next->StartAsync();
}
}
检查异步状态与解析输出数据
代码语言:javascript复制// 检查异步返回
if (OK == async_infer_request_curr->Wait(IInferRequest::WaitMode::RESULT_READY)) {
const float *detections = async_infer_request_curr->GetBlob(outputName)->buffer().as<PrecisionTrait<Precision::FP32>::value_type*>();
for (int i = 0; i < maxProposalCount; i ) {
float image_id = detections[i * objectSize 0];
int label = static_cast<int>(detections[i * objectSize 1]);
float confidence = detections[i * objectSize 2];
float xmin = detections[i * objectSize 3] * width;
float ymin = detections[i * objectSize 4] * height;
float xmax = detections[i * objectSize 5] * width;
float ymax = detections[i * objectSize 6] * height;
if (confidence > 0.5) {
rectangle(curr_frame, Point2f(xmin, ymin), Point2f(xmax, ymax), Scalar(0, 255, 255), 1);
}
}
}
异步请求交换,准备执行下一帧
代码语言:javascript复制// 异步交换
next_frame.copyTo(curr_frame);
async_infer_request_curr.swap(async_infer_request_next);
运行结果如下: