实战精选|如何使用 OpenVINO™ 在 ElectronJS 中创建桌面应用程序

点击蓝字

关注我们,让开发变得更有趣

作者 | Mikołaj Roszczyk  华沙理工大学物联网工程师

翻译 | 武卓 英特尔 AI 软件布道师

排版 | 吴紫琴

OpenVINO™

最近,我完成了一个 demo 演示,展示了 OpenVINO™ 在 Node.js 框架中的强大功能。得益于与 Electron.js 的集成,该演示不仅能够高效地执行神经网络推理,还提供了交互式的用户体验。

OpenVINO™

应用程序概览:一种简单的背景虚化方法

这个演示展示了如何在 Node.js 环境中使用 OpenVINO™ 工具包实现背景虚化,并通过 Electron.js 创建的直观桌面界面进行呈现。启动应用程序后,您会看到一个带有黑色占位符的界面。要激活摄像头,只需从检测到的设备列表中选择您喜欢的视频源并点击“开始”。

99573ae588f3fbaa3ec23c8e1f5192ad.png

完成此步骤后,您应该会在界面中的框内看到来自摄像头的实时视频流。

2440b5b608eb8eac52c6ee27dc031ef3.png

最初,您的画面将显示为未经过任何虚化处理的原始图像。要启用背景虚化功能,请通过指定的切换开关打开推理模式。该应用还允许您选择推理设备,可以在操作前或操作过程中进行设置。当您在会话中首次选择设备时,可能会出现短暂的延迟,因为模型需要进行编译。

bcdc0c1a19a82874225c914e2360a54b.png

在摄像头画面上方,您会看到一个推理时间显示器,显示最近50帧的平均推理时间。同时,还会显示每秒处理(或推理)的帧数,让您了解性能表现。

在应用运行期间,您可以随时停止摄像头或推理,切换视频源,或更改推理设备。

OpenVINO™

项目架构

完整代码可以在 OpenVINO™ Build & Deploy 仓库中找到。该 Electron 应用项目分为几个关键部分:

GitHub - openvinotoolkit/openvino_build_deploy: Pre-built components and code samples to help you build and deploy production-grade AI applications with the OpenVINO™ Toolkit from Intel

  • 界面(Interface):

包括定义界面视觉效果的 HTML 和 CSS 文件,以及控制功能的 renderer.js 文件。

  • OpenVINO™ 任务(OpenVINO Jobs):

后端组件,位于 ov-jobs.js 文件中,包含推理、前处理、后处理和背景虚化的相关函数。

  • 主程序(Main):

main.js 文件负责启动应用程序,设置必要参数,并处理中断等操作。

  • 预加载(Preload):

preload.js 文件作为主程序与界面组件之间的桥梁,启用后端功能并处理用户触发的中断。

  • Node 模块(Node Modules):

程序所需的外部库和模块列在 package.json 文件中,同时包含其他必要的开发信息。要安装这些模块,只需在主目录运行以下命令:

npm install

保持清晰的项目架构至关重要,因为 OpenVINO™ 的 Node.js 库只能在后端运行。如果将其导入到界面层会导致错误。因此,最佳实践是将 OpenVINO™ 的导入限制在 ov-jobs.js 文件中。

OpenVINO™

它是如何工作的?

背景虚化功能使用了一个来自 TensorFlow 的分割模型,名为 “TensorFlow_Lite_Frontend_IR”,该模型已被转换为 OpenVINO™ 的 IR 格式。此模型要求输入尺寸为 1x3x256x256,因此在预处理步骤中,需要将图像调整为正方形(无需填充)。如果图像不是 RGB 格式,还需要将其颜色表示转换为 RGB 格式。

const sharp = require('sharp');// originalImg is a sharp object.async function preprocess(originalImg) {const inputSize = { w: 256, h: 256 };const inputImg = await originalImg.resize(inputSize.w, inputSize.h, { fit: 'fill' }).removeAlpha() // converting RGBA to RGB.raw().toBuffer();const resizedImageData = new Uint8ClampedArray(inputImg.buffer);const tensorData = Float32Array.from(resizedImageData, x => x / 255);const shape = [1, inputSize.w, inputSize.h, 3];return new ov.Tensor(ov.element.f32, shape, tensorData);

