【HZHY-AI300G智能盒试用连载体验】使用YOLOv8进行车辆流量监测

目录

YOLOv8的RKNN模型

程序的部署

流量统计


本文首发于电子发烧友论坛:【新提醒】【HZHY-AI300G智能盒试用连载体验】+ 智能工业互联网网关 - 北京合众恒跃科技有限公司 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com)

环境准备好之后,接下来利用RK3588的NPU进行道路视频中的车辆识别,根据识别到的车辆的数量估计道路的流量情况,实现智慧交通中的流量监控功能。

YOLOv8的RKNN模型

我们使用YOLOv8框架进行目标的检测。YOLOv8(You Only Look Once version 8)是一个深度学习框架,用于实现实时对象检测。YOLOv8 继承了前代模型的优点,并在此基础上进行了多项改进,包括更复杂的网络架构、更优化的训练流程和更强大的特征提取能力。

厂商在其Github仓库中提供了大量已经优化和测试验证过的模型,其中就包括YOLOv8:

https://github.com/airockchip/rknn_model_zoo/blob/main/examples/yolov8/README.md。

厂商提供的模型是一个优化后的模型,与官方原始模型不同。以yolov8n.onnx为例来展示它们之间的差异。

1、它们输出信息的对比如下。左边是官方原始模型的输出,右边是优化后的模型输出。如图所示,原始模型的输出被分为三个部分。例如,在输出集合([1,64,80,80],[1,80,80,80],[1,1,80,80])中,[1,64,80,80]是边界框的坐标,[1,80,80,80]是对应于80个类别的边界框置信度,而[1,1,80,80]是80个类别置信度的总和。

请注意,这里的解释是基于常见目标检测模型(如YOLO系列)的输出格式,具体细节(如维度含义)可能因模型版本或实现而异。但一般来说,上述解释提供了关于YOLO类模型输出结构的通用理解。

2、以输出集合([1,64,80,80],[1,80,80,80],[1,1,80,80])为例,瑞芯微在模型中移除了两个卷积节点之后的子图,保留了这两个卷积的输出([1,64,80,80],[1,80,80,80]),并增加了一个reducesum+clip分支来计算80个类别置信度的总和([1,1,80,80])。

这里的“reducesum”操作通常用于对某个维度上的元素进行求和,而“clip”操作用于限制求和结果的取值范围,以避免数值溢出或保持数值在特定范围内。

 

这里提供的YOLOv8模型的训练方法和官方的完全相同,只是在导出的时候做了一些修改,有关导出 RKNPU 适配模型说明请见:https://github.com/airockchip/ultralytics_yolov8/blob/main/RKOPT_README.zh-CN.md。

程序的部署

YOLOv8程序在RK3588上的部署,我们参考了风筝2100的博文RK3588 npu python运行 YOLOv8 和 YOLOv8-seg 的教程_rk3588支持yolov9版 android-CSDN博客,在此表示感谢。

和RKNN_model_zoo 中的examples 提供的YOLOv8 的相关 demo对比,该程序有两点改进:

1)借助rknn-multi-threaded(https://github.com/leafqycc/rknn-multi-threaded)使用多线程推理提高NPU的占用率,参考:多线程异步提高RK3588的NPU占用率,进而提高yolov5s帧率_rk3588 多线程_rknn多线程-CSDN博客

2)优化了Python 后处理部分去除PyTorch 依赖,将后处理耗时从几百毫秒降低到了几十毫秒。

在 main.py 文件中,可以修改模型、线程数,还可以修改成实时推理摄像头。

# 推理视频文件cap = cv2.VideoCapture('./720p60hz.mp4')# 推理实时摄像头
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH,640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,480)

 程序启动后会显示RNKK的相关信息:

