wx供重浩:创享日记
对话框发送:225头盔
获取完整源码源文件+已标注的数据集(1463张)+源码各文件说明+配置跑通说明文档
若需要一对一远程操作在你电脑跑通,有偿59yuan


效果展示

基于YOLOv8深度学习+PyQT5的电动车头盔佩戴检测系统

在这里插入图片描述

各文件说明

在这里插入图片描述


随着电动车的普及,交通安全问题日益凸显。头盔作为保护骑行者头部安全的重要装备,其佩戴情况的监测对于减少交通事故伤害具有重要意义。本文提出了一种基于YOLOv8(You Only Look Once version 8)的电动车头盔佩戴检测系统,旨在实时监测并提醒骑行者佩戴头盔。该系统利用深度学习技术,通过训练YOLOv8模型来识别电动车骑行者是否佩戴头盔,并在检测到未佩戴头盔的情况下发出警报。系统设计考虑了实时性、准确性和用户友好性,为提升电动车骑行安全提供了一种有效的技术解决方案。

电动车作为一种便捷的交通工具,在城市交通中扮演着越来越重要的角色。然而,由于缺乏必要的安全措施,电动车事故频发,尤其是头部伤害,往往导致严重后果。头盔的正确佩戴可以有效降低头部受伤的风险。因此,开发一种能够实时监测头盔佩戴情况的系统,对于提高骑行者的安全意识和减少交通事故具有重要作用。

YOLOv8是YOLO系列目标检测模型的最新版本,它在前代模型的基础上进行了优化,提高了检测速度和准确性。YOLOv8采用了多尺度特征图的融合、更精细的锚点框设计以及更有效的损失函数,使得模型在处理复杂场景时表现出色。

系统设计
数据集准备
为了训练YOLOv8模型,首先需要收集和标注一个包含大量电动车骑行者图像的数据集。数据集应包含各种天气条件、不同光照环境以及多种头盔类型。图像标注需要指出头盔的位置和类别,以便模型学习区分佩戴头盔与否。

模型训练
使用准备好的数据集,对YOLOv8模型进行训练。训练过程中,需要调整学习率、批大小、训练周期等超参数,以获得最佳的检测效果。同时,可以采用数据增强技术,如随机裁剪、旋转、颜色变换等,以提高模型的泛化能力。

系统实现
系统的核心是YOLOv8模型,它负责从输入的实时视频流中检测头盔。系统还包括一个用户界面,用于显示检测结果和发出警报。当模型检测到未佩戴头盔的骑行者时,系统会通过声音或视觉信号提醒用户。

实时检测
为了实现实时检测,系统需要能够在低延迟的情况下处理视频流。这要求模型不仅要准确,还要高效。在实际部署中,可能需要在边缘设备上进行模型推理,以减少对中心服务器的依赖。

结果与讨论
在测试集上,YOLOv8模型展现出了较高的头盔检测准确率。在不同的场景和光照条件下,模型均能稳定地识别出佩戴和未佩戴头盔的骑行者。然而,模型在处理遮挡严重或头盔与骑行者头部颜色相近的情况下仍有改进空间。

结论
本文提出的基于YOLOv8的电动车头盔佩戴检测系统,能够有效地提高电动车骑行者的安全意识。通过实时监测和提醒,该系统有助于减少因未佩戴头盔导致的交通事故伤害。未来的工作将集中在进一步提高模型的鲁棒性,以及探索更高效的模型部署方案。


软件系统部分源码

# -*- coding: utf-8 -*-
import time
from PyQt5.QtWidgets import QApplication , QMainWindow, QFileDialog, \
    QMessageBox,QWidget,QHeaderView,QTableWidgetItem, QAbstractItemView
