YOLOv5+pyqt5+摄像头在特定条件下进行目标检测并采集原始数据

项目介绍

项目地址

GitHub - biabu0/Yolov5_D435i: 通过YOLOV5与pyqt5实现一个使用D435i深度摄像头采集特定需求与场景下的深度数据的小程序

        通过YOLOV5对指定的区域进行检测,当检测到目标进入特定区域时,开始保存数据,摄像头采用D435i深度相机,用于采集深度数据集。

  1. 指定需要屏蔽的检测区域,即使目标进入该区域也无法进行有效的检测,应用于特定场景的检测。
  2. 只有目标在检测区域内,才进行数据的采集与保存,避免一直采集数据,目标离开检测区域则停止保存数据,避免在数据采集过程中存在大量的无效数据,节约数据清洗时间,节省磁盘容量。
  3. 按照时间存储数据。
  4. 使用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 简介 - 白月黑羽

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

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

相关文章

图像的放缩比率如何计算的?

图像的放缩比率如何计算关键点 在医疗软件的胶片打印中,图像放缩比率的计算需要更加精确和考虑更多因素,以确保最终打印出来的影像准确无误,符合诊断要求。 以下是一些关键点: 像素间距(Pixel Spacing)&a…

leetcode-73.矩阵置零-day5

class Solution {public void setZeroes(int[][] mat) {int m mat.length, n mat[0].length;// 1. 扫描「首行」和「首列」记录「首行」和「首列」是否该被置零boolean r0 false, c0 false;for (int i 0; i < m; i) {if (mat[i][0] 0) {r0 true;break;}}for (int j …

uni-app H5端使用注意事项 【跨端开发系列】

&#x1f517; uniapp 跨端开发系列文章&#xff1a;&#x1f380;&#x1f380;&#x1f380; uni-app 组成和跨端原理 【跨端开发系列】 uni-app 各端差异注意事项 【跨端开发系列】uni-app 离线本地存储方案 【跨端开发系列】uni-app UI库、框架、组件选型指南 【跨端开…

相机不动,机构动作----Hands Eyes

最近在研究 手眼标定&#xff0c;发现大家都需付费&#xff0c;搞啥子&#xff0c;说好的开源。。。 以相机在上固定不动&#xff0c;机械手为 EPSON_Robot 为例&#xff0c;详细的一步一步实例操作指引 EPSON_Robot 的192.168.0.1 2004 Server 详细操作步骤 1. 启动程序 运…

DCDC降压模块

一、项目介绍 在B站看到工科男孙老师发的DCDC模块视频&#xff0c;后面有提到这款芯片&#xff0c;于是就使用这款芯片自己设计了这款降压模块。 芯片的封装为TSOT23-8&#xff0c;对空间利用率高。 输入电压的范围为3-18V。 输出电压的范围为0-8V。 输出电流最…

QILSTE H8-316QFO高亮橙光LED灯珠 发光二极管LED

在当今电子技术领域&#xff0c;H8-316QFO型号的LED以其卓越的性能和可靠性 脱颖而出。本文将深入探讨这款LED的关键参数&#xff0c;以期为工程师和技术人员提供详尽的技术参考。 首先&#xff0c;H8-316QFO的物理特性不容忽视。其外观尺寸为3.2x1.5x0.8mm&#xff0c;小巧的…

康耐视智能相机(Insight)通过ModbusTCP发送字符串到倍福(BECKHOFF)PLC中

文章目录 1.背景2.分析3.实现3.1.PLC的ModbusTCP_Server3.1.1.安装TF6250-Modbus-TCP3.1.2.PLC设置 3.2.智能相机的ModbusTCP_Client3.2.1.了解ModbusTCP的协议3.2.2.根据协议写代码3.2.2.1.纯函数代码3.2.2.2.脚本代码 3.2.3.非脚本处理时的代码逻辑图3.2.4.关于代码的问题及解…

自定义函数库

求两点距离 double dis(double x1, double y1, double x2, double y2){return sqrt(pow(x2-x1, 2)pow(y2-y1, 2)); }判断闰年 bool isLeapYear(int year){return year%40 && year%100!0 || year%4000; }判断素数 bool isPrime(int num){if(num<2) return false;f…

解决前后端发送验证码手机号登陆的sessionId不一致问题

前端&#xff1a;鸿蒙开发ArkTs语言 后端&#xff1a;spring boot mybatis-plus框架 后端代码 PostMapping("/sendMsg")public R<String> sendMsg(RequestBody User user, HttpServletRequest request, HttpServletResponse response) {// 从User对象中提取用…

基于多视角深度学习技术的乳腺X线分类:图神经网络与Transformer架构的研究|文献速递-生成式模型与transformer在医学影像中的应用速递

Title 题目 Mammography classification with multi-view deep learning techniques:Investigating graph and transformer-based architectures 基于多视角深度学习技术的乳腺X线分类&#xff1a;图神经网络与Transformer架构的研究 01 文献速递介绍 乳腺X线检查是乳腺癌…

开发环境服务器 vs 生产环境服务器:开发与生产须分明

【背景】作为开发者&#xff0c;我们在不同的阶段都与两种服务器环境打交道——开发环境服务器和生产环境服务器。虽然听起来名字相似&#xff0c;但它们的职责和工作方式简直是天差地别&#xff01; 不知道朋友们有没有跟我一开始刚了解的时候的一些疑惑&#xff0c;因为刚开始…

Maxscript移动、旋转和缩放

3DMAX对象最常用的三种变换方式是移动、旋转和缩放。本文将详细介绍这些是如何工作的。移动&#xff1a; 使用move函数处理移动&#xff1a; move <object> <vector> 按矢量移动对象&#xff1a; c cone() --c is at 0,0,0 move c [0,1,0] --after this l…

恢复删除的文件:6个免费Windows电脑数据恢复软件

数据恢复软件可帮助您从众多存储设备中恢复损坏或删除的数据。您可以使用这些文件恢复软件来检索文件、文档、视频、图片等。这些应用程序支持多种标准文件格式&#xff0c;如 PNG、RTF、PDF、HTML、JPG、MP3 等。 经过超过 75 小时的研究&#xff0c;我分析了 25 最佳免费数据…

探索 Python 编程调试案例:程序平均值的修复过程

&#x1f49d;&#x1f49d;&#x1f49d;Python 作为一门广泛应用的编程语言&#xff0c;其编程过程并非总是一帆风顺。即使是经验丰富的程序员&#xff0c;也会在代码中遇到各种错误。而调试Python代码过程&#xff0c;也是学习中不可避免的步骤。 今天来看一个简单的案例。…

简单了解一下 Go 语言构建约束?

​构建约束是一种在 Go 语言中控制源文件编译条件的方法&#xff0c;它可以让您指定某些文件只在特定的操作系统、架构、编译器或 Go 版本下编译&#xff0c;而在其他环境中自动忽略。这样可以方便您针对不同的平台或场景编写不同的代码&#xff0c;实现条件编译的功能。 构建…

全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之计数器与累加器实战题目

题目1—三个连续的自然数计算 问题描述&#xff1a; 若有3个连续的自然数&#xff0c;已知第一个自然数为100&#xff0c;请编写程序输出这3个自然数。 输入格式&#xff1a; 无 输出格式&#xff1a; 三行三个整数 输入输出样例&#xff1a; 输入样例 输出样例 无 1…

人工智能大语言模型起源篇(二),从通用语言微调到驾驭LLM

上一篇&#xff1a;《人工智能大语言模型起源篇&#xff08;一&#xff09;&#xff0c;从哪里开始》 &#xff08;5&#xff09;Howard 和 Ruder 于2018年发表的《Universal Language Model Fine-tuning for Text Classification》&#xff0c;https://arxiv.org/abs/1801.06…

基于MATLAB的电力系统潮流计算

为了进行潮流计算&#xff0c;通常可以使用像MATPOWER这样的电力系统分析工具包&#xff0c; 在MATLAB中的MATPOWER工具包中&#xff0c;多个不同的系统模型被定义为测试案例&#xff08;case&#xff09;。这些测试案例用于模拟和分析电力系统中的潮流计算、最优潮流问题、稳…

Unity屏幕截图、区域截图、读取图片、WebGL长截屏并下载到本地jpg

Unity屏幕截图、区域截图、读取图片、WebGL长截屏并下载到本地jpg 一、全屏截图并保存到StreamingAssets路径下 Texture2D screenShot;//保存截取的纹理public Image image; //显示截屏的Imagepublic void Jietu(){StartCoroutine(ScrrenCapture(new Rect(0, 0, Screen.width…

使用 ADB (Android Debug Bridge) 工具来截取 Android 设备的屏幕截图

可以使用 ADB (Android Debug Bridge) 工具来截取 Android 设备的屏幕截图。以下是具体的操作步骤&#xff1a; 1. 连接设备 确保 Android 设备通过 USB 或网络连接到电脑&#xff0c;并运行以下命令检查连接状态&#xff1a; adb devices2. 截取屏幕截图 运行以下命令将设…