【v5lite】调用onnx推理

  • 前言
  • 一、主线程
  • 二、推理线程
    • thred_nms(非极大值抑制阈值)的作用
    • thred_cond(置信度阈值)的作用
  • 三、串口线程
  • 总览
  • @改善版本
  • 总结


前言

跟着博主导入的加以修改的,反正v5lite的版本要是1.4版本的,不然容易出现错误!
后面再去把博主的博文导进来
树莓派4B运行yolov5lite转onnx模型(实测3-7fps)这个比较浅显易懂,跟着博主搞几乎不会出现错误。

还有的参考,因为个人水平有限,我本人没看懂,但是我认为极具参考价值,一致贴上来!
1、pogg源大佬的知乎文章工程部署(五):这周不鸽!v5Lite树莓派15帧教程
但是我没看懂这里QWQ转换出onnx模型之后,我不知道如何检测模型的好坏
2、基于树莓派4B的YOLOv5-Lite目标检测的移植与部署(含训练教程)


一、主线程

def main():# 模型加载model_pb_path = "D:\\YOLOv5-Lite-1.4\\runs\\train\\exp1\\weights\\best.onnx"so = ort.SessionOptions()net = ort.InferenceSession(model_pb_path, so)"""这里首先指定了模型文件的路径(model_pb_path),然后创建了一个ONNX运行时的会话选项(so),最后使用模型路径和会话选项来初始化一个推理会话(net),用于后续对模型进行推理操作。"""# 标签字典global dic_labelsdic_labels = {0: 'good_apple',1: 'bad_apple',2: 'good_banana',3: 'bad_banana',4: 'good_mango',5: 'bad_mango'}"""定义了一个全局的字典(dic_labels),用于将模型输出的类别索引映射到对应的水果标签,方便后续在检测结果中显示有意义的水果名称。"""# 模型参数model_h = 320model_w = 320nl = 3na = 3stride = [8., 16., 32.]anchors = [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]]anchor_grid = np.asarray(anchors, dtype=np.float32).reshape(nl, -1, 2)"""这里定义了一系列模型相关的参数:- model_h和model_w指定了模型输入图像的高度和宽度。- nl表示模型的检测层数。- na表示每层的锚框数量。- stride是不同检测层的步长信息。- anchors是定义的锚框尺寸列表,经过处理后转换为numpy数组并重塑为合适的形状存储在anchor_grid中,这些参数在目标检测模型中用于确定检测框的位置和大小等。"""# 初始化队列和线程img_queue = queue.Queue()result_queue = queue.Queue()result_copy_queue = queue.Queue()detection_thread = DetectionThread(img_queue, result_queue, net, model_h, model_w, nl, na, stride, anchor_grid, dic_labels)detection_thread.start()"""创建了三个队列:- img_queue用于存储待检测的图像数据。- result_queue用于存储检测线程得到的检测结果。- result_copy_queue用于在另一个线程(串口线程)中传递检测结果副本。然后创建了一个检测线程(detection_thread),并传入相关参数后启动该线程,该线程将从img_queue中获取图像进行检测,并将结果放入result_queue。"""# 串口线程配置serial_port = 'COM12'baud_rate = 115200serial_thread = SerialThread(serial_port, baud_rate, result_copy_queue)serial_thread.start()"""配置了串口相关的参数,包括串口号(serial_port)和波特率(baud_rate),然后创建了一个串口线程(serial_thread),并传入相关参数后启动该线程,该线程将从result_copy_queue中获取检测结果副本进行后续处理(可能是通过串口发送数据等操作)。"""video = 0cap = cv2.VideoCapture(video)flag_det = False"""设置视频源为默认摄像头(video = 0),然后使用cv2.VideoCapture创建一个视频捕获对象(cap),用于读取视频帧。同时初始化了一个标志变量flag_det为False,用于控制是否启动检测功能。"""prev_time = time.time()  # 上一帧的时间戳frame_count = 0          # 总帧数try:while True:success, img0 = cap.read()if not success:breakcurr_time = time.time()# 将图像放入队列(即使检测未启动)img_queue.put(img0)"""在循环中,不断从视频捕获对象中读取视频帧(img0),如果读取成功,将当前帧放入img_queue队列中,无论检测功能是否启动,都先将图像放入队列等待后续处理。"""# 如果检测启动,从结果队列中获取结果并绘制if flag_det:if not result_queue.empty():det_boxes, scores, ids = result_queue.get()for box, score, id in zip(det_boxes, scores, ids):label = '%s:%.2f' % (dic_labels[id], score)plot_one_box(box.astype(np.int16), img0, color=(255, 0, 0), label=label, line_thickness=None)result_copy_queue.put( (det_boxes, scores, ids))        # 复制线程"""如果检测标志flag_det为True,表示检测功能已启动,当result_queue队列中有检测结果时,从队列中取出检测框信息(det_boxes)、得分(scores)和类别索引(ids),然后遍历这些结果,根据类别索引从dic_labels字典中获取对应的水果标签,并在图像上绘制检测框和标注信息,最后将检测结果副本放入result_copy_queue队列,以便串口线程获取。"""frame_count += 1if frame_count > 1:  # 避免除以零错误fps = 1. / (curr_time - prev_time)str_FPS = "FPS: %.2f" % fpselse:str_FPS = "FPS: N/A"  # 第一帧时显示N/Aprev_time = curr_timecv2.putText(img0, str_FPS, (50, 50), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 3)"""每处理一帧图像,帧数(frame_count)加1,根据当前帧和上一帧的时间戳计算帧率(fps),并将帧率信息以文本形式绘制在图像上,方便实时查看处理速度。"""cv2.imshow("FruitSeeSee", img0)key = cv2.waitKey(1) & 0xFFif key == ord('q'):breakelif key == ord('s'):flag_det = not flag_detif flag_det:print("Detection started.")else:print("Detection stopped.")# 清空队列以防有残留数据while not result_queue.empty():result_queue.get()while not img_queue.empty():img_queue.get()"""显示处理后的图像(img0),并等待用户按键操作:- 如果按下'q'键,退出循环,结束程序。- 如果按下's'键,切换检测功能的启动和停止状态,当启动检测时打印相应提示信息,当停止检测时,除了打印提示信息,还会清空result_queue和img_queue队列中的残留数据。"""finally:detection_thread.stop()detection_thread.join()serial_thread.stop()serial_thread.join()cap.release()cv2.destroyAllWindows()"""在程序结束时(无论是否正常结束),执行以下清理操作:- 停止并等待检测线程(detection_thread)结束。- 停止并等待串口线程(serial_thread)结束。- 释放视频捕获对象(cap)占用的资源。- 关闭所有打开的cv2窗口。"""