import sys
import os
from PIL import ImageFont
from ultralytics import YOLO
sys.path.append('UIProgram')
from UIProgram.UiMain import Ui_MainWindow
import sys
from PyQt5.QtCore import QTimer, Qt, QThread, pyqtSignal,QCoreApplication
import detect_tools as tools
import cv2
import Config
from UIProgram.QssLoader import QSSLoader
from UIProgram.precess_bar import ProgressBar
import numpy as np
# import torch

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(QMainWindow, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.initMain()
        self.signalconnect()

        # 加载css渲染效果
        style_file = 'UIProgram/style.css'
        qssStyleSheet = QSSLoader.read_qss_file(style_file)
        self.setStyleSheet(qssStyleSheet)

    def signalconnect(self):
        self.ui.PicBtn.clicked.connect(self.open_img)
        self.ui.comboBox.activated.connect(self.combox_change)
        self.ui.VideoBtn.clicked.connect(self.vedio_show)
        self.ui.CapBtn.clicked.connect(self.camera_show)
        self.ui.SaveBtn.clicked.connect(self.save_detect_video)
        self.ui.ExitBtn.clicked.connect(QCoreApplication.quit)
        self.ui.FilesBtn.clicked.connect(self.detact_batch_imgs)

    def initMain(self):
        self.show_width = 770
        self.show_height = 480

        self.org_path = None

        self.is_camera_open = False
        self.cap = None

        # self.device = 0 if torch.cuda.is_available() else 'cpu'

        # 加载检测模型
        self.model = YOLO(Config.model_path, task='detect')
        self.model(np.zeros((48, 48, 3)))  #预先加载推理模型
        self.fontC = ImageFont.truetype("Font/platech.ttf", 25, 0)

        # 用于绘制不同颜色矩形框
        self.colors = tools.Colors()

        # 更新视频图像
        self.timer_camera = QTimer()

        # 更新检测信息表格
        # self.timer_info = QTimer()
        # 保存视频
        self.timer_save_video = QTimer()

        # 表格
        self.ui.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)
        self.ui.tableWidget.verticalHeader().setDefaultSectionSize(40)
        self.ui.tableWidget.setColumnWidth(0, 80)  # 设置列宽
        self.ui.tableWidget.setColumnWidth(1, 200)
        self.ui.tableWidget.setColumnWidth(2, 150)
        self.ui.tableWidget.setColumnWidth(3, 90)
        self.ui.tableWidget.setColumnWidth(4, 230)
        # self.ui.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)  # 表格铺满
        # self.ui.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Interactive)
        # self.ui.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)  # 设置表格不可编辑
        self.ui.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)  # 设置表格整行选中
        self.ui.tableWidget.verticalHeader().setVisible(False)  # 隐藏列标题
        self.ui.tableWidget.setAlternatingRowColors(True)  # 表格背景交替

        # 设置主页背景图片border-image: url(:/icons/ui_imgs/icons/camera.png)
        # self.setStyleSheet("#MainWindow{background-image:url(:/bgs/ui_imgs/bg3.jpg)}")

    def open_img(self):
        if self.cap:
            # 打开图片前关闭摄像头
            self.video_stop()
            self.is_camera_open = False
            self.ui.CaplineEdit.setText('摄像头未开启')
            self.cap = None

        # 弹出的窗口名称:'打开图片'
        # 默认打开的目录:'./'
        # 只能打开.jpg与.gif结尾的图片文件
        # file_path, _ = QFileDialog.getOpenFileName(self.ui.centralwidget, '打开图片', './', "Image files (*.jpg *.gif)")
        file_path, _ = QFileDialog.getOpenFileName(None, '打开图片', './', "Image files (*.jpg *.jepg *.png)")
        if not file_path:
            return

        self.ui.comboBox.setDisabled(False)
        self.org_path = file_path
        self.org_img = tools.img_cvread(self.org_path)

        # 目标检测
        t1 = time.time()
        self.results = self.model(self.org_path)[0]
        t2 = time.time()
        take_time_str = '{:.3f} s'.format(t2 - t1)
        self.ui.time_lb.setText(take_time_str)

        location_list = self.results.boxes.xyxy.tolist()
        self.location_list = [list(map(int, e)) for e in location_list]
        cls_list = self.results.boxes.cls.tolist()
        self.cls_list = [int(i) for i in cls_list]
        self.conf_list = self.results.boxes.conf.tolist()
        self.conf_list = ['%.2f %%' % (each*100) for each in self.conf_list]

        # now_img = self.cv_img.copy()
        # for loacation, type_id, conf in zip(self.location_list, self.cls_list, self.conf_list):
        #     type_id = int(type_id)
        #     color = self.colors(int(type_id), True)
        #     # cv2.rectangle(now_img, (int(x1), int(y1)), (int(x2), int(y2)), colors(int(type_id), True), 3)
        #     now_img = tools.drawRectBox(now_img, loacation, Config.CH_names[type_id], self.fontC, color)
        now_img = self.results.plot()
        self.draw_img = now_img
        # 获取缩放后的图片尺寸
        self.img_width, self.img_height = self.get_resize_size(now_img)
        resize_cvimg = cv2.resize(now_img,(self.img_width, self.img_height))
        pix_img = tools.cvimg_to_qpiximg(resize_cvimg)
        self.ui.label_show.setPixmap(pix_img)
        self.ui.label_show.setAlignment(Qt.AlignCenter)
        # 设置路径显示
        self.ui.PiclineEdit.setText(self.org_path)

        # 目标数目
        target_nums = len(self.cls_list)
        self.ui.label_nums.setText(str(target_nums))

        # 设置目标选择下拉框
        choose_list = ['全部']
        target_names = [Config.names[id]+ '_'+ str(index) for index,id in enumerate(self.cls_list)]
        # object_list = sorted(set(self.cls_list))
        # for each in object_list:
        #     choose_list.append(Config.CH_names[each])
        choose_list = choose_list + target_names

        self.ui.comboBox.clear()
        self.ui.comboBox.addItems(choose_list)

        if target_nums >= 1:
            self.ui.type_lb.setText(Config.CH_names[self.cls_list[0]])
            self.ui.label_conf.setText(str(self.conf_list[0]))
        #   默认显示第一个目标框坐标
        #   设置坐标位置值
            self.ui.label_xmin.setText(str(self.location_list[0][0]))
            self.ui.label_ymin.setText(str(self.location_list[0][1]))
            self.ui.label_xmax.setText(str(self.location_list[0][2]))
            self.ui.label_ymax.setText(str(self.location_list[0][3]))
        else:
            self.ui.type_lb.setText('')
            self.ui.label_conf.setText('')
            self.ui.label_xmin.setText('')
            self.ui.label_ymin.setText('')
            self.ui.label_xmax.setText('')
            self.ui.label_ymax.setText('')

        # # 删除表格所有行
        self.ui.tableWidget.setRowCount(0)
        self.ui.tableWidget.clearContents()
        self.tabel_info_show(self.location_list, self.cls_list, self.conf_list,path=self.org_path)


    def detact_batch_imgs(self):
        if self.cap:
            # 打开图片前关闭摄像头
            self.video_stop()
            self.is_camera_open = False
            self.ui.CaplineEdit.setText('摄像头未开启')
            self.cap = None
        directory = QFileDialog.getExistingDirectory(self,
                                                      "选取文件夹",
                                                      "./")  # 起始路径
        if not  directory:
            return
        self.org_path = directory
        img_suffix = ['jpg','png','jpeg','bmp']
        for file_name in os.listdir(directory):
            full_path = os.path.join(directory,file_name)
            if os.path.isfile(full_path) and file_name.split('.')[-1].lower() in img_suffix:
                # self.ui.comboBox.setDisabled(False)
                img_path = full_path
                self.org_img = tools.img_cvread(img_path)
                # 目标检测
                t1 = time.time()
                self.results = self.model(img_path)[0]
                t2 = time.time()
                take_time_str = '{:.3f} s'.format(t2 - t1)
                self.ui.time_lb.setText(take_time_str)

                location_list = self.results.boxes.xyxy.tolist()
                self.location_list = [list(map(int, e)) for e in location_list]
                cls_list = self.results.boxes.cls.tolist()
                self.cls_list = [int(i) for i in cls_list]
                self.conf_list = self.results.boxes.conf.tolist()
                self.conf_list = ['%.2f %%' % (each * 100) for each in self.conf_list]

                now_img = self.results.plot()

                self.draw_img = now_img
                # 获取缩放后的图片尺寸
                self.img_width, self.img_height = self.get_resize_size(now_img)
                resize_cvimg = cv2.resize(now_img, (self.img_width, self.img_height))
                pix_img = tools.cvimg_to_qpiximg(resize_cvimg)
                self.ui.label_show.setPixmap(pix_img)
                self.ui.label_show.setAlignment(Qt.AlignCenter)
                # 设置路径显示
                self.ui.PiclineEdit.setText(img_path)

                # 目标数目
                target_nums = len(self.cls_list)
                self.ui.label_nums.setText(str(target_nums))

                # 设置目标选择下拉框
                choose_list = ['全部']
                target_names = [Config.names[id] + '_' + str(index) for index, id in enumerate(self.cls_list)]
                choose_list = choose_list + target_names

                self.ui.comboBox.clear()
                self.ui.comboBox.addItems(choose_list)

                if target_nums >= 1:
                    self.ui.type_lb.setText(Config.CH_names[self.cls_list[0]])
                    self.ui.label_conf.setText(str(self.conf_list[0]))
                    #   默认显示第一个目标框坐标
                    #   设置坐标位置值
                    self.ui.label_xmin.setText(str(self.location_list[0][0]))
                    self.ui.label_ymin.setText(str(self.location_list[0][1]))
                    self.ui.label_xmax.setText(str(self.location_list[0][2]))
                    self.ui.label_ymax.setText(str(self.location_list[0][3]))
                else:
                    self.ui.type_lb.setText('')
                    self.ui.label_conf.setText('')
                    self.ui.label_xmin.setText('')
                    self.ui.label_ymin.setText('')
                    self.ui.label_xmax.setText('')
                    self.ui.label_ymax.setText('')

                # # 删除表格所有行
                # self.ui.tableWidget.setRowCount(0)
                # self.ui.tableWidget.clearContents()
                self.tabel_info_show(self.location_list, self.cls_list, self.conf_list, path=img_path)
                self.ui.tableWidget.scrollToBottom()
                QApplication.processEvents()  #刷新页面

    def draw_rect_and_tabel(self, results, img):
        now_img = img.copy()
        location_list = results.boxes.xyxy.tolist()
        self.location_list = [list(map(int, e)) for e in location_list]
        cls_list = results.boxes.cls.tolist()
        self.cls_list = [int(i) for i in cls_list]
        self.conf_list = results.boxes.conf.tolist()
        self.conf_list = ['%.2f %%' % (each * 100) for each in self.conf_list]

        for loacation, type_id, conf in zip(self.location_list, self.cls_list, self.conf_list):
            type_id = int(type_id)
            color = self.colors(int(type_id), True)
            # cv2.rectangle(now_img, (int(x1), int(y1)), (int(x2), int(y2)), colors(int(type_id), True), 3)
            now_img = tools.drawRectBox(now_img, loacation, Config.CH_names[type_id], self.fontC, color)

        # 获取缩放后的图片尺寸
        self.img_width, self.img_height = self.get_resize_size(now_img)
        resize_cvimg = cv2.resize(now_img, (self.img_width, self.img_height))
        pix_img = tools.cvimg_to_qpiximg(resize_cvimg)
        self.ui.label_show.setPixmap(pix_img)
        self.ui.label_show.setAlignment(Qt.AlignCenter)
        # 设置路径显示
        self.ui.PiclineEdit.setText(self.org_path)

        # 目标数目
        target_nums = len(self.cls_list)
        self.ui.label_nums.setText(str(target_nums))
        if target_nums >= 1:
            self.ui.type_lb.setText(Config.CH_names[self.cls_list[0]])
            self.ui.label_conf.setText(str(self.conf_list[0]))
            self.ui.label_xmin.setText(str(self.location_list[0][0]))
            self.ui.label_ymin.setText(str(self.location_list[0][1]))
            self.ui.label_xmax.setText(str(self.location_list[0][2]))
            self.ui.label_ymax.setText(str(self.location_list[0][3]))
        else:
            self.ui.type_lb.setText('')
            self.ui.label_conf.setText('')
            self.ui.label_xmin.setText('')
            self.ui.label_ymin.setText('')
            self.ui.label_xmax.setText('')
            self.ui.label_ymax.setText('')

        # 删除表格所有行
        self.ui.tableWidget.setRowCount(0)
        self.ui.tableWidget.clearContents()
        self.tabel_info_show(self.location_list, self.cls_list, self.conf_list, path=self.org_path)
        return now_img

    def combox_change(self):
        com_text = self.ui.comboBox.currentText()
        if com_text == '全部':
            cur_box = self.location_list
            cur_img = self.results.plot()
            self.ui.type_lb.setText(Config.CH_names[self.cls_list[0]])
            self.ui.label_conf.setText(str(self.conf_list[0]))
        else:
            index = int(com_text.split('_')[-1])
            cur_box = [self.location_list[index]]
            cur_img = self.results[index].plot()
            self.ui.type_lb.setText(Config.CH_names[self.cls_list[index]])
            self.ui.label_conf.setText(str(self.conf_list[index]))

        # 设置坐标位置值
        self.ui.label_xmin.setText(str(cur_box[0][0]))
        self.ui.label_ymin.setText(str(cur_box[0][1]))
        self.ui.label_xmax.setText(str(cur_box[0][2]))
        self.ui.label_ymax.setText(str(cur_box[0][3]))

        resize_cvimg = cv2.resize(cur_img, (self.img_width, self.img_height))
        pix_img = tools.cvimg_to_qpiximg(resize_cvimg)
        self.ui.label_show.clear()
        self.ui.label_show.setPixmap(pix_img)
        self.ui.label_show.setAlignment(Qt.AlignCenter)


    def get_video_path(self):
        file_path, _ = QFileDialog.getOpenFileName(None, '打开视频', './', "Image files (*.avi *.mp4 *.jepg *.png)")
        if not file_path:
            return None
        self.org_path = file_path
        self.ui.VideolineEdit.setText(file_path)
        return file_path

    def video_start(self):
        # 删除表格所有行
        self.ui.tableWidget.setRowCount(0)
        self.ui.tableWidget.clearContents()

        # 清空下拉框
        self.ui.comboBox.clear()

        # 定时器开启,每隔一段时间,读取一帧
        self.timer_camera.start(1)
        self.timer_camera.timeout.connect(self.open_frame)

    def tabel_info_show(self, locations, clses, confs, path=None):
        path = path
        for location, cls, conf in zip(locations, clses, confs):
            row_count = self.ui.tableWidget.rowCount()  # 返回当前行数(尾部)
            self.ui.tableWidget.insertRow(row_count)  # 尾部插入一行
            item_id = QTableWidgetItem(str(row_count+1))  # 序号
            item_id.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)  # 设置文本居中
            item_path = QTableWidgetItem(str(path))  # 路径
            # item_path.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

            item_cls = QTableWidgetItem(str(Config.CH_names[cls]))
            item_cls.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)  # 设置文本居中

            item_conf = QTableWidgetItem(str(conf))
            item_conf.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)  # 设置文本居中

            item_location = QTableWidgetItem(str(location)) # 目标框位置
            # item_location.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)  # 设置文本居中

            self.ui.tableWidget.setItem(row_count, 0, item_id)
            self.ui.tableWidget.setItem(row_count, 1, item_path)
            self.ui.tableWidget.setItem(row_count, 2, item_cls)
            self.ui.tableWidget.setItem(row_count, 3, item_conf)
            self.ui.tableWidget.setItem(row_count, 4, item_location)
        self.ui.tableWidget.scrollToBottom()

    def video_stop(self):
        self.cap.release()
        self.timer_camera.stop()
        # self.timer_info.stop()

    def open_frame(self):
        ret, now_img = self.cap.read()
        if ret:
            # 目标检测
            t1 = time.time()
            results = self.model(now_img)[0]
            t2 = time.time()
            take_time_str = '{:.3f} s'.format(t2 - t1)
            self.ui.time_lb.setText(take_time_str)

            location_list = results.boxes.xyxy.tolist()
            self.location_list = [list(map(int, e)) for e in location_list]
            cls_list = results.boxes.cls.tolist()
            self.cls_list = [int(i) for i in cls_list]
            self.conf_list = results.boxes.conf.tolist()
            self.conf_list = ['%.2f %%' % (each * 100) for each in self.conf_list]

            now_img = results.plot()

            # 获取缩放后的图片尺寸
            self.img_width, self.img_height = self.get_resize_size(now_img)
            resize_cvimg = cv2.resize(now_img, (self.img_width, self.img_height))
            pix_img = tools.cvimg_to_qpiximg(resize_cvimg)
            self.ui.label_show.setPixmap(pix_img)
            self.ui.label_show.setAlignment(Qt.AlignCenter)

            # 目标数目
            target_nums = len(self.cls_list)
            self.ui.label_nums.setText(str(target_nums))

            # 设置目标选择下拉框
            choose_list = ['全部']
            target_names = [Config.names[id] + '_' + str(index) for index, id in enumerate(self.cls_list)]
            # object_list = sorted(set(self.cls_list))
            # for each in object_list:
            #     choose_list.append(Config.CH_names[each])
            choose_list = choose_list + target_names

            self.ui.comboBox.clear()
            self.ui.comboBox.addItems(choose_list)

            if target_nums >= 1:
                self.ui.type_lb.setText(Config.CH_names[self.cls_list[0]])
                self.ui.label_conf.setText(str(self.conf_list[0]))
                #   默认显示第一个目标框坐标
                #   设置坐标位置值
                self.ui.label_xmin.setText(str(self.location_list[0][0]))
                self.ui.label_ymin.setText(str(self.location_list[0][1]))
                self.ui.label_xmax.setText(str(self.location_list[0][2]))
                self.ui.label_ymax.setText(str(self.location_list[0][3]))
            else:
                self.ui.type_lb.setText('')
                self.ui.label_conf.setText('')
                self.ui.label_xmin.setText('')
                self.ui.label_ymin.setText('')
                self.ui.label_xmax.setText('')
                self.ui.label_ymax.setText('')


            # 删除表格所有行
            # self.ui.tableWidget.setRowCount(0)
            # self.ui.tableWidget.clearContents()
            self.tabel_info_show(self.location_list, self.cls_list, self.conf_list, path=self.org_path)

        else:
            self.cap.release()
            self.timer_camera.stop()

    def vedio_show(self):
        if self.is_camera_open:
            self.is_camera_open = False
            self.ui.CaplineEdit.setText('摄像头未开启')

        video_path = self.get_video_path()
        if not video_path:
            return None
        self.cap = cv2.VideoCapture(video_path)
        self.video_start()
        self.ui.comboBox.setDisabled(True)

    def camera_show(self):
        self.is_camera_open = not self.is_camera_open
        if self.is_camera_open:
            self.ui.CaplineEdit.setText('摄像头开启')
            self.cap = cv2.VideoCapture(0)
            self.video_start()
            self.ui.comboBox.setDisabled(True)
        else:
            self.ui.CaplineEdit.setText('摄像头未开启')
            self.ui.label_show.setText('')
            if self.cap:
                self.cap.release()
                cv2.destroyAllWindows()
            self.ui.label_show.clear()

    def get_resize_size(self, img):
        _img = img.copy()
        img_height, img_width , depth= _img.shape
        ratio = img_width / img_height
        if ratio >= self.show_width / self.show_height:
            self.img_width = self.show_width
            self.img_height = int(self.img_width / ratio)
        else:
            self.img_height = self.show_height
            self.img_width = int(self.img_height * ratio)
        return self.img_width, self.img_height

    def save_detect_video(self):
        if self.cap is None and not self.org_path:
            QMessageBox.about(self, '提示', '当前没有可保存信息,请先打开图片或视频!')
            return

        if self.is_camera_open:
            QMessageBox.about(self, '提示', '摄像头视频无法保存!')
            return

        if self.cap:
            res = QMessageBox.information(self, '提示', '保存视频检测结果可能需要较长时间,请确认是否继续保存?',QMessageBox.Yes | QMessageBox.No ,  QMessageBox.Yes)
            if res == QMessageBox.Yes:
                self.video_stop()
                com_text = self.ui.comboBox.currentText()
                self.btn2Thread_object = btn2Thread(self.org_path, self.model, com_text)
                self.btn2Thread_object.start()
                self.btn2Thread_object.update_ui_signal.connect(self.update_process_bar)
            else:
                return
        else:
            if os.path.isfile(self.org_path):
                fileName = os.path.basename(self.org_path)
                name , end_name= fileName.rsplit(".",1)
                save_name = name + '_detect_result.' + end_name
                save_img_path = os.path.join(Config.save_path, save_name)
                # 保存图片
                cv2.imwrite(save_img_path, self.draw_img)
                QMessageBox.about(self, '提示', '图片保存成功!\n文件路径:{}'.format(save_img_path))
            else:
                img_suffix = ['jpg', 'png', 'jpeg', 'bmp']
                for file_name in os.listdir(self.org_path):
                    full_path = os.path.join(self.org_path, file_name)
                    if os.path.isfile(full_path) and file_name.split('.')[-1].lower() in img_suffix:
                        name, end_name = file_name.rsplit(".",1)
                        save_name = name + '_detect_result.' + end_name
                        save_img_path = os.path.join(Config.save_path, save_name)
                        results = self.model(full_path)[0]
                        now_img = results.plot()
                        # 保存图片
                        cv2.imwrite(save_img_path, now_img)

                QMessageBox.about(self, '提示', '图片保存成功!\n文件路径:{}'.format(Config.save_path))


    def update_process_bar(self,cur_num, total):
        if cur_num == 1:
            self.progress_bar = ProgressBar(self)
            self.progress_bar.show()
        if cur_num >= total:
            self.progress_bar.close()
            QMessageBox.about(self, '提示', '视频保存成功!\n文件在{}目录下'.format(Config.save_path))
            return
        if self.progress_bar.isVisible() is False:
            # 点击取消保存时,终止进程
            self.btn2Thread_object.stop()
            return
        value = int(cur_num / total *100)
        self.progress_bar.setValue(cur_num, total, value)
        QApplication.processEvents()