python3 main.pyI RKNN: [19:25:32.433] RKNN Runtime Information, librknnrt version: 2.0.0b0 (35a6907d79@2024-03-24T10:31:14)I RKNN: [19:25:32.433] RKNN Driver Information, version: 0.9.3I RKNN: [19:25:32.434] RKNN Model Information, version: 6, toolkit version: 1.6.0+81f21f4d(compiler version: 1.6.0 (585b3edcf@2023-12-11T07:42:56)), target: RKNPU v2, target platform: rk3588, framework name: ONNX, framework layout: NCHW, model inference type: static_shape./rknnModel/yolov8s.rknn         doneI RKNN: [19:25:32.644] RKNN Runtime Information, librknnrt version: 2.0.0b0 (35a6907d79@2024-03-24T10:31:14)I RKNN: [19:25:32.644] RKNN Driver Information, version: 0.9.3I RKNN: [19:25:32.644] RKNN Model Information, version: 6, toolkit version: 1.6.0+81f21f4d(compiler version: 1.6.0 (585b3edcf@2023-12-11T07:42:56)), target: RKNPU v2, target platform: rk3588, framework name: ONNX, framework layout: NCHW, model inference type: static_shape./rknnModel/yolov8s.rknn         doneI RKNN: [19:25:32.770] RKNN Runtime Information, librknnrt version: 2.0.0b0 (35a6907d79@2024-03-24T10:31:14)I RKNN: [19:25:32.770] RKNN Driver Information, version: 0.9.3I RKNN: [19:25:32.771] RKNN Model Information, version: 6, toolkit version: 1.6.0+81f21f4d(compiler version: 1.6.0 (585b3edcf@2023-12-11T07:42:56)), target: RKNPU v2, target platform: rk3588, framework name: ONNX, framework layout: NCHW, model inference type: static_shape./rknnModel/yolov8s.rknn         done

流量统计

我们在每帧推理结束后,统计其中"car"、"motorbike "、 "bus"和"truck"对象的数量,作为流量统计的依据。

def myFunc(rknn_lite, IMG):IMG2 = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)# 等比例缩放IMG2, ratio, padding = letterbox(IMG2)# 强制放缩# IMG2 = cv2.resize(IMG, (IMG_SIZE, IMG_SIZE))IMG2 = np.expand_dims(IMG2, 0)outputs = rknn_lite.inference(inputs=[IMG2],data_format=['nhwc'])#print("oups1",len(outputs))#print("oups2",outputs[0].shape)boxes, classes, scores = yolov8_post_process(outputs)global car_numglobal truck_numglobal motorbike_numglobal bus_numcar_num = 0truck_num = 0motorbike_num = 0bus_num = 0if classes is not None:for box, score, cl in zip(boxes, scores, classes):if CLASSES[cl] == 'car':car_num = car_num + 1elif CLASSES[cl] == 'motorbike':motorbike_num = motorbike_num + 1elif CLASSES[cl] == 'bus':bus_num = bus_num + 1elif CLASSES[cl] == 'truck':truck_num = truck_num + 1if boxes is not None:draw(IMG, boxes, scores, classes, ratio, padding)return IMG

 我的程序已经可以在开发板上实时运行,并显示车辆检测结果。

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

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

相关文章

福建聚鼎:现在装饰画好做吗

在当今社会,随着人们审美情趣的提升和生活品质的改善,家居装饰画已经成为了一种流行的墙面装饰方式。许多人都在思考,现在做装饰画是否是一个好时机? “逆水行舟,不进则退。”在日新月异的市场中,装饰画行业的竞争愈发…

商用密码测评之对HTTPS(TLS)协议中各个参数解释

