目录

NPU边缘推理识物系统

一、项目简介

二、硬件介绍

三、软件设计

1、底层NPU推理代码

2、应用层QT显示代码

四、项目成果展示


NPU边缘推理识物系统

一、项目简介

物品分类是计算机视觉的重要技术,本项目的核心是:使用NPU(神经网络处理器或神经网络处理单元)进行本地推理计算识别。相比与传统的识别技术,NPU边缘推理识别不需要依赖网络和云端,它在本地SoC(System on Chip片上系统)上就可以高效、快速地处理AI任务。NPU在AI推理计算上比CPU更专业和高效,比GPU更省电。

二、硬件介绍

本项目使用的是NXP(恩智浦)推出的i.MX93,i.MX93处理器集成的NPU,搭载了 ARM 自研的 Ethos-U65。Ethos-U65 神经处理单元(NPU)是 ARM 为了在面积受限的嵌入式和物联网设备的情况下加速机器学习推理而设计。

项目开发板使用的是正点原子推出的ATK-DLIMX93 开发板

开发板实物展示

硬件层面虽然正点原子设计的接口很多,但是我们只使用了SoC中的NPU和屏幕进行效果展示。后期考虑接入摄像头设备。

注意:正点原子没有提供i.MX93的核心板原理图,如果想要自己设计出核心板需要借鉴NXP(恩智浦)官方提供的评估板原理图资料进行复刻。

三、软件设计

首先声明,我们项目的所有操作都是基于Linux操作系统来进行的,所以我们要对i.MX93上面烧录Linux操作系统之后再能进行后续软件开发。

1、底层NPU推理代码

底层NPU推理识别流程图

底层控制NPU推理识别Python代码

'''
项目所有文件名 : main4.py
作者 : SELSL
版本 : V1.0
描述 : 使用NPU推理得出图片类型
其他 : 无
论坛 : 无
日志 : 初版 V1.0 2025/8/8 SELSL创建
'''
​
#导入依赖库
#用于加载和运行 .tflite 格式的模型
import tflite_runtime.interpreter as tflite
#用于处理数组和数值计算
import numpy as np
#(OpenCV): 用于视频捕获、图像处理和保存图像
import cv2
#用于测量代码执行时间
import time
#用于解析命令行参数
import argparse
#将模型输出的类别索引映射为人类可读的类别名称
from labels import label2string
​
#定义模型路径和解析命令行参数
#指定了 .tflite 模型文件的路径
MODEL_PATH = "../vela_models/ssd_mobilenet_v1_quant_vela.tflite"
​
parser = argparse.ArgumentParser()
parser.add_argument('-i','--input',default='/dev/video0',help='input to be classified')
parser.add_argument('-d','--delegate',default='',help='delegate path')
args = parser.parse_args()
​
#设置图片输入
if args.input.isdigit():cap_input = int(args.input)
else:cap_input = args.input
vid = cv2.VideoCapture(cap_input)
​
#加载和初始化 TFLite 模型
if args.delegate:ext_delegate = [tflite.load_delegate(args.delegate)]interpreter = tflite.Interpreter(model_path=MODEL_PATH, experimental_delegates=ext_delegate)
else:interpreter = tflite.Interpreter(model_path=MODEL_PATH)
interpreter.allocate_tensors()
​
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
height = input_details[0]['shape'][1]
width = input_details[0]['shape'][2]
​
#初始化性能计数器和读取照片
total_fps = 0
total_time = 0
​
ret, frame = vid.read()
if frame is None:print("Can't read frame from source file", args.input)exit(0)
​
saved = False
​
#主循环
while ret:total_fps += 1loop_start = time.time()
​#图像预处理img = cv2.resize(frame, (width, height)).astype(np.uint8)input_data = np.expand_dims(img, axis=0)interpreter.set_tensor(input_details[0]['index'], input_data)#执行推理invoke_start = time.time()interpreter.invoke()invoke_end = time.time()
​#获取和处理推理结果boxes = interpreter.get_tensor(output_details[0]['index'])[0]labels = interpreter.get_tensor(output_details[1]['index'])[0]scores = interpreter.get_tensor(output_details[2]['index'])[0]number = interpreter.get_tensor(output_details[3]['index'])[0]
​#后处理与可视化if int(number) > 0 and not saved:for i in range(int(number)):if scores[i] > 0.5:box = [boxes[i][0], boxes[i][1], boxes[i][2], boxes[i][3]]x0 = max(2, int(box[1] * frame.shape[1]))y0 = max(2, int(box[0] * frame.shape[0]))x1 = int(box[3] * frame.shape[1])y1 = int(box[2] * frame.shape[0])
​cv2.rectangle(frame, (x0, y0), (x1, y1), (255, 0, 0), 2)cv2.putText(frame, label2string[labels[i]], (x0, y0 + 13),cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)print(f"Detected object: ({x0},{y0})-({x1},{y1}) label:{label2string[labels[i]]} score:{scores[i]:.2f}")
​cv2.imwrite('test.bmp', frame)print("Detection result saved as test.bmp")saved = True
​#性能计算与显示loop_end = time.time()total_time += (loop_end - loop_start)
​fps = int(total_fps / total_time)invoke_time = int((invoke_end - invoke_start) * 1000)print(f"Processing frame {total_fps}: FPS={fps}, Inference time={invoke_time}ms")
​#检查退出ret, frame = vid.read()if cv2.waitKey(1) & 0xFF == ord('q'):break
​
vid.release()