class btn2Thread(QThread):
    """
    进行检测后的视频保存
    """
    # 声明一个信号
    update_ui_signal = pyqtSignal(int,int)

    def __init__(self, path, model, com_text):
        super(btn2Thread, self).__init__()
        self.org_path = path
        self.model = model
        self.com_text = com_text
        # 用于绘制不同颜色矩形框
        self.colors = tools.Colors()
        self.is_running = True  # 标志位,表示线程是否正在运行

    def run(self):
        # VideoCapture方法是cv2库提供的读取视频方法
        cap = cv2.VideoCapture(self.org_path)
        # 设置需要保存视频的格式“xvid”
        # 该参数是MPEG-4编码类型,文件名后缀为.avi
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        # 设置视频帧频
        fps = cap.get(cv2.CAP_PROP_FPS)
        # 设置视频大小
        size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
        # VideoWriter方法是cv2库提供的保存视频方法
        # 按照设置的格式来out输出
        fileName = os.path.basename(self.org_path)
        name, end_name = fileName.split('.')
        save_name = name + '_detect_result.avi'
        save_video_path = os.path.join(Config.save_path, save_name)
        out = cv2.VideoWriter(save_video_path, fourcc, fps, size)

        prop = cv2.CAP_PROP_FRAME_COUNT
        total = int(cap.get(prop))
        print("[INFO] 视频总帧数:{}".format(total))
        cur_num = 0

        # 确定视频打开并循环读取
        while (cap.isOpened() and self.is_running):
            cur_num += 1
            print('当前第{}帧,总帧数{}'.format(cur_num, total))
            # 逐帧读取,ret返回布尔值
            # 参数ret为True 或者False,代表有没有读取到图片
            # frame表示截取到一帧的图片
            ret, frame = cap.read()
            if ret == True:
                # 检测
                results = self.model(frame)[0]
                frame = results.plot()
                out.write(frame)
                self.update_ui_signal.emit(cur_num, total)
            else:
                break
        # 释放资源
        cap.release()
        out.release()

    def stop(self):
        self.is_running = False


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

