YOLOv5+pyqt5+摄像头在特定条件下进行目标检测并采集原始数据
项目介绍
项目地址
GitHub - biabu0/Yolov5_D435i: 通过YOLOV5与pyqt5实现一个使用D435i深度摄像头采集特定需求与场景下的深度数据的小程序
通过YOLOV5对指定的区域进行检测,当检测到目标进入特定区域时,开始保存数据,摄像头采用D435i深度相机,用于采集深度数据集。
- 指定需要屏蔽的检测区域,即使目标进入该区域也无法进行有效的检测,应用于特定场景的检测。
- 只有目标在检测区域内,才进行数据的采集与保存,避免一直采集数据,目标离开检测区域则停止保存数据,避免在数据采集过程中存在大量的无效数据,节约数据清洗时间,节省磁盘容量。
- 按照时间存储数据。
- 使用pyqt5设计可视化界面,将UI界面与逻辑代码分离。
项目演示视频
演示视频
环境配置
按照requements.txt文件配置yolov5环境,安装pyqt5和pyrealsense2。
核心代码解析
detect_logical.py:负责加载模型,并初始化模型参数;选择遮蔽区域以及需要保存的数据文件地址;加载D435深度相机数据流,将数据送入检测,检测到特定目标返回数据保存的标志位进行数据存储。
main_logic.py:主界面,可以进行注册账号与登录账号。
ui/ori_ui:ui源文件,可以通过使用QTdesigner对UI界面进行修改,修改后使用**pyuic5 main.ui > ui_main.py**,(注意最好使用绝对路径,不然可能出现问题)转换成py文件。
utlis/id_utlis.py与userInfo.csv:用于写入账户信息。
遮蔽区域选择
通过鼠标左键获取需要屏蔽的区域的四个角的位置,保存到一个全局变量中,用于后序检测的时候生成指定区域的掩码,从而屏蔽特定区域。
def mouse_callback(self, event, x, y, flags, param):if event == cv2.EVENT_LBUTTONDOWN:# 将位置标准化(可选,根据需求决定是否需要)normalized_x = x / self.frame_shape[1]normalized_y = y / self.frame_shape[0]# 将位置添加到二维数组中self.mouse_positions.append([normalized_x, normalized_y])return ;def select_mask(self):self.mouse_positions = []self.pipeline.start(self.config)frames = self.pipeline.wait_for_frames()img_color = frames.get_color_frame()# 检查摄像头是否成功打开if img_color is None:print("Error: Could not open video device.")exit()img_color = np.asanyarray(img_color.get_data())self.frame_shape = img_color.shape[:2]# 创建一个窗口cv2.namedWindow('Camera Image')# 设置鼠标回调函数cv2.setMouseCallback('Camera Image', self.mouse_callback)while True:# 显示图像cv2.imshow('Camera Image', img_color)#等待按键,如果按下'q'键,退出循环if cv2.waitKey(0) & 0xFF == ord('q'):break# 释放D435i对象self.pipeline.stop() # 停止RealSense管道# 销毁创建的窗口print("mouse_positions", self.mouse_positions)QtWidgets.QMessageBox.information(self, u"Notice", u"遮掩区域选择成功", buttons=QtWidgets.QMessageBox.Ok,defaultButton=QtWidgets.QMessageBox.Ok)
选择数据保存地址
直接将寻找的路径保存到全局变量中,后序需要保存地址的时候加载进去。
def open_file(self):self.openfile_name_dataset = QFileDialog.getExistingDirectory(self, '选择数据集目录')if not self.openfile_name_dataset:QtWidgets.QMessageBox.warning(self, u"Warning", u"打开文件地址失败", buttons=QtWidgets.QMessageBox.Ok,defaultButton=QtWidgets.QMessageBox.Ok)else:QtWidgets.QMessageBox.information(self, u"Notice", u"数据集路径为:" + str(self.openfile_name_dataset), buttons=QtWidgets.QMessageBox.Ok,defaultButton=QtWidgets.QMessageBox.Ok)
采集数据
当检测到目标存在时,需要进行数据保存,调用该函数。从D435i中获取帧作为参数。将深度帧与彩色帧对齐,获取深度图与彩色图。按照时间格式创建数据保存的文件夹,可以选择保存四种数据格:color:彩色图;depth:原始深度图npy格式;depthjpg与可视化后的彩色图。
def save_dataset(self, frames):align_to = rs.stream.coloralign = rs.align(align_to) # 对齐aligned_frames = align.process(frames)aligned_depth_frame = aligned_frames.get_depth_frame()color_frame = aligned_frames.get_color_frame()depth_image = np.asanyarray(aligned_depth_frame.get_data())depth_data = np.asanyarray(aligned_depth_frame.get_data(), dtype="uint16")color_image = np.asanyarray(color_frame.get_data())t1 = time.strftime("%Y_%m_%d_%H_%M", time.localtime())if not self.openfile_name_dataset:QtWidgets.QMessageBox.warning(self, u"Warning", u"请先选择数据集地址", buttons=QtWidgets.QMessageBox.Ok,defaultButton=QtWidgets.QMessageBox.Ok)returnsave_path = os.path.join(self.openfile_name_dataset, "outfile", t1)os.makedirs(save_path, exist_ok=True)os.makedirs(os.path.join(save_path, "color"), exist_ok=True)os.makedirs(os.path.join(save_path, "depth"), exist_ok=True)os.makedirs(os.path.join(save_path, "depthjpg"), exist_ok=True)os.makedirs(os.path.join(save_path, "depth_mapped_image"), exist_ok=True)saved_count = int(time.time() * 1000) #毫秒级的时间戳depth_mapped_image = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET)# 彩色图片保存为png格式cv2.imwrite(save_path + "/color/" + "{}".format(saved_count) + '.jpg', color_image)# -----------深度图保存信息----------------## 深度信息由采集到的float16直接保存为npy格式np.save(os.path.join(save_path, "depth", "{}".format(saved_count)), depth_data) ## 黑白图# 使用jpg格式保存的图片,图像采集错误还能肉眼发现cv2.imwrite(save_path + "/depthjpg/" + "{}.jpg".format(saved_count), depth_image)# 渲染的图片cv2.imwrite(save_path + "/depth_mapped_image/"+"{}.jpg".format(saved_count), depth_mapped_image)return True
目标检测信息
根据选择掩码阶段选择的四个坐标位置生成mask应用到图像上,达到遮蔽区域检测的目的。实现mask后查看掩码具体位置,然后进入检测逻辑,返回检测信息以及数据保存位。
def detect(self, name_list, img):#(1, 3, 480, 640) [[[145 146 143], [148 149 146# ]]]showimg = imghl1 = self.mouse_positions[0][1] # 监测区域高度距离图片顶部比例wl1 = self.mouse_positions[0][0] # 监测区域高度距离图片左部比例hl2 = self.mouse_positions[1][1] # 监测区域高度距离图片顶部比例wl2 = self.mouse_positions[1][0] # 监测区域高度距离图片左部比例hl3 = self.mouse_positions[3][1] # 监测区域高度距离图片顶部比例wl3 = self.mouse_positions[3][0] # 监测区域高度距离图片左部比例hl4 = self.mouse_positions[2][1] # 监测区域高度距离图片顶部比例wl4 = self.mouse_positions[2][0] # 监测区域高度距离图片左部比例mask = np.zeros([img.shape[0], img.shape[1]], dtype=np.uint8)pts = np.array([[int(img.shape[1] * wl1), int(img.shape[0] * hl1)], # pts1[int(img.shape[1] * wl2), int(img.shape[0] * hl2)], # pts2[int(img.shape[1] * wl3), int(img.shape[0] * hl3)], # pts3[int(img.shape[1] * wl4), int(img.shape[0] * hl4)]], np.int32)cv2.fillPoly(mask, [pts], (255, 255, 255))mask = 255 - mask# 应用mask:将mask为0的部分设置为黑色(0,0,0)img = cv2.add(img, np.zeros(np.shape(img), dtype=np.uint8), mask=mask)# 2========================================================================================if not self.border:# 只显示一次# 定义框的颜色和线宽border_color = (255, 0, 0) # 红色border_thickness = 2cv2.polylines(img, [pts], True, border_color, border_thickness)self.border = True# 显示结果cv2.imshow('Image with Mask and Border', img)cv2.waitKey(0)cv2.destroyAllWindows()# 2========================================================================================with torch.no_grad():img = letterbox(img, new_shape=self.opt.img_size)[0]# Convertimg = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, to 3x416x416img = np.ascontiguousarray(img)img = torch.from_numpy(img).to(self.device)img = img.half() if self.half else img.float() # uint8 to fp16/32img /= 255.0 # 0 - 255 to 0.0 - 1.0if img.ndimension() == 3:img = img.unsqueeze(0)# Inference# 1==============================================================================================================# 1========================================================================================pred = self.model(img, augment=self.opt.augment)[0]# Apply NMSpred = non_max_suppression(pred, self.opt.conf_thres, self.opt.iou_thres, classes=self.opt.classes,agnostic=self.opt.agnostic_nms)info_show = ""info_show_target = ""# Process detectionsself.info_show_int = 1for i, det in enumerate(pred):if det is not None and len(det):# 3=====================================================================================condition = (det[:, 5] == 0.0) & (det[:, 4] > 0.6)if condition.any():#print("有人员进入监测区域")info_show_target = "有人员进入检测区域"self.info_show_int = 0else:info_show_target = "无人员进入检测区域"self.info_show_int = 1# 3================================================================================================================================================================# Rescale boxes from img_size to im0 sizedet[:, :4] = scale_coords(img.shape[2:], det[:, :4], showimg.shape).round()for *xyxy, conf, cls in reversed(det):label = '%s %.2f' % (self.names[int(cls)], conf)name_list.append(self.names[int(cls)])single_info = plot_one_box2(xyxy, showimg, label=label, color=self.colors[int(cls)], line_thickness=2)# print(single_info)info_show = info_show + single_info + "\n"return info_show_target, self.info_show_int
视频帧操作逻辑
打开D435i,获取彩色图,要将彩色图copy一份再送入detect检测逻辑,不然会导致最后保存的数据还有检测的目标框。
def show_video_frame(self):frames = self.pipeline.wait_for_frames()color_frame = frames.get_color_frame()#在此处就获取帧,后面获取帧会导致获取color含有检测框# depth_frame = frames.get_depth_frame()if not color_frame:self.finish_detect()returncolor_image = np.asanyarray(color_frame.get_data())color_image_detect = color_image.copy()info_show, info_show_int = self.detect([], color_image_detect) # 检测结果写入到原始img上#print(info_show)if info_show_int == 0:#print("---开始处理保存数据程序---")flag = self.save_dataset(frames)if flag:#print("数据保存成功")info_show += " 数据保存成功"elif info_show_int == 1:#print("---停止保存数据程序---")info_show += " 停止保存数据"# 显示检测信息和图像self.ui.textBrowser.setText(info_show)show = cv2.resize(color_image_detect, (640, 480))self.result = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)showImage = QtGui.QImage(self.result.data, self.result.shape[1], self.result.shape[0],QtGui.QImage.Format_RGB888)self.ui.label.setPixmap(QtGui.QPixmap.fromImage(showImage))self.ui.label.setScaledContents(True)
参考
项目UI主要参考使用PyQt5为YoloV5添加界面(一)_pyqt pyvista-CSDN博客
YOLOv5区域入侵检测【附完整代码以及视频演示】_yolov5入侵检测-CSDN博客
pyqt5学习:Python Qt 简介 - 白月黑羽
相关文章:
YOLOv5+pyqt5+摄像头在特定条件下进行目标检测并采集原始数据
项目介绍 项目地址 GitHub - biabu0/Yolov5_D435i: 通过YOLOV5与pyqt5实现一个使用D435i深度摄像头采集特定需求与场景下的深度数据的小程序 通过YOLOV5对指定的区域进行检测,当检测到目标进入特定区域时,开始保存数据,摄像头采用D435i深度…...
12.6深度学习_模型优化和迁移_整体流程梳理
七、整体流程梳理 1. 引入使用的包 用到什么包,临时引入就可以,不用太担心。 import time import osimport numpy as np import pandas as pd import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvisio…...
TCP 和 UDP 可以使用同一个端口吗
TCP 和 UDP 可以使用同一个端口吗 简单来说 可以使用同一个端口,关键在于它们属于不同的传输层协议,在内核中是两个完全独立的软件模块,各自维护独立的端口空间,虽然端口号相同,但通过协议类型可以确定是哪种协议。 …...
信而泰网络测试仪校准解决方案
一、影响仪表精度的因素 网络测试仪是用于对数据网络及其相关设备性能参数进行测试的仪表,可以模拟网络终端产生流量,进行网络性能测试,对网络状态进行实时监测,分析和统计。数字计量对于精准数据的网络测试仪来说是一剂强心针&a…...
Java 实现给pdf文件指定位置盖章功能
Java 实现给pdf文件指定位置盖章功能 开发中遇到一个需求, 需要给用户上传的的pdf文件, 指定位置上盖公章的功能, 经过调研和对比, 最终确定实现思路. 这里是使用pdf文件中的关键字进行章子的定位, 之所以这样考虑是因为如果直接写死坐标的话, 可能会出现因pdf大小, 缩放, 盖章…...
机器学习支持向量机(SVM)算法
一、引言 在当今数据驱动的时代,机器学习算法在各个领域发挥着至关重要的作用。支持向量机(Support Vector Machine,SVM)作为一种强大的监督学习算法,以其在分类和回归任务中的卓越性能而备受瞩目。SVM 具有良好的泛化…...
解决 MySQL 启动失败与大小写问题,重置数据库
技术文档:解决 MySQL 启动失败与大小写问题,重置数据库 1. 问题背景 在使用 MySQL 时,可能遇到以下问题: MySQL 启动失败,日志显示 “permission denied” 或 “Can’t create directory” 错误。MySQL 在修改配置文…...
计算生成报价单小程序系统开发方案
计算生成报价单小程序报价系统,是根据商品品牌、类型、型号、规格、芯数、特性、颜色、分类进行选择不同的参数进行生成报价单,要求报价单支持生成图片、pdf、excel表格。 计算生成报价单小程序系统的主要功能模块有: 1、在线生成报价单&…...
若依集成Uflo2工作流引擎
文章目录 1. 创建子模块并添加依赖1.1 新建子模块 ruoyi-uflo1.2 引入 Uflo2 相关依赖 2. 配置相关 config2.1 配置 ServletConfig2.2 配置 UfloConfig2.3 配置 TestEnvironmentProvider 3. 引入Uflo配置文件4. 启动并访问 Uflo2 是由 BSTEK 自主研发的一款基于 Java 的轻量级工…...
STM32模拟I2C通讯的驱动程序
目录 STM32模拟I2C通讯的驱动程序 开发环境 引脚连接 驱动程序 STM32模拟I2C通讯的驱动程序 开发环境 立创天空星开发板、主控芯片为STM32F407VxT6 引脚连接 使用stm32的PB9引脚模拟I2C时钟线SCL、PB8引脚模拟I2C数据线SDA 驱动程序 i2c.h文件如下:#ifndef…...
Unity简单操作及使用教程
Unity 是一款强大的跨平台游戏引擎,它不仅支持 2D 和 3D 游戏的开发,还可以用于虚拟现实 (VR)、增强现实 (AR)、动画、建筑可视化等多个领域。Unity 提供了完整的开发环境,具有丰富的功能、工具和资源,可以帮助开发者快速实现创意…...
网络安全法-监测预警与应急处置
第五章 监测预警与应急处置 第五十一条 国家建立网络安全监测预警和信息通报制度。国家网信部门应当统筹协调有关部门加强网络安全信息收集、分析和通报工作,按照规定统一发布网络安全监测预警信息。 第五十二条 负责关键信息基础设施安全保护工作的部门…...
qt 设置系统缩放为150%,导致的文字和界面的问题
1 当我们设置好布局后,在100%的设置里面都是正常的,但是当我们修改缩放为150%后,字体图标,界面大小就出现问题了,这就需要我们设置一些参数。 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QCoreAppl…...
Scala的正则表达式二
验证用户名是否合法 规则 1.长度在6-12之间 2.不能数字开头 3.只能包含数字,大小写字母,下划线def main(args: Array[String]): Unit {val name1 "1admin"//不合法,是数字开头val name2 "admin123"//合法val name3 &quo…...
软考系分:今日成绩已出
前言 今年报考了11月份的软考高级:系统分析师。 考试时间:11月9日。 总体感觉偏简单,但是知识点记得不牢,估计机会不大。 今日 12.11 ,成绩已出,每科总分 75分,全部45分以上为通过。 成绩总…...
DevExpress WPF中文教程:Grid - 如何移动和调整列大小?(一)
DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...
Docker 安装 sentinel
Docker 安装系列 1、拉取 [rootTseng ~]# docker pull bladex/sentinel-dashboard Using default tag: latest latest: Pulling from bladex/sentinel-dashboard 4abcf2066143: Pull complete 1ec1e81da383: Pull complete 56bccb36a894: Pull complete 7cc80011dc6f: Pull…...
PyCharm 2024.1 解锁版 (Python集成开发IDE)详细安装步骤
分享文件:PyCharm 2024.1 解锁版 (Python集成开发IDE) 链接:https://pan.xunlei.com/s/VOAa_CiVVvZnyQgLfpmCIOABA1 提取码:cx4h 安装步骤 1、下载解压后点击如下进行安装 2、选择安装路径 3、默认勾选将PyCharm创建桌面快捷方式 4、默认…...
SQL中的函数介绍
大多数SQL实现支持以下类型 文本函数:用于处理文本字符串(如删除或填充值,转换值为大写或小写)。数值函数:用于在数值数据上进行算术操作(如返回绝对值,进行代数运算)。日期和时间函…...
【工业机器视觉】基于深度学习的水表盘读数识别(2-数据采集与增强)
【工业机器视觉】基于深度学习的仪表盘识读(1)-CSDN博客 数据采集与增强 为了训练出适应多种表型和环境条件的模型,确保数据集的质量与多样性对于模型的成功至关重要。高质量的数据不仅需要准确无误、具有代表性,还需要涵盖尽可能…...
AI率从90%降到合格线,我踩了3个坑后找到的方法
我的论文AI率在知网检出了91%。 最后我把AI率降到了9%,但在这之前踩了3个坑,多花了将近两天时间。这篇文章不是炫成绩,是把这3个坑说清楚,让后来的人少走一段弯路。 坑一:花了一天手动改写,基本没用 拿到…...
S7-200 MCGS 基于PLC的小型水厂恒压供水系统 带解释的梯形图接线图原理图图纸,io分配
S7-200 MCGS 基于PLC的小型水厂恒压供水系统 带解释的梯形图接线图原理图图纸,io分配,组态画面最近在搞一个小型水厂的恒压供水系统项目,用西门子S7-200 PLC搭配MCGS组态软件,效果挺有意思的。这个系统核心就仨字——稳如狗&#…...
2026 年1月 17 日-KB5077744(OS 内部版本26200.7627 和 26100.7627)带外
🔥个人主页:杨利杰YJlio❄️个人专栏:《Sysinternals实战教程》《Windows PowerShell 实战》《WINDOWS教程》《IOS教程》《微信助手》《锤子助手》 《Python》 《Kali Linux》《那些年未解决的Windows疑难杂症》🌟 让复杂的事情更…...
基于两相交错并联技术的Buck-Boost变换器仿真研究:采用双向DCDC及多环控制策略实现高...
两相交错并联buck/boost变换器仿真 采用双向DCDC,管子均为双向管 模型内包含开环,电压单环,电压电流双闭环三种控制方式 两个电感的电流均流控制效果好可见下图电流细节 matlab/simulink/两相交错并联buck/boost变换器的仿真总能让工程师又爱…...
人生苦难的本质的庖丁解牛
“人生苦难的本质”,常被误解为“命运的不公”、“物质的匮乏”或“肉体的疼痛”。 但本质上,苦难并非来自外部世界的客观事件,而是源于**“内在预期”与“外在实相”之间的剧烈摩擦**,是**“有限的自我”试图掌控“无限的无常”时…...
AI辅助开发新思路:告诉快马你的需求,自动生成图形化MobaXterm工具
今天想和大家分享一个用AI辅助开发的小技巧——如何快速生成一个图形化的MobaXterm工具。作为一个经常需要管理远程服务器的开发者,我一直在寻找更高效的工作方式。最近在InsCode(快马)平台上尝试了AI辅助开发,发现它真的能大幅提升开发效率。 需求分析 …...
Pytorch自动微分模块:从原理到实战,解锁反向传播核心奥秘
Pytorch自动微分模块:从原理到实战,解锁反向传播核心奥秘一、核心认知:自动微分,深度学习的求导"神器"1.1 自动微分的核心价值1.2 核心公式:参数更新的底层逻辑(1)权重更新公式&#…...
HuggingFace Transformers库中Tokenizer与Model的高效实践指南
1. 为什么Tokenizer和Model是NLP项目的基石 第一次接触HuggingFace Transformers库时,我被Tokenizer和Model这两个组件的配合方式惊艳到了。想象一下,Tokenizer就像一位专业的翻译官,把人类能看懂的文字转换成计算机能理解的数字密码…...
周末限免别浪费!手把手教你用Node.js和Gemini API玩转Nano Banana开源项目
周末限免别浪费!手把手教你用Node.js和Gemini API玩转Nano Banana开源项目 周末的闲暇时光,正是技术爱好者探索新工具的最佳时机。最近Google AI Studio推出的Gemini API周末限免活动,为开发者们提供了一个零成本体验前沿AI技术的绝佳机会。…...
Vite Plus 迁移记录与踩坑总结
2. 为什么决定迁移到 ViteVite 刚刚发布,MIT 协议,免费且开源。我十分喜欢 Vite 的 API 的设计和兼容性,对于 Tona, Vite 几乎每个版本都有经历,从 Vite 0.8 版本开始使用, 逐步过渡到 Vite 8,每…...