二、推理线程

识别线程

"""################# 识别线程 ###########################"""
class DetectionThread(threading.Thread):def __init__(self, img_queue, result_queue, net, model_h, model_w, nl, na, stride, anchor_grid, dic_labels):"""识别线程类的构造函数,用于初始化线程相关的属性。:param img_queue: 存储待检测图像的队列:param result_queue: 用于存储检测结果的队列:param net: ONNX模型推理会话对象,用于对图像进行推理:param model_h: 模型输入图像的高度:param model_w: 模型输入图像的宽度:param nl: 模型的检测层数:param na: 每层的锚框数量:param stride: 不同检测层的步长信息:param anchor_grid: 处理后的锚框尺寸数组,用于辅助检测:param dic_labels: 类别标签字典,将类别索引映射到具体的标签名称"""threading.Thread.__init__(self)self.img_queue = img_queueself.result_queue = result_queueself.net = netself.model_h = model_hself.model_w = model_wself.nl = nlself.na = naself.stride = strideself.anchor_grid = anchor_gridself.dic_labels = dic_labelsself.running = Falsedef run(self):"""线程启动后执行的方法,在此方法中实现了图像的检测和结果推送逻辑。只要线程处于运行状态(self.running为True),就会不断从图像队列中获取图像进行检测,并将检测结果放入结果队列。"""self.running = Truewhile self.rrunning:if not self.img_queue.empty():img0 = self.img_queue.get()det_boxes, scores, ids = infer_img(img0, self.net, self.model_h, self.model_w, self.nl, self.na, self.stride, self.anchor_grid)self.result_queue.put((det_boxes, scores, ids))time.sleep(0.01)  # 防止线程过于繁忙def stop(self):"""用于停止线程运行的方法,通过将self.running设置为False,使得线程在下次循环检查时退出循环,从而停止线程的执行。"""self.running = False

