YOLOV8 + PYQT5单目测距—风险类别检测(五)

35 篇文章 23 订阅
14 篇文章 5 订阅

1. 相关配置

系统:win 10
YOLO版本:yolov8
拍摄视频设备:安卓手机
电脑显卡:NVIDIA 2080Ti(CPU也可以跑,GPU只是起到加速推理效果)

2. 测距源码

详见文章 YOLOv8跟踪分割+单目测距(python),下载源码后进入下一步

3. PYQT环境配置

首先安装一下pyqt5

pip install PyQt5
pip install PyQt5-tools

接着再pycharm设置里配置一下
请添加图片描述
添加下面两个工具:
工具1:Qt Designer

Program D:\Anaconda3\Lib\site-packages\qt5_applications\Qt\bin\designer.exe#代码所用环境路径
Arauments : $FileName$
Working directory :$FileDir$

请添加图片描述
工具2:PyUIC

Program D:\Anaconda3\Scripts\pyuic5.exe 
Arguments : $FileName$ -o $FileNameWithoutExtension$.py
Working directory :$FileDir$

请添加图片描述

4. 实验结果

4.1 界面

创建一个main.py文件,将以下代码写入

import sys

import torch
import torchvision
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QLabel
from PyQt5 import QtCore, QtGui, QtWidgets
import cv2
from ultralytics import YOLO
from distance import person_distance,car_distance
class Ui_MainWindow(QMainWindow):
    # global text_dis
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.retranslateUi(self)
        self.image_path = ''
        self.label = QLabel(self)
        self.label.setGeometry(50, 50, 200, 50)
        # self.text_dis = None
        # 创建一个QTextBrowser来显示变量值
        self.text_browser = QtWidgets.QTextBrowser(self.centralwidget)
        # 添加QTextBrowser到窗口的布局中
        self.setCentralWidget(self.text_browser)

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1128, 1009)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(20, 10, 93, 28))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(160, 10, 93, 28))
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(290, 10, 93, 28))
        self.pushButton_3.setObjectName("pushButton_3")

        self.label = QtWidgets.QTextBrowser(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(420, 10, 93, 28))
        self.label.setObjectName("label")


        self.label1 = QtWidgets.QTextBrowser(self.centralwidget)
        self.label1.setGeometry(QtCore.QRect(20, 60, 1071, 71))
        self.label1.setObjectName("label1")
        self.label2 = QtWidgets.QLabel(self.centralwidget)
        self.label2.setGeometry(QtCore.QRect(40, 190, 481, 421))
        self.label2.setObjectName("label2")
        self.label3 = QtWidgets.QLabel(self.centralwidget)
        self.label3.setGeometry(QtCore.QRect(600, 200, 461, 381))
        self.label3.setObjectName("label3")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1128, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        # 点击响应函数
        self.pushButton.clicked.connect(self.uploadImage)
        self.pushButton_2.clicked.connect(self.showEnvironment)
        self.pushButton_3.clicked.connect(self.startProgram)
        # self.image_path = ''

    def retranslateUi(self, MainWindow):# 设置界面各个组件的文本内容。
        # text_dis = ''
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "上传文件"))
        self.pushButton_2.setText(_translate("MainWindow", "终止运行"))
        self.pushButton_3.setText(_translate("MainWindow", "启动程序"))

        # self.label.setText(_translate("MainWindow", "{}".format(text_dis)))
        self.label2.setText(_translate("MainWindow", "CSDN:积极向上的Mr.d"))
        self.label3.setText(_translate("MainWindow", "CSDN:积极向上的Mr.d"))

    def showEnvironment(self):    # 退出
        sys.exit()


    def uploadImage(self):
            file_dialog = QFileDialog()
            image_path, _ = file_dialog.getOpenFileName(self, '选择图片', '', 'Images (*.png *.xpm *.jpg *.bmp *.mp4)')
            self.image_path = image_path
            if image_path:
                pixmap = QtGui.QPixmap(image_path)
                self.label2.setPixmap(pixmap)
                self.label2.setScaledContents(True)
                # 加载图片的逻辑保持不变

    # global text_dis
    def startProgram(self):
        text_dis_list = []  # 用于存储每次循环中的 text_dis 值
        if self.image_path.endswith('.mp4'):
            # 如果是视频文件,使用视频流而不是单个图像
            cap = cv2.VideoCapture(self.image_path)
            frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
            frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            fps = int(cap.get(cv2.CAP_PROP_FPS))
            out = cv2.VideoWriter('result.mp4', cv2.VideoWriter_fourcc(*'mp4v'), fps, (frame_width, frame_height))
            model = YOLO('yolov8n.pt')

            while True:
                ret, frame = cap.read()
                if not ret:
                    break

                # 对每一帧运行对象检测
                results = model(frame)
                annotated_frame = results[0].plot()
                boxes = results[0].boxes.xywh.cpu()
                for i, box in enumerate(boxes):
                    # for box, class_idx in zip(boxes, classes):
                    x_center, y_center, width, height = box.tolist()
                    x1 = x_center - width / 2
                    y1 = y_center - height / 2
                    x2 = x_center + width / 2
                    y2 = y_center + height / 2
                    h = y2 - y1
                    dis_m = person_distance(h)
                  
                    text_dis_list.append(dis_m)
                    max_dis_m = min(text_dis_list)
                    # global text_dis
                    if max_dis_m < 2:
                        text_dis = '高风险'
                    elif max_dis_m > 5:
                        text_dis = '低风险'
                    else:
                        text_dis = '中风险'
                # text_dis_list.append(text_dis)
                    self.label.setText(text_dis)
                # 将检测结果写入输出视频流
                out.write(annotated_frame)
                # 将结果显示在label3中(可选)
                rgb_annotated_frame = cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB)
                # 使用QImage将RGB图像转换为Qt格式
                height, width, channel = rgb_annotated_frame.shape
                bytes_per_line = channel * width
                q_img = QImage(rgb_annotated_frame.data, width, height, bytes_per_line, QImage.Format_RGB888)
                # 将QImage转换为QPixmap并显示在label3中
                pixmap = QPixmap.fromImage(q_img)
                # pixmap = QtGui.QPixmap.fromImage(QtGui.QImage(annotated_frame.data, annotated_frame.shape[1], annotated_frame.shape[0], QtGui.QImage.Format_RGB888))
                self.label3.setPixmap(pixmap)
                self.label3.setScaledContents(True)

                cv2.waitKey(1)

            cap.release()
            out.release()

        else:
            # 如果是单个图像文件,保持原始逻辑不变
            self.label1.setText(self.image_path)
            model = YOLO('yolov8n.pt')
            results = model(self.image_path)
            annotated_frame = results[0].plot()
            boxes = results[0].boxes.xywh.cpu()
            for i, box in enumerate(boxes):
                # for box, class_idx in zip(boxes, classes):
                x_center, y_center, width, height = box.tolist()
                x1 = x_center - width / 2
                y1 = y_center - height / 2
                x2 = x_center + width / 2
                y2 = y_center + height / 2
                h = y2 - y1
                dis_m = person_distance(h)
                if dis_m < 2:
                    text_dis = '高风险'
                elif dis_m > 5:
                    text_dis = '低风险'
                else:
                    text_dis = '中风险'
                self.label.setText(text_dis)
            cv2.imwrite("result.jpg",annotated_frame)
            pixmap = QtGui.QPixmap("result.jpg")
            self.label3.setPixmap(pixmap)
            self.label3.setScaledContents(True)
        return text_dis



if __name__ == '__main__':
    app = QApplication(sys.argv)
    MainWindow1 = QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow1)
    MainWindow1.show()
    sys.exit(app.exec_())

4.2 界面卡住解决方案

如果点击图片检测或者视频检测按钮卡住,大概律师代码中间出现了错误,这时候是看不到报错的,具体可以把以下这个功能打开,这样就可以看到报错
请添加图片描述
请添加图片描述

5. 实现效果

显示界面
请添加图片描述
检测图片
请添加图片描述
检测视频
请添加图片描述

工程源码下载:YOLOV8 + PYQT5单目测距(风险类别检测)
解压密码:csdn:mr.d

文章内容后续会慢慢完善…

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积极向上的mr.d

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值