1、TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 是一个广泛使用的TLS(传输层安全协议)加密套件,它结合了多种技术和算法来确保网络通信的安全。下面是对该加密套件中各个参数的详细解释: 1. TLS 定义:TLS(传…

JMeter 使用

1.JMeter 是什么? JMeter 是一款广泛使用的开源性能测试工具,由 Apache 软件基金会维护。它主要用于测试 Web 应用程序的负载能力和性能,但也支持其他类型的测试,如数据库、FTP、JMS、LDAP、SOAP web services 等。 2.特点&#x…

Infuse Pro for Mac全能视频播放器

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件,将其从左侧拖入右侧文件夹中,等待安装完毕2、应用程序显示软件图标,表示安装成功 三、运行测试安装完成!!! 效果 一、下载软件 下载软件…

Qt系统机制

Qt系统 Qt文件概述输入输出设备类QFileQFileInfoQt多线程Qt多线程常用API使用Qt多线程 线程安全互斥锁读写锁条件变量信号量 Qt网络QUdpSocketQNetworkDatagram设计一个UDP回显服务器QTcpServerQTcpSocketTcp版本的回显服务器HttpClient核心API Qt 音频Qt视频 Qt文件概述 ⽂件操…

【C++BFS】1020. 飞地的数量

本文涉及知识点 CBFS算法 LeetCode1020. 飞地的数量 给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。 一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 gr…

【C++初阶】string类

【C初阶】string类 🥕个人主页:开敲🍉 🔥所属专栏:C🥭 🌼文章目录🌼 1. 为什么学习string类? 1.1 C语言中的字符串 1.2 实际中 2. 标准库中的string类 2.1 string类 2.…

前缀表达式(波兰式)和后缀表达式(逆波兰式)的计算方式

缀是指操作符。 1. 前缀表达式(波兰式) (1)不需用括号; (2)不用考虑运算符的优先级; (3)操作符置于操作数的前面。(如 3 2 ) 1.1 中…

《Programming from the Ground Up》阅读笔记:p75-p87

《Programming from the Ground Up》学习第4天,p75-p87总结,总计13页。 一、技术总结 1.persistent data p75, Data which is stored in files is called persistent data, because it persists in files that remain on disk even when the program …

hash表如何形成,hash函数如何计算,什么是hash冲突 如何解决 ,Golang map的底层原理及扩容机制

散列表 散列表(hash表):根据给定的关键字来计算出关键字在表中的地址的数据结构。也就是说,散列表建立了关键字和 存储地址之间的一种直接映射关系。 问题:如何建立映射管血 散列函数:一个把查找表中的关键字映射成该关键字对应…

oracle语法介绍

Oracle数据库是关系型数据库管理系统之一,其SQL语法遵循标准的SQL规范,但也有一些自己的扩展。以下是一些Oracle SQL语法的基本示例: 1.选择数据: SELECT * FROM my_table; 1.插入数据: INSERT INTO my_table (colum…

RocketMQ事务消息机制原理

RocketMQ工作流程 在RocketMQ当中,当消息的生产者将消息生产完成之后,并不会直接将生产好的消息直接投递给消费者,而是先将消息投递个中间的服务,通过这个服务来协调RocketMQ中生产者与消费者之间的消费速度。 那么生产者是如何…

【设计模式】工厂模式详解

1.简介 工厂模式是一种创建型设计模式,通过提供一个接口或抽象类来创建对象,而不是直接实例化对象。工厂模式的主要思想是将对象的创建与使用分离,使得创建对象的过程更加灵活和可扩展。 工厂模式主要包括以下角色: 抽象工厂&a…

地铁深基坑结构施工预警实时监测系统测点布设

01 基坑监测背景 随着我国城市建设的发展,基坑规模和开挖深度不断增加。在基坑开挖过程中,如何尽快的在第一时间了解基坑的变形情况,并动态评估基坑的结构安全,避免事故的发生。与其它监测方法相比,实现自动化监测、信…

gradio 之页面布局

输出组件的可交互,默认垂直排列 import gradio as gr def greet(name):return "Hello " name "!" with gr.Blocks() as demo:name gr.Textbox(label"Name")# 不可交互# output gr.Textbox(label"Output Box")# 可交互…

超声波清洗机哪个品牌比较好耐用?好用的超声波清洗机推荐

随着科技的发展,超声波清洗机已经慢慢出现在我们日常生活中了。像日常使用的小物品,如手表和首饰等,时间久了,难免会积累灰尘,滋生细菌。那么应该如何进行彻底清洁呢?超声波清洗机可以给我们答案&#xff0…

Move生态:从Aptos和Sui到Starcoin的崛起

区块链技术自诞生以来,已经经历了多个发展阶段和技术迭代。近年来,随着智能合约平台的不断演进,以Move语言为核心的生态系统逐渐崭露头角。Move语言以其安全性、灵活性和高效性吸引了大量开发者和项目方的关注。在Move生态中,Apto…

uniapp实现局域网(内网)中APP自动检测版本,弹窗提醒升级

uniapp实现局域网(内网)中APP自动检测版本,弹窗提醒升级 在开发MES系统的过程中,涉及到了平板端APP的开发,既然是移动端的应用,那么肯定需要APP版本的自动更新功能。 查阅相关资料后,在uniapp的…

【数据结构】——双链表的实现(赋源码)

双链表的概念和结构 双链表的全称叫做:带头双向循环链表 它的结构示意图如下 注意:这⾥的“带头”跟前⾯我们说的单链表的“头结点”是两个概念,实际前⾯的在单链表阶段称呼不严谨,但是为了读者们更好的理解就直接称为单链表的头…

Transformer——逐步详解架构和完整代码搭建

好久没更新博客,后面更新会勤一些。今天想聊一下Transformer,Transformer在NLP和CV领域都有着重要的价值,甚至可以看作是一个基础模型,这篇博客将通过详细代码深入解析Transformer模型总体架构图各个部分的的作用和搭建:论文链接&…