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博客 数据采集与增强 为了训练出适应多种表型和环境条件的模型,确保数据集的质量与多样性对于模型的成功至关重要。高质量的数据不仅需要准确无误、具有代表性,还需要涵盖尽可能…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...
自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