2、应用层QT显示代码

QT应用层代码流程图

显示图像框架预览

QT核心代码预览

/***************************************************************
项目所有文件名 : mainwindow.h main.c mainwindow.c mainwindow.ui
作者 : SELSL
版本 : V1.0
描述 : 使用NPU推理得出图片类型
其他 : 无
论坛 : 无
日志 : 初版 V1.0 2025/8/8 SELSL创建
***************************************************************/
#include "mainwindow.h"
#include "ui_mainwindow.h"
​
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);
​//设置工作路径,方便后续操作图片处理命令QDir::setCurrent("/usr/bin/eiq-examples-git/object_detection");//创建QProcess对象,方便后期进行命令执行process = new QProcess;
​
}
​
MainWindow::~MainWindow()
{delete process;delete imageLabel;delete imageLabel2;delete ui;
}
​
//关闭窗口
void MainWindow::on_pushButton_2_pressed()
{close();
}
​
//打开对象图片,并显示
void MainWindow::on_toolButton_clicked()
{//使用QFileDialog中的getOpenFileName获取要进行目标检测的图片地址QString imageName = QFileDialog::getOpenFileName(this, tr("请选择图片"), "/usr/bin/eiq-examples-git/object_detection");//输出图片地址是否正确qDebug() << imageName;//把图片地址放入QLineEdit组件中,方便用户查看ui->lineEdit->setText(imageName);//创建QLabel标签对象,为放置图片做准备imageLabel = new QLabel;//把图片放入QImage对象中QImage image(imageName);//把图片放入QPixmap处理,在放入QLabel中imageLabel->setPixmap(QPixmap::fromImage(image));//最终把图片展示在界面的QScrollArea组件中,显示出要识别的图片,方便用户直观的查看图片。ui->sa_object->setWidget(imageLabel);
}
​
//开始目标采集,并显示
void MainWindow::on_pushButton_clicked()
{//输出当前的工作目录qDebug() << QDir::currentPath();//使用 NPU 推理进行目标检测的终端命令QString command1 = QString("python3 main4.py -i ");QString command2 = QString(ui->lineEdit->text());QString command3 = QString(" -d /usr/lib/libethosu_delegate.so");QString command = command1 + command2 + command3;//输出验证终端命令是否正确qDebug() << command;//开始使用NPU 推理进行目标检测process->start("/bin/sh", QStringList() << "-c" << command);//等待使用NPU推理进行目标检测完成process->waitForFinished();
​//输出NPU推理目标检测完成后的输出信息QString output = process->readAllStandardOutput();qDebug() << output;
​//得到NPU推理得出的目标图片地址QString imageName = QString("/usr/bin/eiq-examples-git/object_detection/test.bmp");//输出图片地址是否正确qDebug() << imageName;
​//创建QLabel标签对象,为放置图片做准备imageLabel2 = new QLabel;//把图片放入QImage对象中QImage image(imageName);//把图片放入QPixmap处理,在放入QLabel中imageLabel2->setPixmap(QPixmap::fromImage(image));//向目标QScrollArea展示推理得出的目标图片ui->sa_result->setWidget(imageLabel2);
}

注意:QT应用层代码有mainwindow.h main.c mainwindow.c mainwindow.ui,这里只显示了最核心的部分mainwindow.c,其他代码请向项目成员SELSL获取。

四、项目成果展示

