【OpenVINO 】在 MacOS 上编译 OpenVINO C++ 项目

前言

英特尔公司发行的模型部署工具OpenVINO™模型部署套件,可以实现在不同系统环境下运行,且发布的OpenVINO™ 2023最新版目前已经支持MacOS系统并同时支持在苹果M系列芯片上部署模型。在该项目中,我们将向大家展示如何在MacOS系统、M2芯片的Macbook Air电脑上,展示使用OpenVINO™ C++ API 部署深度学习模型。

文章目录

  • 1. OpenVINO™
  • 2. OpenVINO™ 下载
  • 3. 代码实现
  • 4. 项目编译运行
  • 5. 总结

1. OpenVINO™

英特尔发行版 OpenVINO™ 工具套件基于 oneAPI 而开发,可以加快高性能计算机视觉和深度学习视觉应用开发速度工具套件,适用于从边缘到云的各种英特尔平台上,帮助用户更快地将更准确的真实世界结果部署到生产系统中。通过简化的开发工作流程,OpenVINO™ 可赋能开发者在现实世界中部署高性能应用程序和算法。

在这里插入图片描述

OpenVINO™ 2023.2 于 2023 年 11 月 16 日发布,该工具包带来了挖掘生成人工智能全部潜力的新功能。更多的生成式 AI 覆盖和框架集成,以最大限度地减少代码更改,并且扩展了对直接 PyTorch 模型转换的模型支持。支持更多新的模型,包括 LLaVA、chatGLM、Bark 和 LCM 等著名模型。支持更广泛的大型语言模型(LLM)和更多模型压缩技术,支持运行时推理支持以下 Int4 模型压缩格式,通过神经网络压缩框架(NNCF) 进行本机 Int4 压缩等一系列新的功能。

在这里插入图片描述

通过OpenVINO™官网信息,我们可以看出,目前OpenVINO™已经能够在苹果MacOS系统、M系列芯片上运行,这为使用MacOS系统的开发者提供了很好的工具。因此在此处,我们将在MacOS系统、M2芯片的Macbook Air电脑上,展示使用 OpenVINO™ C++ API 部署深度学习模型的详细流程。

2. OpenVINO™ 下载

官方在发布版本中已经提供MacOS系统的编译库,因此在此处我们只需要下载官方编译库即可

首先访问OpenVINO™网站,依次选择版本号、操作系统、安装方式等内容,然后点击下载,如下图所示:

在这里插入图片描述

下面是官方编译的文件,此处主要提供了两个版本,一个是适用于苹果电脑之前的版本,主要是MacOS 10以及之前的版本系统并且使用的是Intel CPU,另一个是使用了苹果的M系列芯片的新版本电脑,主要是MacOS 11 之后的系统。大家可以根据自己的电脑进行选择:

在这里插入图片描述

下载完后,将该文件解压到任意文件夹,在此处为了方便后续使用一集更新,将其解压到用户文件夹,如下图所示:
在这里插入图片描述

后续我们会使用CMake进行项目编译,因此我们此处无需再做其他的设置。

其他环境配置:

  • MacOS:14.2.1
  • CMake:3.28
  • Make:3.81
  • 编译软件:Visual Studio Code
  • OpenCV:4.8.0
    其他环境配置此处不做过多赘述,OpenCV环境安装可以参考下述文章实现:

3. 代码实现

此处我们以Yolov8图片分类模型为例进行项目测试,由于该模型之前我们已经多次使用,所以在此处不在做耕作的阐述,具体代码如下所示:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sys/time.h>
#include "openvino/openvino.hpp" //openvino header file
#include "opencv2/opencv.hpp"    //opencv header file