重头戏
plot_one_box函数:
功能:在给定图像上绘制一个检测框及对应的标签。
实现:首先根据图像大小动态计算绘制检测框的线条粗细(tl),如果未指定颜色则随机生成一个颜色。然后根据传入的检测框坐标信息绘制矩形检测框。若有标签信息,还会计算合适的字体大小并在检测框上方绘制填充矩形作为背景,再将标签文本绘制在上面。
_make_grid函数:
功能:创建一个二维网格坐标数组,用于后续对模型输出坐标的矫正等操作。
实现:通过np.meshgrid函数分别生成在 x 轴和 y 轴方向的坐标数组,然后将它们堆叠并重塑为形状为(-1, 2)的二维数组,每个元素表示一个网格点的坐标(x, y)。
cal_outputs函数:
功能:对模型输出的坐标等信息进行矫正处理,使其符合实际图像的尺寸和坐标体系。
实现:通过遍历模型的检测层数,根据每层的步长、锚框数量等信息,结合之前创建的网格坐标数组,对模型输出的坐标数据进行一系列的计算和调整,最终返回矫正后的模型输出数据。
post_process_opencv函数:
功能:对模型输出进行后处理,包括计算检测框的实际坐标、进行非极大值抑制(NMS)等操作。
实现:首先从模型输出数据中提取出置信度、中心点坐标、宽度和高度等信息,并根据模型输入和原始输入图像的尺寸关系计算出检测框的实际坐标。然后通过cv2.dnn.NMSBoxes函数进行非极大值抑制操作,根据设定的置信度阈值和非极大值抑制阈值筛选出有效的检测框,最后返回经过处理后的检测框坐标、置信度和类别索引信息。
infer_img函数:
功能:对输入图像进行推理计算,包括图像预处理、模型推理、输出坐标矫正、检测框计算等一系列操作,最终得到检测结果。
实现:
图像预处理:将原始输入图像调整到模型输入的尺寸,转换颜色通道为 RGB,并进行归一化处理,最后将其转换为适合模型输入的张量格式(blob)。
模型推理:使用模型推理会话对象net对预处理后的图像张量进行推理,得到模型的原始输出数据。
输出坐标矫正:调用cal_outputs函数对模型原始输出数据进行坐标矫正。
检测框计算:调用post_process_opencv函数对矫正后的输出数据进行检测框计算,得到最终的检测框坐标、置信度和类别索引信息,并返回这些结果。

def plot_one_box(x, img, color=None, label=None, line_thickness=None) :tl = (line_thickness or round( 0.002 * (img.shape[0] + img.shape[1]) / 2 ) + 1)  # line/font thicknesscolor = color or [random.randint(0, 255 ) for _ in range( 3 )]c1, c2 = (int( x[0] ), int( x[1] )), (int( x[2] ), int( x[3] ))cv2.rectangle( img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA )if label :tf = max( tl - 1, 1 )  # font thicknesst_size = cv2.getTextSize( label, 0, fontScale=tl / 3, thickness=tf)[0]c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3cv2.rectangle( img, c1, c2, color, -1, cv2.LINE_AA)  # filledcv2.putText(img,label,(c1[0], c1[1] - 2),0

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

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

相关文章

使用itextpdf进行pdf模版填充中文文本时部分字不显示问题