相关文章

一张图读懂人工智能

三、人工智能和多式联运 AI产品的发展趋势,以及语言模型的应急能力和广泛应用。视频探讨了人工智能和人类的优劣势,以及未来的发展方向。视频提出了一种积极的心态,认为人工智能可以成为我们的同事,帮助我们提高效率和能力。二、大型语言模型的训练过程和应用场景,包括文本到文本、图像到文本、语音转录等多个方面。同时也提到了不同模型的能力和成本。一、生成人工智能的概念和应用,以及如何使用大型语言模型进行聊天和创造原创内容。五、如何使用生成人工智能作为招聘公司的工具,以及如何有效地使用生成人工智能来制作有用结果的提示。

chatgpt的大致技术原理

在RLHF中,人类用户对模型生成的文本提供反馈(如打分或选择更喜欢的文本),然后模型根据这些反馈进行进一步的训练。预处理步骤包括分词(使用BPE算法将文本分解为更小的子单元,如单词或符号)、去除停用词(即那些对文本意义不大的词,如“的”、“了”等)以及其他可能的文本清洗工作。生成过程中,模型会考虑前文的上下文信息,以确保生成的文本是连贯和有意义的。通过收集大量的文本数据、建立深度学习模型、进行预训练和微调以及使用搜索算法和人类反馈强化学习等技术,ChatGPT能够生成高质量、连贯且有用的文本回复。