int main(int argc, char* argv[])
{
    ov::Version version = ov::get_openvino_version();
    std::cout << version.description << ": " << version.buildNumber << std::endl;

    // -------- Step 1. Initialize OpenVINO Runtime Core --------
    ov::Core core;

    // -------- Step 2. Compile the Model --------
    auto compiled_model = core.compile_model("yolov8s-cls.xml", "CPU");

    // -------- Step 3. Create an Inference Request --------
    ov::InferRequest infer_request = compiled_model.create_infer_request();

    // -------- Step 4.Read a picture file and do the preprocess --------
    cv::Mat img = cv::imread("image.jpg"); 
    // Preprocess the image
    int col = img.cols;
    int row = img.rows;
    int _max = MAX(col, row);
    cv::Mat letterbox_img = cv::Mat::zeros(_max, _max, CV_8UC3);
    img.copyTo(letterbox_img(cv::Rect(0, 0, col, row)));
    
    cv::Mat blob = cv::dnn::blobFromImage(letterbox_img, 1.0 / 255.0, cv::Size(224, 224), cv::Scalar(), true);

    // -------- Step 5. Feed the blob into the input node of the Model -------
    // Get input port for model with one input
    auto input_port = compiled_model.input();
    std::cout << "The shape of input tensor:" << input_port.get_shape() << std::endl;
    // Create tensor from external memory
    ov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), blob.ptr(0));
    // Set input tensor for model with one input
    infer_request.set_input_tensor(input_tensor);

    // -------- Step 6. Start inference --------
    infer_request.infer();
    struct timeval start_time, end_time;
    gettimeofday(&start_time,NULL);
    infer_request.infer();
    gettimeofday(&end_time,NULL);
    // Get the elapsed millisecond time
    double elapsed_time = (end_time.tv_sec - start_time.tv_sec)*1000 + (end_time.tv_usec - start_time.tv_usec)/1000;
    // -------- Step 7. Get the inference result --------
    auto output = infer_request.get_output_tensor(0);
    auto output_shape = output.get_shape();
    std::cout << "The shape of output tensor:" << output_shape << std::endl;

    // -------- Step 8. Postprocess the result --------
    float* output_buffer = output.data<float>();
    std::vector<float> result(output_buffer, output_buffer + output_shape[1]);
    auto max_idx = std::max_element(result.begin(), result.end());
    int class_id = max_idx - result.begin();
    float score = *max_idx;
    std::cout << "Class ID:" << class_id << " Score:" <<score<< std::endl;
    std::cout << "infer time:" <<elapsed_time<< std::endl;
    return 0;
}

在该代码中,主要是获取OpenVINO™版本信息,然后按照模型部署流程部署测试了Yolov8图片分类模型,并打印输出结果以及推理时间。

4. 项目编译运行

在该项目中通过CMake编译项目,定义的CMakeLists.txt文件如下所示:

cmake_minimum_required(VERSION 3.28)
project(test_openvino)
set(OpenCV_DIR /Users/ygj/3lib/opencv_4.8.0/lib/cmake/opencv4)
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV_DIR = ${OpenCV_DIR}")
message(STATUS "OpenCV_INCLUDE_DIRS = ${OpenCV_INCLUDE_DIRS}")
message(STATUS "OpenCV_LIBS = ${OpenCV_LIBS}")
set(OpenVINO_DIR /Users/ygj/3lib/openvino_2023.2/runtime/cmake)
set(OpenVINO_LIBs "/Users/ygj/3lib/openvino_2023.2/runtime/lib/arm64/Release/libopenvino.2320.dylib")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories(
    /Users/ygj/3lib/openvino_2023.2/runtime/include
    ${OpenCV_INCLUDE_DIRS}
)
add_executable(test_openvino test_openvino.cpp )
target_link_libraries(test_openvino ${OpenVINO_LIBs} ${OpenCV_LIBS})

在这个CMakeLists文件中,需要同时配置OpenCV以及OpenVINO这两个依赖库,具体编译以及配置方式参考CMake手册。

接下来就可以项目编译了,在终端中输入一下命令,就可以进行项目配置了,输出结果如下所示:

cmake .

在这里插入图片描述

接下来就是进行项目编译,CMake编译后会生成Makefile文件,之后就可以运行make命令进行项目最后的编译,然后就可以直接运行生成的项目文件,如下所示:

make
./test_openvino