代码预览展示

调试阶段性结果展示

最终结果演示

注意:这个项目我们采用的是官方提供的免费开源模型,开源的,你懂的,就是能用,但是效果没有自己训练的模型或买的模型效果好,所以有一部分物体识别达不到先要的效果,包括本团队后期使用NPU进行的人脸识别推理,同一个人识别出不同的效果的现象。这不是代码的问题也NPU的问题,而是模型上的问题。

我们的NPU算力达到了6TOPs,在移动终端设备上是一个比较快的水准,当然向上与GPU几百的算力相比还是稍显逊色,但是相比于功耗来说,我们的NPU的功耗是远远低于GPU的功耗。这里通过上面的调试推理过程也可以看到推理时间大概在4ms左右,这也是一个很快的推理速度,相比与传统的把图片上传至云端耗时操作好点的,特别是在实时性要求比较高的场所,NPU边缘推理是一个很好的解决方案。

资料获取:https://download.csdn.net/download/2403_82436914/91888061

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# WinForm分页控件实现与使用详解

C# WinForm分页控件实现与使用详解概述在WinForms应用程序开发中&#xff0c;数据分页是常见的需求。本文将介绍如何实现一个功能完整的分页控件&#xff0c;并在窗体中如何使用该控件进行数据分页展示。分页控件实现核心属性与字段public partial class PageControl : UserCon…

高级 ACL 有多强?一个规则搞定 “IP + 端口 + 协议” 三重过滤

一、实验拓扑及描述 二、实验需求 1、完成拓扑中各设备的基础配置&#xff0c;使得全网互通&#xff1b; 2、在上一个需求的基础上&#xff0c;在路由器上部署高级ACL&#xff0c;使得Client1无法访问Server的HTTP服务&#xff0c;但是PC1依然能够访问服务器及其他节点&#xf…

支持多材质密度设置的金属重量计算使用指南

传统手工计算各种型材&#xff08;如钢管、角钢、钢板等&#xff09;的重量繁琐且容易出错。 它的体积小巧&#xff0c;不足100KB&#xff0c;运行不占内存&#xff0c;绿色免安装&#xff0c;双击即开&#xff0c;使用便捷。 可计算钢管、钢板、型钢、角钢等常见型材的重量&a…

在Spring Boot中使用H2数据库

好处 程序启动时自动创建数据库数据表。 使用步骤 引入依赖&#xff1a; <dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency><dependency><groupId&…

Day21_【机器学习—决策树(2)—ID3树 、C4.5树、CART树】

一、ID3 决策树1. 核心思想使用信息增益&#xff08;Information Gain&#xff09;作为特征选择的标准&#xff0c;递归地构建决策树。2. 特征选择标准信息增益&#xff08;IG&#xff09;&#xff1a;选择使信息增益最大的特征进行划分。3. 优点算法简单&#xff0c;易于理解。…

2025计算机视觉新技术

CLIP / BLIP-3 类「视觉-语言大模型」 • 是什么&#xff1a;让网络自己学会“看图说话”&#xff0c;zero-shot 就能分类、检测、检索。 • 能干什么&#xff1a;不写训练代码&#xff0c;直接一句中文 prompt 就把商品图分成 500 类。 • 落地难度&#xff1a;★☆☆&#xf…

[光学原理与应用-431]:非线性光学 - 能生成或改变激光波长的物质或元件有哪些?

要生成或改变激光波长&#xff0c;可依赖增益介质、非线性光学元件、调谐元件及特殊激光器设计&#xff0c;以下是一些关键物质和元件及其作用机制&#xff1a;一、增益介质&#xff1a;波长的“决定者”增益介质是激光器的核心&#xff0c;其原子或分子的能级结构直接决定输出…

接口权限验证有哪些方式

接口权限验证是保障 API 安全的核心机制&#xff0c;常见的方式有以下几类&#xff0c;适用于不同场景和安全需求&#xff1a; 1. 基于令牌&#xff08;token&#xff09;的验证 &#xff08;1&#xff09;JWT&#xff08;JSON Web Token&#xff09; 原理&#xff1a; 服务器验…

Go开发的自行托管代理加速服务:支持Docker与GitHub加速

HubProxy&#xff1a;一站式解决Docker与GitHub访问难题的轻量级代理服务作为开发者&#xff0c;我们经常遇到这些问题&#xff1a;Docker镜像拉取速度慢得让人抓狂&#xff0c;GitHub Release文件下载到一半断开&#xff0c;或者某些境外容器仓库完全无法访问。最近发现的hubp…