云计算与边缘计算:有什么区别?

云计算和边缘计算作为不同的计算范式,各自在特定场景中发挥着独特的作用。它们的区别体现在数据处理位置、延迟、可用性以及应用场景等方面。然而,随着数字化时代的发展,它们也逐渐形成了协同应用的趋势,充分发挥各自的优势,提供更灵活、高效的计算体系结构。未来,随着智能化、自动化和边缘计算的边界拓展,云计算和边缘计算将进一步推动数字化转型。同时,安全性、跨边缘计算标准和环境可持续性等问题也需要在未来的发展中得到更好的解决。

ChatGPT高效提问—prompt基础

​ 设计一个好的prompt对于获取理想的生成结果至关重要。通过选择合适的关键词、提供明确的上下文、设置特定的约束条件,可以引导模型生成符合预期的回复。例如,在对话中,可以使用明确的问题或陈述引导模型生成相关、具体的回答;在摘要生成中,可以提供需要摘要的文章段落作为prompt,以确保生成的摘要准确而精炼。

二维平面阵列波束赋形原理和Matlab仿真

阵面左下角天线位于坐标原点,将坐标原点阵元设为参考阵元,计算每个阵元相对于该参考阵元的入射波程差,从而来计算每个阵元接收的回波信号。实现波束赋形的最基本的方法是对各个天线阵元的信号进行适当延迟后相加,使目标方向的信号同相叠加得到增强,而其他方向均有不同程度的削弱,该方法通常用于模拟信号.根据上述理论推导可以仿真任意平面阵列的方向图,这里对两种典型的阵列(矩形平面阵列和圆形阵列)进行Matlab仿真,其余类型的阵列在此基础上修改即可。根据上述圆形阵列公式做仿真,得到下述的三维空间方向图。

