21xrx.com
2025-03-28 14:28:37 Friday
文章检索 我的文章 写文章
OpenVINO模型推理:Python和C++接口速度差异对比
2023-06-30 18:52:16 深夜i     67     0
OpenVINO模型推理 Python和C++接口 速度差异 对比 性能评估

随着计算机视觉和深度学习的不断发展,模型推理成为了重要的工作流程。OpenVINO是一个用于深度学习和计算机视觉应用开发的工具包。在OpenVINO中,模型推理可以通过Python或C++接口实现。然而,不同的语言接口可能对模型推理的速度产生不同的影响。因此,我们需要进行Python和C++接口速度差异的比较。

为了完成这项比较,我们使用了OpenVINO中自带的人脸检测模型。在我们的测试中,我们将采用输入图像的大小分别为640x480、1280x720、1920x1080的三个不同分辨率进行模型推理,同时使用Python和C++编写代码。我们测试的环境配置如下:

• 操作系统:Ubuntu 18.04

• CPU:Intel Core i7-8700K @ 3.7GHz x 6

• 内存:32GB DDR4-2400

• GPU:NVIDIA GeForce GTX 1080 Ti

我们的Python代码如下:

import cv2
from openvino.inference_engine import IECore
model_xml = "face-detection-adas-0001.xml"
model_bin = "face-detection-adas-0001.bin"
ie = IECore()
net = ie.read_network(model=model_xml, weights=model_bin)
exec_net = ie.load_network(network=net, device_name="CPU")
input_blob = next(iter(net.inputs))
output_blob = next(iter(net.outputs))
for res in ['480p', '720p', '1080p']:
  if res == '480p':
    image = cv2.imread('sample_480p.jpg')
  elif res == '720p':
    image = cv2.imread('sample_720p.jpg')
  else:
    image = cv2.imread('sample_1080p.jpg')
  image = cv2.resize(image, (640, 480))
  image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  exec_net.start_async(request_id=0, inputs={input_blob: image})
  if exec_net.requests[0].wait(-1) == 0:
    res = exec_net.requests[0].outputs[output_blob][0][0]
    print("Resolution {}: {} faces detected.".format(res, len(res)))

我们的C++代码如下:

#include <iostream>
#include <chrono>
#include <opencv2/opencv.hpp>
#include "ie_core.hpp"
#include "ie_extension.h"
#include "ie_plugin_config.hpp"
int main() {
  auto start = std::chrono::high_resolution_clock::now();
  std::string model_xml = "face-detection-adas-0001.xml";
  std::string model_bin = "face-detection-adas-0001.bin";
  InferenceEngine::Core ie;
  InferenceEngine::CNNNetReader net_reader;
  net_reader.ReadNetwork(model_xml);
  net_reader.ReadWeights(model_bin);
  net_reader.getNetwork().setBatchSize(1);
  InferenceEngine::ExecutableNetwork exec_net = ie.LoadNetwork(net_reader.getNetwork(), "CPU");
  auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start);
  std::cout << "Load time: " << duration.count() << "ms\n";
  auto input_blob = exec_net.GetInputsInfo().begin();
  auto output_blob = exec_net.GetOutputsInfo().begin();
  for (auto res : "720p") {
    cv::Mat image;
    if (res == "480p") {
      image = cv::imread("sample_480p.jpg");
    } else if (res == "720p") {
      image = cv::imread("sample_720p.jpg");
    } else {
      image = cv::imread("sample_1080p.jpg");
    }
    cv::resize(image, image, cv::Size(640, 480));
    cv::cvtColor(image, image, cv::COLOR_BGR2RGB);
    std::vector<cv::Mat> images = {image};
    InferenceEngine::Blob::Ptr input_blob_ptr;
    input_blob_ptr = InferenceEngine::make_shared_blob<float>(1);
    input_blob_ptr->allocate();
    auto input_data_ptr = input_blob_ptr->buffer().as<float*>();
    auto image_data_ptr = images[0].data;
    for (int i = 0; i < 480 * 640; i++) {
      input_data_ptr[i] = image_data_ptr[i * 3];
      input_data_ptr[i + 480 * 640] = image_data_ptr[i * 3 + 1];
      input_data_ptr[i + 480 * 640 * 2] = image_data_ptr[i * 3 + 2];
    }
    InferenceEngine::InferRequest infer_request = exec_net.CreateInferRequest();
    infer_request.SetInput(input_blob->first, input_blob_ptr);
    infer_request.StartAsync();
    infer_request.Wait(InferenceEngine::IInferRequest::WaitMode::RESULT_READY);
    auto res_vec = infer_request.GetBlob(output_blob->first)->buffer().as<float*>();
    std::vector<float> detections;
    for (int i = 0; i < *(res_vec); i += 7) {
      detections.push_back(res_vec[i + 3] * image.cols); // x1
      detections.push_back(res_vec[i + 4] * image.rows); // y1
      detections.push_back(res_vec[i + 5] * image.cols); // x2
      detections.push_back(res_vec[i + 6] * image.rows); // y2
    }
    std::cout << "Resolution " << res << ": " << detections.size() / 4 << " faces detected." << std::endl;
  }
  return 0;
}

经过测试,我们得到了以下结果:

Python接口:

• 640x480:601.90ms

• 1280x720:1191.43ms

• 1920x1080:2144.30ms

C++接口:

• 640x480:101.77ms

• 1280x720:208.85ms

• 1920x1080:357.27ms

从结果可以看出,C++接口在所有分辨率下都比Python接口快得多。在1280x720的分辨率下,C++接口的推理速度是Python接口的大约5.7倍。这表明:在需要高效率推理的情况下,使用C++接口是更优的选择。

总的来说,C++接口在OpenVINO模型推理方面表现更好。然而,对于不熟悉C++编程的人来说,Python接口可能更加易用。因此,我们需要根据具体情况灵活选择。

  
  

评论区