该模型作为分类器工作,将图像中的每个像素分配到六个类别之一,其中类别 0 代表背景。在推理后,输出会经过后处理生成一个掩码,其中 0 表示背景(需要进行虚化),1 表示其他元素(需要保持清晰)。随后,该掩码会被调整为与原始图像尺寸匹配。

程序运行时采用两个主要线程:一个线程从摄像头捕获帧,根据掩码对背景进行虚化处理,并将处理后的结果显示在屏幕上。另一个线程“借用”一帧图像,运行推理以更新掩码,确保摄像头的画面保持流畅,即使某些设备上的推理需要较长时间。

OpenVINO™

在 JavaScript 中使用 OpenVINO™ 的基本功能

发现可用来进行推理的设备:

const { addon: ov } = require('openvino-node');const core = new ov.Core();
const devices = core.getAvailableDevices();

读入和编译模型:

const { addon: ov } = require('openvino-node');const core = new ov.Core();
const modelPath = "path/to/your/model";
const model = await core.readModel(modelPath);
const device = "AUTO"; // or "GPU", "CPU" and others
const compiledModel = await core.compileModel(model, device);

运行编译后的模型:

// have compiledModel and inputTensor prepared
let inferRequest = compiledModel.createInferRequest();
inferRequest.setInputTensor(inputTensor);
inferRequest.infer()  // inference
const outputLayer = compiledModel.outputs[0]; // only one output in this scenario
const resultTensor = inferRequest.getTensor(outputLayer); // your inference result

虚化步骤:

这是最简单的虚化图像的方式:

  1. 捕获一帧图像
    从摄像头捕获当前帧。

  2. 复制并虚化图像
    创建原始图像的副本,使用 sharp.blur() 对整个副本进行虚化处理(替代方案:OpenCV 或卷积操作)。

  3. 获取分割模型生成的掩码
    在独立线程中运行分割模型,获取当前帧的掩码。

  4. 应用掩码到虚化图像
    将虚化图像的所有像素值与掩码相乘,保留需要虚化的区域。

  5. 生成“反掩码”
    计算掩码的反值(即 1 - mask),生成“非虚化区域掩码”。

  6. 应用“反掩码”到原始图像
    将原始图像的像素值与“反掩码”相乘,保留需要保持清晰的区域。

  7. 融合两张图像
    将虚化后的图像和清晰区域的图像进行融合,生成最终图像。

在最终的应用程序代码中,多个操作被整合在一起,充分利用了 Sharp 库的功能。以下是使用 Sharp 实现的方法:

  • 根据掩码裁剪原始图像:

const sharp = require('sharp');const person = await sharp(outputMask, {raw: {channels: 3,width: inputSize.w,height: inputSize.h,}}).resize(width, height, { fit: 'fill' }).unflatten().composite([{input: image.data,raw: {channels: 4,width,height,},blend: 'in',}]).toBuffer();
  • 对副本进行虚化处理,并将其与裁剪后的原始图像合并(复合):

const blurSize = Math.floor(widthOfImage * 0.01)
const blurredImage = await sharp(imageToBlur.data, {raw: { channels: 4, width, height }, // back to RGBA
}).blur(blurSize).composite([{input: person,raw: { channels: 4, width, height },blend: 'atop'}]).raw().toBuffer();

OpenVINO™

虚化面临的挑战

图像虚化是一项耗时的操作,对性能影响较大,尤其是当它是图像显示线程的一部分时,这直接关系到用户体验。没有人希望视频流出现卡顿。


一种优化方法是在一开始就将图像调整为最终显示的大小。较小的图像处理速度更快,从而提高性能。

起初,我们尝试使用 OpenCV 的虚化功能(通过 opencv-wasm 模块)。然而事实证明,其速度太慢,甚至比模型推理还慢,这促使我们寻找替代方案。

我们曾设想创建一个专门用于虚化的轻量化模型。该模型以图像帧和掩码作为输入,执行“虚化过程”部分描述的数学操作,并通过深度卷积(Depthwise Convolution)实现虚化。我们使用 TensorFlow 构建了这个模型,并将其转换为 OpenVINO 格式。

  • 重要说明:OpenVINO™ 从 2024.4 版本开始支持深度卷积操作。

尽管这种方法具有潜力,但由于深度卷积速度较慢且优化不足,最终被我们放弃。

最终,我们发现 Sharp 库在此操作中表现最佳,因此将其作为项目中的解决方案。

