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博客 数据采集与增强 为了训练出适应多种表型和环境条件的模型,确保数据集的质量与多样性对于模型的成功至关重要。高质量的数据不仅需要准确无误、具有代表性,还需要涵盖尽可能…...
重装系统后的环境快速恢复:包含BERT模型部署的自动化脚本
重装系统后的环境快速恢复:包含BERT模型部署的自动化脚本 重装系统,对开发者来说,就像一场“数字大扫除”。清爽是清爽了,但看着空空如也的终端和待部署的一长串服务列表,那种从头再来的疲惫感瞬间涌上心头。尤其是当…...
【架构实战】健康检查与故障转移机制
一、为什么需要健康检查 在分布式系统中,服务实例可能因为各种原因变得不可用,而调用方却毫不知情,继续向故障实例发送请求,导致大量失败。常见的服务不可用场景:- 进程假死:Java进程存在但无法响应请求&am…...
手把手教你用FUTURE POLICE:会议录音秒变带时间轴字幕
手把手教你用FUTURE POLICE:会议录音秒变带时间轴字幕 1. 为什么需要高精度字幕对齐? 在日常工作中,我们经常遇到这样的场景:重要会议录音需要整理成文字稿,但人工听写耗时耗力;视频剪辑时需要添加字幕&a…...
ROS2 Humble下,如何用MoveIt! Action接口让机械臂“听话”?一个抓取demo的完整复盘
ROS2 Humble下机械臂精准控制实战:从MoveIt! Action接口到完整抓取任务 在工业自动化和服务机器人领域,机械臂的精准运动控制一直是核心挑战。ROS2 Humble版本中的MoveIt!框架为这一挑战提供了优雅的解决方案,而理解其Action接口的运作机制则…...
如何获取网易云音乐永久链接:终极免费解决方案指南
如何获取网易云音乐永久链接:终极免费解决方案指南 【免费下载链接】netease-cloud-music-api 网易云音乐直链解析 API 项目地址: https://gitcode.com/gh_mirrors/ne/netease-cloud-music-api 你是否曾经遇到过这样的烦恼:好不容易找到一首喜欢的…...
Cogito v1预览版3B模型实战体验:超越Llama/DeepSeek的混合推理能力
Cogito v1预览版3B模型实战体验:超越Llama/DeepSeek的混合推理能力 1. 模型概览与核心优势 1.1 什么是Cogito v1预览版 Cogito v1预览版是Deep Cogito推出的混合推理模型系列,这个3B参数的版本在多项基准测试中表现优异。与传统的语言模型不同&#x…...
Wan2.2-I2V-A14B部署教程:解决OOM/驱动报错/端口冲突三大常见问题
Wan2.2-I2V-A14B部署教程:解决OOM/驱动报错/端口冲突三大常见问题 1. 镜像概述与核心优势 Wan2.2-I2V-A14B是一款专为文生视频任务优化的私有部署镜像,特别针对RTX 4090D 24GB显存配置进行了深度优化。这个镜像最大的特点是解决了AI视频生成领域常见的…...
Lingbot-Depth-Pretrain-ViTL-14 Anaconda环境搭建:创建隔离的Python开发与推理环境
Lingbot-Depth-Pretrain-ViTL-14 Anaconda环境搭建:创建隔离的Python开发与推理环境 你是不是也遇到过这种情况:好不容易跟着教程跑通了一个AI项目,结果过两天想跑另一个项目时,发现各种库版本冲突,报错满天飞&#x…...
Qwen-Image-Edit-F2P开源可部署优势:模型权重完全本地化,无外部API依赖风险
Qwen-Image-Edit-F2P开源可部署优势:模型权重完全本地化,无外部API依赖风险 1. 开箱即用的AI图像编辑体验 想象一下,你只需要一台配备24GB显存的电脑,就能拥有一个专业的AI图像编辑工作室。Qwen-Image-Edit-F2P正是这样一个让人…...
保姆级教程:用PtitPrince的RainCloud函数,5步搞定分组数据可视化
5步精通RainCloud Plot:用PtitPrince实现专业级分组数据可视化 第一次看到同事用雨云图展示A/B测试结果时,我被这种"既见森林又见树木"的呈现方式震撼了——左侧的密度曲线如山脉般起伏,中间的箱线图标出关键分位点,右侧…...