人工智能与机器学习——开启智能时代的里程碑

人工智能是指使计算机系统表现出类似于人类智能的能力。其目标是实现机器具备感知、理解、学习、推理和决策等智能行为。人工智能的发展可以追溯到上世纪50年代,随着计算机技术和算法的不断进步,人工智能得以实现。机器学习是人工智能的一个重要分支,它通过让计算机从数据中学习和改进性能,而不需要明确的编程指令。机器学习可以分为监督学习、无监督学习和强化学习三种主要类型。

【GPU】深入理解GPU硬件架构及运行机制

GPU的基本底层构成,主要是以GPU计算核心 Cores,以及Memory以及控制单元,三大组成要素组成。Core是计算的基本单元,既可以用作简单的浮点运算,又可以做一些复杂的运算例如,tensor 或者ray tracing。多个core之间通讯的方式:在特定的应用场合多个core之间是不需要的通讯的,也就是各干各的(例如 图像缩放)。但是也有一些例子,多个core之间要相互通讯配合(例如上文谈到的数组求和问题),每个core之间都可以实现交互数据是非常昂贵的,

RAG中的3个高级检索技巧

我们介绍的这些检索技术有助于提高文档的相关性。但是这方面的研究还正在进行,还有很多其他方法例如,利用真实反馈数据对嵌入模型进行微调;直接微调LLM以使其检索能力最大化(RA-DIT);探索更复杂的嵌入适配器使用深度神经网络而不是矩阵;深度和智能分块技术作者:Ahmed Besbes。

