import sys
from PyQt5.QtWidgets import (QWidget, QPushButton,
QHBoxLayout, QVBoxLayout, QApplication, QLabel,
QFileDialog, QMessageBox, QRadioButton, QFrame)
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import QTimer, Qt
import cv2
import os
from model import PredictModel
class MainGUI(QWidget):
def __init__(self):
super().__init__()
self.windows_title = "目标检测GUI"
self.camera_stat = False # 摄像头默认关闭
self.cap = None # 视频或者摄像头
self.export_cap = None # 导出的视频
self.fname = None # 图片或者视频路径
self.init_ui()
self.init_timer()
self.predictor = PredictModel()
def init_ui(self):
h_layout = QHBoxLayout()
# 第一列布局,显示窗口 选择图片/视频按钮 打开摄像头按钮
v1_layout = QVBoxLayout()
v1_h1_layout = QHBoxLayout()
self.display_label = QLabel()
self.display_label.setMinimumHeight(300)
self.display_label.setMinimumWidth(400)
self.display_label.setStyleSheet("border: 1px dashed")
v1_h1_layout.addWidget(self.display_label)
v1_layout.addLayout(v1_h1_layout)
v1_h2_layout = QHBoxLayout()
v1_h2_layout.addStretch(1)
self.image_btn = QPushButton("选择图片/视频")
self.image_btn.clicked.connect(self.select_file)
v1_h2_layout.addWidget(self.image_btn)
v1_h2_layout.addStretch(1)
self.camera_btn = QPushButton("打开/关闭摄像头")
self.camera_btn.clicked.connect(self.open_camera)
v1_h2_layout.addWidget(self.camera_btn)
v1_h2_layout.addStretch(1)
v1_layout.addLayout(v1_h2_layout)
v1_frame = QFrame()
# v1_frame.setStyleSheet("border: 1px dashed; border-color: (100, 100, 100);")
v1_frame.setFrameStyle(QFrame.Panel|QFrame.Sunken)
v1_frame.setLayout(v1_layout)
# 第二列 显示检测结果
v2_layout = QVBoxLayout()
dis_frame = QFrame()
dis_frame.setFrameStyle(QFrame.Panel|QFrame.Sunken)
dis_frame.setFixedHeight(50)
dis_layout = QHBoxLayout()
self.display_detected_img_btn = QRadioButton("显示检测结果")
self.display_detected_img_btn.setStyleSheet("border: 1px dashed")
self.display_detected_img_btn.setChecked(True)
dis_layout.addWidget(self.display_detected_img_btn)
dis_frame.setLayout(dis_layout)
v2_layout.addWidget(dis_frame)
export_frame = QFrame()
export_frame.setFixedHeight(120)
export_frame.setFrameStyle(QFrame.Panel|QFrame.Sunken)
export_layout = QVBoxLayout()
self.export_btn = QRadioButton("导出检测结果")
self.export_btn.setStyleSheet("border: 1px dashed")
self.export_btn.setChecked(True)
export_layout.addWidget(self.export_btn)
self.export_path_btn = QPushButton("选择导出路径")
self.export_path_btn.setChecked(True)
self.export_path_btn.clicked.connect(self.select_export_path)
export_layout.addWidget(self.export_path_btn)
default_export_path = os.path.join(os.getcwd(), 'outputs')
os.makedirs(default_export_path, exist_ok=True)
self.export_label = QLabel(default_export_path)
self.export_label.setFixedHeight(20)
self.export_label.setStyleSheet("border: 1px dashed; border-color: (100, 100, 100);")
export_layout.addWidget(self.export_label)
export_frame.setLayout(export_layout)
v2_layout.addWidget(export_frame)
self.info_label = QLabel()
self.info_label.setStyleSheet("border: 1px dashed")
v2_layout.addWidget(self.info_label)
v2_frame = QFrame()
# v2_frame.setStyleSheet("border: 1px dashed; border-color: (100, 100, 100);")
v2_frame.setFrameStyle(QFrame.Panel|QFrame.Sunken)
v2_frame.setLayout(v2_layout)
h_layout.addWidget(v1_frame)
h_layout.addWidget(v2_frame)
self.setLayout(h_layout)
self.setWindowTitle(self.windows_title)
# self.setGeometry(300, 300, 500, 500)
self.show()
def select_export_path(self):
directory = QFileDialog.getExistingDirectory(None, "选择导出文件路径", "./")
self.export_label.setText(directory)
return directory
def select_file(self):
# 仅允许选择一个文件
self.fname, _ =QFileDialog.getOpenFileName(self,'打开文件', "./", "Files(*.jpg *.bmp *.png *.jpeg *.mp4 *.avi)")
if self.fname == '':
return
if self.fname.endswith(('png', 'bmp', 'jpg', 'jpeg')):
self.show_single_frame(self.fname)
self.fname = None # 清空路径
else:
self.cap = cv2.VideoCapture(self.fname)
if not self.cap.isOpened():
QMessageBox.information(self, "警告", "视频异常!", QMessageBox.Ok)
self.cap = None
return
self.display_label.setEnabled(True)
self.timer.start() # 清空路径放在定时器
print("beginning!") #
def open_camera(self):
if self.camera_stat:
self.camera_stat = not self.camera_stat
self.close_camera()
return
self.cap = cv2.VideoCapture(0)
if not self.cap.isOpened():
QMessageBox.information(self, "警告", "摄像头开启失败!", QMessageBox.Ok)
self.cap = None
else:
self.camera_stat = True
# 幕布可以播放
self.display_label.setEnabled(True)
self.timer.start()
print("beginning!")
def close_camera(self):
self.cap.release()
self.cap = None
self.timer.stop()
if self.export_cap != None: # 清空导出视频
self.export_cap.release()
self.export_cap = None
self.fname = None
# 播放视频画面
def init_timer(self):
self.timer = QTimer(self)
self.timer.timeout.connect(self.show_pic)
# 显示视频图像
def show_pic(self):
ret, img = self.cap.read()
if ret:
self.show_single_frame(img)
def show_single_frame(self, img):
image_path = None
if isinstance(img, str):
image_path = img
img = cv2.imread(img)
##################################################det#####################################################
result, det_img, names, cls_info = self.predictor(img)
txt = ''
print(names, cls_info)
for k in names.keys():
name = names[k]
if k in cls_info.keys():
count = cls_info[k]
txt += name + ': ' + str(count) + '\n'
else:
txt += name + ': ' + '0' + '\n'
self.info_label.setText(txt)
if self.display_detected_img_btn.isChecked():
img = det_img
if self.export_btn.isChecked():
if image_path is not None: # 检测的是图片
image_name = os.path.basename(image_path)
out_path = os.path.join(self.export_label.text(), image_name)
cv2.imwrite(out_path, det_img)
else: # 检测的是摄像头或者视频
if self.export_cap is None:
fourcc = cv2.VideoWriter_fourcc(*'XVID')
if self.fname is not None:
video_name = os.path.basename(self.fname)
if 'mp4' in video_name:
video_name = video_name.replace('mp4', 'avi')
print(video_name)
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
基于yolov8的口罩检测系统,包含使用yolov8训练好的模型权重,使用pyqt开发的显示界面,支持图片、视频、摄像头输入 相关说明: 1、本资源包含yolov8在口罩数据集上的训练权重,包含best.pt和last.pt两个权重; 2、本资源包含yolov8的口罩检测推理代码,可以根据推理代码快速实现口罩数量计数推理; 3、本资源包含的内容介绍如博客:https://blog.csdn.net/qq_40035462/article/details/135568325 所示; 4、本资源包含GUI界面,该GUI界面支持图片检测、视频检测、摄像头检测; 5、该GUI支持导出检测结果到指定的文件目录下; 6、该代码使用pyqt、ultralystic开发,需要安装相关依赖,建议使用conda虚拟环境; 7、该代码提供售后服务,如果您在使用中遇到任何问题,可以联系压缩包中的联系方式; 8、售后服务包含:代码安装、代码跑通、环境搭建、使用教学,不包含功能修改; 9、修改代码可能需要额外付费,价格根据具体的功能需求制定; 10、代码有任何问题,可以直接联系作者,确保您能跑通。
资源推荐
资源详情
资源评论
收起资源包目录
基于yolov8的口罩检测系统.zip (6个子文件)
gui.py 9KB
weights
best.pt 5.97MB
last.pt 5.97MB
model.py 983B
148.jpg 102KB
138.jpg 78KB
共 6 条
- 1
资源评论
- 亦逍遥2024-02-29怎么能有这么好的资源!只能用感激涕零来形容TAT...
justld
- 粉丝: 1w+
- 资源: 77
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功