在网上找了很多种办法 都解决不了; 最后发现是文本域字体设置出了问题; 在这不展示其他的代码 只展示重要代码; 1 引入扩展包 <dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</v…

web——sqliabs靶场——第十三关——报错注入+布尔盲注

发现是单引号加括号闭合的 尝试联合注入 发现不太行&#xff0c;那尝试报错注入。 测试报错注入 unameadmin) and updatexml(1,0x7e,3) -- &passwdadmin&submitSubmit 爆数据库 unameadmin) and updatexml(1,concat(0x7e,database(),0x7e),3) -- &passwdadmin&a…

QT如何共享文件+拷贝文件

QString sharedFolderPathImg "\\\\" IP "/profileImage/"; // 更换为你的共享文件夹路径QDir dirImg(sharedFolderPathImg);dirImg.setFilter(QDir::NoDotAndDotDot | QDir::AllEntries);QVector<QString> curFileEntryArrayImg dirImg.entryList…

跟《经济学人》学英文:2024年11月23日这期 Why British MPs should vote for assisted dying

Why British MPs should vote for assisted dying A long-awaited liberal reform is in jeopardy in jeopardy&#xff1a;在危险中 jeopardy&#xff1a;美 [ˈdʒepərdi] 危险&#xff1b;危机&#xff1b;风险&#xff1b; 原文&#xff1a; THIS NEWSPAPER believes …

【es6进阶】vue3中的数据劫持的最新实现方案的proxy的详解

vuejs中实现数据的劫持,v2中使用的是Object.defineProperty()来实现的&#xff0c;在大版本v3中彻底重写了这部分&#xff0c;使用了proxy这个数据代理的方式&#xff0c;来修复了v2中对数组和对象的劫持的遗留问题。 proxy是什么 Proxy 用于修改某些操作的默认行为&#xff0…

D73【 python 接口自动化学习】- python 基础之正则表达式

day73 正则表达式-元字符匹配 学习日期&#xff1a;20241119 学习目标&#xff1a;正则表达式--133 正则表达式-元字符匹配 学习笔记&#xff1a; 元字符匹配 数量匹配 实践操作 总结 字符串的r标记表示&#xff0c;字符串内转移字符无效&#xff0c;作为普通字符使用正则…

Python浪漫之画明亮的月亮

目录 1、效果展示 2、完整版代码 1、效果展示 2、完整版代码 import turtledef draw_moon():# 设置画布turtle.bgcolor("black") # 背景颜色为黑色turtle.speed(10) # 设置绘制速度# 绘制月亮的外圈turtle.penup()turtle.goto(0, -100) # 移动到起始…

微信小程序包之加农炮游戏

微信小程序 - 气球射击游戏 项目简介 这是一个简单有趣的微信小程序射击游戏。玩家通过控制屏幕底部的加农炮&#xff0c;射击从上方降落的蓝色气球。游戏考验玩家的反应能力和瞄准技巧。 游戏规则 点击屏幕任意位置发射炮弹大炮会自动对准点击位置击中气球获得10分如果气球触…

autogen+ollama+litellm实现本地部署多代理智能体

autogen 是一个专门为大语言模型 (LLMs) 驱动的自治代理 (autonomous agents) 设计的 Python 库,由 Microsoft 开发和维护。它通过高度模块化和可扩展的架构,支持用户快速构建和运行多代理系统,这些代理可以在没有明确人类干预的情况下协作完成复杂任务。AutoGen 支持以最少…

分公司如何纳税

分公司不进行纳税由总公司汇总纳税“子公司具有法人资格&#xff0c;依法独立承担民事责任;分公司不具有法人资格&#xff0c;其民事责任由公司承担。”企业设立分支机构&#xff0c;使其不具有法人资格&#xff0c;且不实行独立核算&#xff0c;则可由总公司汇总缴纳企业所得税…

HashMap源码详解