大数据深度学习卷积神经网络CNN:CNN结构、训练与优化一文全解

卷积神经网络是一种前馈神经网络,它的人工神经元可以响应周围单元的局部区域,从而能够识别视觉空间的部分结构特征。卷积层: 通过卷积操作检测图像的局部特征。激活函数: 引入非线性,增加模型的表达能力。池化层: 减少特征维度,增加模型的鲁棒性。全连接层: 在处理空间特征后,全连接层用于进行分类或回归。卷积神经网络的这些组件协同工作,使得CNN能够从原始像素中自动学习有意义的特征层次结构。随着深度增加,这些特征从基本形状和纹理逐渐抽象为复杂的对象和场景表现。

从虚拟到现实:数字孪生驱动智慧城市可持续发展

同时,我们也需要不断探索和创新数字孪生技术的应用场景和发展方向,为智慧城市的可持续发展提供更加全面和深入的支持。“方案365”2023年全新整理智慧城市、数字孪生、乡村振兴、智慧乡村、元宇宙、数据中台、智慧园区、智慧社区、智慧矿山、城市生命线、智慧水利、智慧应急、智慧校园、智慧工地、智慧农业、智慧文旅、智慧交通等300+行业全套解决方案。通过智能电表和能源管理系统,数字孪生技术可以实现对家庭、企业等各个层面的能源使用情况进行监测和优化,提高能源利用效率,推动城市的绿色发展。

如何使用人工智能优化 DevOps?

DevOps 和人工智能密不可分,影响着各种业务。DevOps 可以加快产品开发速度并简化现有部署的维护,而 AI 则可以改变整个系统的功能。DevOps团队可以依靠人工智能和机器学习来进行数据集成、测试、评估和发布系统。更重要的是,人工智能和机器学习可以以高效、快速、安全的方式改进 DevOps 驱动的流程。从开发人员实用性和业务支持的角度来看, 评估AI和ML在 DevOps 中的重要性对于企业来说是有益的。

人工智能有哪些领域?