OpenVINO™

总结

如果遵循以下关键指南,使用 Electron.js 和 OpenVINO™ 创建桌面应用程序是非常简单的:

  • 前后端功能分离:
    确保将后端功能与前端功能分开,并记住 OpenVINO™ 只能在后端使用。

  • JavaScript API 的局限性:
    并非所有 Python 中可用的 OpenVINO™ 方法都已在 JavaScript 中实现。然而,当前的 API 已足以完成大多数任务。

  • 阅读文档:
    许多常见问题的答案都可以在文档中找到。参考 OpenVINO™ Node.js API 文档以获取更多信息。

  • 检查库兼容性:
    某些 JavaScript 库可能无法很好地与 Electron 配合使用。在这些情况下,您可能需要寻找替代版本或定制分支。


别忘了亲自体验一下 "Hide Your Mess Behind" 应用程序!您可以从代码仓库运行该应用程序,也可以下载适用于 Windows(exe)或 Linux(deb、rpm)的可执行版本。

下载exe文件,一键运行安装的效果如下

OpenVINO™

---------------------------------------

*OpenVINO and the OpenVINO logo are trademarks of Intel Corporation or its subsidiaries.

-----------------------------

 OpenVINO 中文社区 

微信号 : openvinodev

B站:OpenVINO中文社区

“开放、开源、共创”

致力于通过定期举办线上与线下的沙龙、动手实践及开发者交流大会等活动,促进人工智能开发者之间的交流学习。

○ 点击 “ 在看 ”,让更多人看见

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

PyCharm的类型警告: Expected type ‘SupportsWrite[bytes]‘, got ‘BinaryIO‘ instead

记录时使用的PyCharm版本: PyCharm 2024.3 (Professional Edition) Build #PY-243.21565.199, built on November 13, 2024 问题描述 当在PyCharm里使用pickle保存文件, 比如以下代码这样: with open(meta_save_path, wb) as f:pickle.dump(meta, f)会发现PyCharm对此发出类型…

【Docker】快速部署 Pikachu:一个包含常见 Web 安全漏洞的渗透测试练习靶场

系统介绍 Pikachu是一个带有漏洞的Web应用系统,在这里包含了常见的web安全漏洞。 如果你是一个Web渗透测试学习人员且正发愁没有合适的靶场进行练习,那么Pikachu可能正合你意。 Pikachu上的漏洞类型列表如下: Burt Force(暴力破解漏洞) XSS…

vscode 执行 vue 命令无效/禁止运行

在cmd使用命令可以创建vue项目但是在vscode上面使用命令却不行 一、问题描述 在 cmd 中已确认vue、node、npm命令可以识别运行,但是在 vscode 编辑器中 vue 命令被禁止,详细报错为:vue : 无法加载文件 D:\Software\nodejs\node_global\vue.…

【电路笔记 通信】:数字式时分制指令响应型多路传输数据总线 1553协议 289A-97协议

系统及组成 MIL-STD-1553是一种用于航空、航天和军用系统中的多路传输数据总线标准。最初由美国国防部在1973年制定,该标准旨在为军用飞机、导弹和其他嵌入式系统提供可靠的数据通信,现已被广泛应用于航空航天、卫星、舰船、地面车辆以及其他关键任务系统…

npm/cnpm的使用

npm 1、安装npm 前往nodejs官网下载安装node 验证是否安装成功node node -v node安装npm也会安装 npm -v 2、使用npm 1. 初始化项目 在一个项目文件夹中运行: npm init 根据提示输入项目信息(如项目名称、版本号等)。 如果你希望快速初…

红外相机和RGB相机外参标定 - 无需标定板方案

1. 动机 在之前的文章中红外相机和RGB相机标定:实现两种模态数据融合_红外相机标定-CSDN博客 ,介绍了如何利用标定板实现外参标定;但实测下来发现2个问题: (1)红外标定板尺寸问题,由于标定板小…

web小:在html页面实现多边形按钮

效果如下图所示 主要是使用了clip-path&#xff0c;代码如下 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">&l…

【蓝桥杯C/C++】翻转游戏:多种实现与解法解析