提醒你一下&#xff0c;用电脑或者平板看&#xff0c;手机屏幕小&#xff0c;图片会看不清楚&#xff0c;源码不方便看 基础前置 看该篇文章之前先看看这篇基础文章 HashMap底层原理-CSDN博客 先来看HashMap里面的一些参数。 1.DEFAULT_INITIAL_CAPACITY 默认的数组初…

09 —— Webpack搭建开发环境

搭建开发环境 —— 使用webpack-dev-server 启动Web服务&#xff0c;自动检测代码变化&#xff0c;有变化后会自动重新打包&#xff0c;热更新到网页&#xff08;代码变化后&#xff0c;直接替换变化的代码&#xff0c;自动更新网页&#xff0c;不用手动刷新网页&#xff09; …

动态反馈控制器(DFC)和 服务率控制器(SRC);服务率和到达率简单理解

目录 服务率和到达率简单理解 服务率 到达率 排队论中的应用 论文解析:队列等待成本动态感知控制模型 动态反馈和队列等待成本意识: 服务速率调整算法: 动态反馈控制器(DFC)和 服务率控制器(SRC) SRC公式4的原理 算力资源分配系统中的调整消耗 举例说明 服务…

九、FOC原理详解

1、FOC简介 FOC&#xff08;field-oriented control&#xff09;为磁场定向控制&#xff0c;又称为矢量控制&#xff08;vectorcontrol&#xff09;&#xff0c;是目前无刷直流电机&#xff08;BLDC&#xff09;和永磁同步电机&#xff08;PMSM&#xff09;高效控制的最佳选择…

web-03

CSS回顾 选择器 标签选择器 标签{}ID选择器 标签中定义ID属性。 #ID值{}类选择器 标签中使用class属性 .类名{}关于DIV/span div任意的大小的长方形&#xff0c;大小css&#xff1a; width, height控制。—换行 span-- 一行内 CSS常用属性 width/height 宽度/高度 定义&…

Excel求和如何过滤错误值

一、问题的提出 平时&#xff0c;我们在使用Excel时&#xff0c;最常用的功能就是求和了&#xff0c;一说到求和你可能想到用sum函数&#xff0c;但是如果sum的求和区域有#value #Div等错误值怎么办&#xff1f;如下图&#xff0c;记算C列中工资的总和。 直接用肯定会报错&…

蓝桥杯每日真题 - 第22天

题目&#xff1a;&#xff08;卡片&#xff09; 题目描述&#xff08;12届 C&C B组B题&#xff09; 解题思路&#xff1a; 该问题要求用数字卡片从 1 开始拼出整数&#xff0c;直到某一时刻不能拼出时停止。要确定拼到哪个最大整数&#xff0c;需要统计 每个数字“1”被用…

Ubuntu20.04 Rk3588 交叉编译ffmpeg7.0

firefly 公司出的rk3588的设备&#xff0c;其中已经安装了gcc 交叉编译工具&#xff0c;系统版本是Ubuntu20.04。 使用Ubuntu20.04 交叉编译ffmpeg_ubuntu下配置ffmpeg交叉编译器为arm-linux-gnueabihf-gcc-CSDN博客文章浏览阅读541次。ubuntu20.04 交叉编译ffmpeg_ubuntu下配…

python代码制作数据集的测试和数据质量检测思路

前言 本文指的数据集为通用数据集&#xff0c;并不单是给机器学习领域使用。包含科研和工业领域需要自己制作数据集的。 首先&#xff0c;在制作大型数据集时&#xff0c;代码错误和数据问题可能会非常复杂。 前期逻辑总是简单的&#xff0c;库库一顿写&#xff0c;等排查的时…

Windows系统编程 - 进程遍历

文章目录 前言进程的遍历CreateToolhelp32SnapshotProcess32FirstProcess32Next进程遍历 总结 前言 各位师傅好&#xff0c;我是qmx_07&#xff0c;今天给大家讲解进程遍历的相关知识点 进程的遍历 快照&#xff1a;使用vmware虚拟机的时候&#xff0c;经常需要配置环境服务…