像京东自主研发的无人仓采用大量智能物流机器人进行协同与配合,通过人工智能、深度学习、图像智能识别、大数据应用等技术,让工业机器人可以进行自主的判断和行为,完成各种复杂的任务,在商品分拣、运输、出库等环节实现自动化。人工智能在金融领域的应用主要有:智能获客、身份识别、大数据风控、智能投顾、智能客服、金融云等,该行业也是人工智能渗透最早、最全面的行业。目前,我国在ITS方面的应用主要是通过对交通中的车辆流量、行车速度进行采集和分析,可以对交通进行实施监控和调度,有效提高通行能力、简化交通管理、降低环境污染等。

使用LOTR合并检索提高RAG性能

为了解决LIM问题并提高检索性能,对RAG系统进行增强是非常重要的。通过设置不同的VectorStores并将它们与Merge retriver结合,以及使用LongContextReorder重新排列结果,可以减少LIM问题并使检索过程更高效。此外,在合并检索器中合并特定领域的嵌入也有着关键作用。这些步骤对于确保我们不会在检索文件的过程中遗漏重要细节至关重要。Lost in the Middle: How Language Models Use Long Contexts 论文。

【AI】人工智能复兴的推进器之神经网络

神经网络是一种模仿生物神经网络(动物的中枢神经系统,特别是大脑)的结构和功能的数学模型或计算模型,用于对函数进行估计或近似。神经网络由大量节点(或神经元)相互关联构成,每两个节点间的连接都代表一个对于通过该连接信号的加权值,称之为权重,这可以看作人工神经元的记忆。网络的输出则依网络的连接方式,权重值和激励函数的不同而不同。而网络自身通常都是对自然界某种算法或者函数的逼近,也可能是对一种逻辑策略的表达。此外,根据网络的结构和运行方式,神经网络可以分为前馈神经网络和反馈神经网络。

目标检测与测距算法在极端天气下的应用

在现代社会中,极端天气条件对人们的生活和工作带来了很大的挑战。对于一些特定领域,如交通运输、安全监控等,准确的目标检测与测距算法在极端天气下尤为重要。本文将分点概述极端天气下目标检测与测距算法的关键问题及解决办法。

AI时代架构设计新模式

本书是一本旨在帮助架构师在人工智能时代展翅高飞的实用指南。全书以ChatGPT为核心工具,揭示了人工智能技术对架构师的角色和职责进行颠覆和重塑的关键点。本书通过共计 13 章的系统内容,深入探讨AI技术在架构设计中的应用,以及AI对传统架构师工作方式的影响。通过学习,读者将了解如何利用ChatGPT这一强大的智能辅助工具,提升架构师的工作效率和创造力。本书的读者主要是架构师及相关从业人员。

深度解析 PyTorch Autograd:从原理到实践

本文深入探讨了 PyTorch 中 Autograd 的核心原理和功能。从基本概念、Tensor 与 Autograd 的交互,到计算图的构建和管理,再到反向传播和梯度计算的细节,最后涵盖了 Autograd 的高级特性。

AIGC实战——WGAN(Wasserstein GAN)

在本节中,我们学习了如何使用 Wasserstein 损失函数以解决经典 GAN 训练过程中的模式坍塌和梯度消失等问题,使得 GAN 的训练更加可预测和可靠。WGAN-GP 通过在损失函数中添加一个令梯度范数指向 1 的项,为训练过程施加 1-Lipschitz 约束。

ChatGPT的常识

ChatGPT不仅可以提供高效的服务,还可以通过模拟人类对话和表情,提高人机交互的趣味性和友好性。其次,ChatGPT可以实现个性化服务,根据用户的个性化需求和反馈不断优化和改进。用户在与ChatGPT进行交互的过程中,ChatGPT可以对用户的个性化需求进行识别和记录,从而实现个性化的服务。ChatGPT的设计理念是建立一个可以持续学习和更新的聊天机器人,可以不断地根据用户的反馈和互动进行优化和改进。同时,ChatGPT还具有很强的适应性和灵活性,可以应对不同场景和话题的要求。

人工智能时代:AIGC的横空出世

AIGC是一种新的人工智能技术,即人工智能生成内容。它是一种基于机器学习和自然语言处理的技术,能够自动产生文本、图像、音频等多种类型的内容。

【图像处理】使用各向异性滤波器和分割图像处理从MRI图像检测脑肿瘤(Matlab代码实现)

脑肿瘤是一种致命的疾病,没有MRI技术,无法可靠地检测到。为了为MRI图像的形态学操作铺平道路,我们首先使用各向异性扩散滤波器对图像进行滤波,以降低像素之间的对比度。然后,我们调整图像大小,并手动将其转换为黑白图像,通过阈值处理来初步筛选出肿瘤可能存在的区域。这个项目的更大目标是建立一个包含从不同角度拍摄的特定人类MRI图像中的肿瘤2D图像数据的数据库,并通过对这些图像进行分析来确定肿瘤的精确3D位置。尽管这个模拟程序在大多数情况下可以给出准确的结果,但对于过小的肿瘤或具有中空结构的肿瘤,它可能无法执行。
返回
顶部