文章目录 &#x1f4af;题目&#x1f4af;问题分析解法一&#xff1a;减法法解法二&#xff1a;位运算解法解法三&#xff1a;逻辑非解法解法四&#xff1a;条件运算符解法解法五&#xff1a;数组映射法不同解法的比较 &#x1f4af;小结 &#x1f4af;题目 在蓝桥镇&#xff0…

V-rep机器人仿真软件学习笔记

常用的机器人仿真软件有哪些&#xff1f;为什么选择V-rep&#xff1f; 目前常用的机器人物理仿真软件有Gazebo、V-rep、Webots等&#xff0c;这三款都是开源软件&#xff0c;自己使用过前两种&#xff0c;Gazebo配合ROS使用功能十分强大&#xff0c;但是要在Linux系统下使用&am…

第7章 硬件测试-7.1 硬件调试

第7章 硬件测试 7.1 硬件调试7.1.1 电路检查7.1.2 电源调试7.1.3 时钟调试7.1.4 主芯片及外围小系统调试7.1.5 存储器件和串口外设调试7.1.6 其他功能模块调试 测试是每项成功产品的必经环节。硬件测试是评估产品质量的重要方法&#xff0c;产品质量是公司的信誉和品牌象征&…

《深入理解 Spring MVC 工作流程》

一、Spring MVC 架构概述 Spring MVC 是一个基于 Java 的轻量级 Web 应用框架&#xff0c;它遵循了经典的 MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;将请求、响应和业务逻辑分离&#xff0c;从而构建出灵活可维护的 Web 应用程序。 在 Spring MV…

基于Java Springboot宿舍管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

LeetCode螺旋矩阵

快一个月没刷题了&#xff0c;最近工作有些忙&#xff0c;今天闲下来两小时&#xff0c;刷一道 题目描述 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4…

探索CompletableFuture:高效异步编程的利器

目录 一、CompletableFuture基本功能安利 二、CompletableFuture使用介绍 &#xff08;一&#xff09;任务创建使用 1.supplyAsync创建带有返回值的异步任务 2.runAsync创建没有返回值的异步任务 &#xff08;二&#xff09;异步回调使用 1.异步回调&#xff1a;thenApp…

java的强,软,弱,虚引用介绍以及应用

写在前面 本文看下Java的强&#xff0c;软&#xff0c;弱&#xff0c;虚引用相关内容。 1&#xff1a;各种引用介绍 顶层类是java.lang.ref.Reference,注意是一个抽象类&#xff0c;而不是接口&#xff0c;其中比较重要的引用队列ReferenceQueue就在该类中定义&#xff0c;子…

基于STM32的智能垃圾分类投递系统设计

目录 引言系统需求与设计目标硬件设计 3.1 核心控制模块 3.2 传感器模块 3.3 驱动模块 3.4 显示模块 3.5 通信模块软件设计 4.1 数据采集与处理 4.2 垃圾分类逻辑实现 4.3 状态显示与远程监控代码实现 5.1 数据采集与处理 5.2 分类逻辑与控制 5.3 状态显示与通信 5.4 主程序实…

手摸手6-创建前端应用

目录 手摸手6-创建前端应用简介命令 npm create vue 和 npm init vue3的区别 使用 Create-Vue 创建应用1、输入命令 npm create vue 创建应用2、输入命令 npm install 安装相关依赖3、输入命令 npm run dev 运行项目 项目结构 手摸手6-创建前端应用 简介 create-vue 是 vue 应…

第T8周:Tensorflow实现猫狗识别(1)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 具体实现 &#xff08;一&#xff09;环境 语言环境&#xff1a;Python 3.10 编 译 器: PyCharm 框 架: &#xff08;二&#xff09;具体步骤 from absl.l…

【MySQL】数据库基础

1.数据库基本认识 广义上来说数据库是长期存储在磁盘上的数据文件的集合&#xff0c;而MySQL是采用了C/S模式实现的一个网络服务&#xff0c;它由MySQL&#xff08;数据库客户端&#xff09; 、MySQLD &#xff08;数据库服务&#xff09;、磁盘上的数据库文件组成。MySQL服务是…

AWS IAM

一、介绍 1、简介 AWS Identity and Access Management (IAM) 是 Amazon Web Services 提供的一项服务&#xff0c;用于管理 AWS 资源的访问权限。通过 IAM&#xff0c;可以安全地控制用户、组和角色对 AWS 服务和资源的访问权限。IAM 是 AWS 安全模型的核心组成部分&#xf…