在这里插入图片描述

上图中展示了项目最后运行结果,可以看出,此处使用的模型输入大小为[1,3,224,224],输出大小为[1,1000],识别结果Class ID=386,查看分类结果字典,图片识别结果与图片一致;模型的推理时间为:7ms。

5. 总结

该项目中,我们在MacOS 14.2.1 系统、M2芯片的 Macbook Air 电脑上,成功使用OpenVINO™ C++ API 部署了Yolov8图片分类深度学习模型,并详细演示了OpenVINO™ C++ API在苹果电脑上使用与配置流程,为使用MacOS系统的开发者提供了很好的范例与参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/303379.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

③使用Redis缓存,并增强数据一致性。

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 使用Redis缓存&#xff0c;并增强数据一致性。…

1. 认识SPSS

使用的是IBM SPSS statistics 25&#xff0c;参考教材《统计分析与SPSS的应用》 一、安装和启动 具体安装过程是参考spss下载以及安装详细教程这篇文章&#xff0c;下载安装包然后按他的步骤获取用户许可证即可。 二、主要窗口 数据编辑器窗口data editor 是SPSS的主程序窗…

UV映射技巧和窍门

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 有一个鲜为人知的主题是纹理映射。这始终是 3D 建模师想要处理的最后…

.NET 6中如何使用Redis

1、安装redis Redis在windows平台上不受官方支持&#xff0c;所以想要在window安装Redis就必须去下载windows提供的安装包。安装地址&#xff1a;https://github.com/tporadowski/redis/releases 2、在NueGet安装包 3、在appsettings.json文件里面添加Redis相关配置信息 &quo…

第11章 GUI Page480~486 步骤二十七 “脏数据”与“新文档”状态维护

wxMyPainterFrame类定义中声明新的成员&#xff1a; 增加一个全局变量&#xff0c;初始化新成员&#xff1a; 先实现TrySaveFile() SaveFile()暂时为空实现 增加两个新的私有成员方法&#xff1a; wxMyPainterFrame类中&#xff0c;修改了“_items”的几个地方 ① 鼠标抬起时…

uniapp中使用tmt-calendar字体的颜色如何修改

tmt-calendar这个插件市场下载的组件默认的眼色为深蓝&#xff0c;如下图 然后能够动态修改这些颜色的参数也很限制&#xff0c;就想着从源代码上面去修改&#xff0c; 但是本人在项目的src/components这个目录下找了很久没有找到 又去node_modules目录下寻找也没有找到&#…

嵌入式——循环队列

循环队列 (Circular Queue) 是一种数据结构(或称环形队列、圆形队列)。它类似于普通队列,但是在循环队列中,当队列尾部到达数组的末尾时,它会从数组的开头重新开始。这种数据结构通常用于需要固定大小的队列,例如计算机内存中的缓冲区。循环队列可以通过数组或链表实现,…

【深度学习】优化器介绍

文章目录 前言一、梯度下降法&#xff08;Gradient Descent&#xff09;二、动量优化器&#xff08;Momentum&#xff09;三、自适应学习率优化器 前言 深度学习优化器的主要作用是通过调整模型的参数&#xff0c;使模型在训练数据上能够更好地拟合目标函数&#xff08;损失函…

Fiddler工具 — 9.命令行和状态栏

1、命令行 命令行在Fiddler的左下方的黑色窗口&#xff0c;也叫QuickExec&#xff0c;可以调用 Fiddler的内置命令。 这一系列内置的函数用于筛选和操作会话列表中的session&#xff08;会话&#xff09;。 虽然它不是很显眼&#xff0c;但用好它&#xff0c;会让你的工作效率…

python 函数中字典的修改会影响函数外字典的值

def modify_dict(d):d[key] new valueprint(函数中字典d的位置,id(d))# 创建一个字典 original_dict {key: old value} print(函数外字典的位置,id(original_dict))# 调用函数来修改字典 modify_dict(original_dict)# 输出原始字典的值&#xff0c;可以看到它已经被修改了 pr…