用Python打造逼真的照片桌面:从拖拽到交互的完整实现

在这个数字化时代&#xff0c;我们经常需要处理大量的照片和图片文件。今天我将带你一步步实现一个功能丰富的照片桌面程序&#xff0c;让你可以像在真实桌面上摆放照片一样操作数字图片。这个程序使用wxPython构建&#xff0c;支持拖拽、调整大小、删除等交互功能。C:\pythonc…

《sklearn机器学习——模型的持久性》joblib 和 pickle 进行模型保存和加载

模型持久性在 Scikit-learn 中的应用详解 模型持久性的基本概念 在机器学习领域&#xff0c;模型持久性是指将训练好的模型保存到磁盘或数据库中&#xff0c;以便在后续的预测任务中能够直接使用&#xff0c;而无需重新训练模型。这一过程不仅提高了模型的可重用性&#xff0c;…

前端-组件化开发

目录 一.组件化 二.根组件 三.App.vue文件&#xff08;单文件组件&#xff09;的三个组成部分 四.普通组件的注册和使用&#xff1a; 1.普通组件的创建 2.局部注册 3.全局注册 &#x1f9e0; 补充小技巧&#xff1a; &#x1f4a1; 关于组件名&#xff08;第一个参数&…

UNIX/macOS路由表查询原理与实现

&#x1f310; UNIX/macOS路由表查询原理与实现&#x1f4cc; 功能全景图 #mermaid-svg-mz6rxrQ73xinNsqc {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-mz6rxrQ73xinNsqc .error-icon{fill:#552222;}#mermaid-svg…

Python爬虫实战:研究Style sheets模块,构建电商平台笔记本电脑销售数据采集和分析系统

1. 引言 1.1 研究背景 在数字经济时代,互联网蕴含的海量数据已成为企业决策与学术研究的核心资源。网络爬虫技术通过自动化请求、解析网页,能够高效提取公开数据,为市场分析、竞品研究等场景提供基础支撑。Python 凭借其丰富的生态库(如 Requests、BeautifulSoup、Pandas…

lesson55:CSS导航组件全攻略:从基础导航条到动态三级菜单与伸缩菜单实现

目录 一、CSS导航条&#xff1a;构建基础导航系统 1.1 语义化HTML结构 1.2 现代Flexbox布局实现 1.3 核心技术解析 二、三级菜单&#xff1a;构建多层级导航体系 2.1 嵌套HTML结构 2.2 多级菜单CSS实现 2.3 关键技术解析 三、伸缩菜单&#xff1a;实现动态交互导航 3…

Linux基础知识(二)

文件操作1. 怎么理解 I/O 重定向&#xff1f; 2. /dev/null 是什么&#xff0c;有什么用途&#xff1f; 3. 解释下列命令的结果&#xff1a;&> /dev/null 、2>> file 4. 怎么理解管道&#xff1f;管道和重定向有什么区别&#xff1f; 5. 在什么情况下需要使用 tee…

Ribbon和LoadBalance-负载均衡

Ribbon和LoadBalance-负载均衡 Ribbon 和 Spring Cloud LoadBalancer (SCL) 都是 Spring Cloud 生态中实现客户端负载均衡的核心组件&#xff0c;但它们在定位、架构、实现和功能上有显著区别。以下是详细的对比分析&#xff1a; ​1. 核心定位与背景​​Ribbon:​​起源于 ​N…

【数据可视化-107】2025年1-7月全国出口总额Top 10省市数据分析:用Python和Pyecharts打造炫酷可视化大屏

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

Java中的字符串

字符串 String Java编译器对String类型有特殊处理&#xff0c;可用使用"…"来表示一个字符串。实际上字符串在String内部是通过一个数组表示的。 Java中字符串的一个重要特点是不可变。这种不可变性是通过内部的private final char[]字段&#xff0c;以及没有任何修改…

ragflow MCP 调用核心提示词解析:逻辑闭环与优化方向

大家好&#xff5e;我是你们的提示词工程师朋友&#xff0c;今天想跟大家聊聊开源项目 ragflow 里&#xff0c;MCP调用体系中的两个关键提示词。最近在研究调用工具和提示词撰写之间的平衡态。这俩家伙在信息处理和问题解决里作用不小&#xff0c;既有让人眼前一亮的优势✨&…