21xrx.com
2024-11-05 14:54:39 Tuesday
登录
文章检索 我的文章 写文章
OpenVINO模型推理:Python和C++接口速度差异对比
2023-06-30 18:52:16 深夜i     --     --
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接口可能更加易用。因此,我们需要根据具体情况灵活选择。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复