致远OA getAjaxDataServlet XXE漏洞复现(QVD-2023-30027)

0x01 产品简介 致远互联-OA 是数字化构建企业数字化协同运营中台,面向企业各种业务场景提供一站式大数据分析解决方案的协同办公软件。 0x02 漏洞概述 致远互联-OA getAjaxDataServlet 接口处存在XML实体注入漏洞,未经身份认证的攻击者可以利用此漏洞读取系统内部敏感文件…

基于Spark个性化图书推荐系统

介绍 该系统基于Spark&#xff0c;结合了协同过滤算法和个性化推荐技术&#xff0c;实现了一款个性化的书籍推荐系统。 在该系统中&#xff0c;用户可以通过登陆注册后进入系统&#xff0c;查找和筛选自己喜欢的图书信息&#xff0c;同时也能够获得基于用户历史浏览、评分等数…

【PostgreSQL在线创建索引(CIC)功能的锁分析以及使用注意】

前一篇文章提到了普通创建索引会阻塞DML操作 PostgreSQL创建索引的锁分析和使用注意 而PostgreSQL里可以使用create index concurrently 在线创建索引(CIC)功能&#xff0c;降低创建索引在表上申请的锁的级别&#xff0c;ShareUpdateExclusiveLock级别的锁和RowExclusiveLock…

解决Qt Creator中文乱码的问题

方法1 使用QStringLiteral()包裹中文字符串 QString str1"中文测试&#xff01;"; QString str2QStringLiteral("中文测试&#xff01;");方法2 #if _MSC_VER > 1600//MSVC2015>1899,MSVC_VER14.0 #pragma execution_character_set("utf-8&qu…

第二百五十四回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"如何给图片添加阴影"相关的内容&#xff0c;本章回中将介绍自定义Radio组件.闲话休提&#xff0c;让我们一起Talk Flutter吧…

7个Pandas绘图函数助力数据可视化

大家好&#xff0c;在使用Pandas分析数据时&#xff0c;会使用Pandas函数来过滤和转换列&#xff0c;连接多个数据帧中的数据等操作。但是&#xff0c;生成图表将数据在数据帧中可视化&#xff0c;通常比仅仅查看数字更有帮助。 Pandas具有几个绘图函数&#xff0c;可以使用它…

Java面向对象综合练习(拼图小游戏),用java图形化界面实现拼图小游戏

1. 设计游戏的目的 锻炼逻辑思维能力利用Java的图形化界面&#xff0c;写一个项目&#xff0c;知道前面学习的知识点在实际开发中的应用场景 2. 游戏的最终效果呈现 Hello&#xff0c;各位同学大家好。今天&#xff0c;我们要写一个非常有意思的小游戏 —《拼图小游戏》 我们…

【机器学习】循环神经网络(三)

四、序列预测问题 循环神经网络实现的序列到序列的映射&#xff08;Recurrent Neural Network based Sequence-to-Sequence Mapping&#xff09;是一种使用循环神经网络来将一个序列数据映射到另一个序列数据的方法&#xff0c;它可以用于机器翻译、文本摘要、对话生成等任务。…

多国管理中心多语言区块链源码一元夺宝程序仿趣步奕跑/原生计步器/原生人脸识别

前后台分开的&#xff0c;后台是TP3.2的框架了&#xff0c;应该是比较老的程序了。 目前把整体UI 改版黄色系风格&#xff0c;集成了一元夺宝程序&#xff0c;用户数据同步趣步&#xff0c;效果看起来很棒&#xff0c;另外加入股票走势图&#xff08;K线图&#xff09;&#xf…

使用即时设计绘制原型设计方便吗?和Axure RP相比怎么样?

对于原型设计&#xff0c;APP 和 Web 都是一样的&#xff0c;因为产品原型是用来确定需求的工具。我们使用这种工具的目的是为了快速迭代&#xff0c;从而深入挖掘和筛选产品的需求。 绘制原型&#xff0c;最重要的原则是&#xff1a;快速、清晰&#xff01; Axure 工具的优缺…