本次yolov8可视化界面Ui相较之前文章中的界面进行了部分改动,比较明显的改动为本文使用的yolov8版本为8.2.0,有了较新的范围内统计目标数量的功能(目前还没整合进来,后续更新),且分为左右两个区域分别显示原始图像和处理后的图像,还可以分别对图片,视频,摄像头以及云ip摄像头分别进行识别并展示,本文仅针对图像处理做出代码示例,所有代码只需要在根目录下新建一个ui.py即可正常运行,无需新建过多的文件,对于视频及摄像头处理可以根据图像处理进行修改后实现功能,或者私聊我获取成品。
目录
1.准备工作
1.1 yolov8(Ultralytics)源码获取
源代码文件获取请查看之前文章,或者点此链接下载,压缩包内为整合源码及权重文件夹。
yolov8官方地址为 GitHub - ultralytics/ultralytics: Ultralytics YOLO11 🚀 ,建议下载yolov8 8.2.0版本源码。
1.2 yolov8环境配置
环境异常请根据下文配置相应python环境,再尝试使用本文提供的可视化界面
建议使用Anaconda3+pycharm,下载yolov8 8.2.0版本源码。
2.完整界面展示
2.1 主界面展示
界面整体分为三部分,左右图像展示框以及下方功能按钮,下图为运行后界面展示
2.2 功能展示
首先选择模型,选择完之后可以分别进行图片或者视频或者打开摄像头进行实时检测,检测之后的图像会实时显示在界面上,左边显示原始图像,右边显示检测后的图像
也可以选择视频进行检测,效果如下图(显示检测物体没录制上)
点击显示检测物体即可显示出当前检测到的所有物体
3.界面实现
本文仅对图片检测进行展示,如需其它功能界面请私聊获取。
3.1 相关库
除了yolov8所用库之外,本文所用到的额外库为pyqt5,输入指令进行安装
pip install PyQt5
3.2 导入库
我这里导入的是以下这些,同官方源码兼容。
import sys
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QPushButton, QHBoxLayout, QMessageBox, QFileDialog
from PyQt5.QtGui import QImage, QPixmap,QIcon
import cv2
from ultralytics import YOLO
3.3 功能实现
3.3.1 添加按钮
这里只实现了简单的权重选择和图片检测功能并添加了对应的按钮
# 添加模型选择按钮
self.load_model_button = QPushButton("📁模型选择")
self.load_model_button.clicked.connect(self.load_model)
self.load_model_button.setFixedSize(120, 30)
hbox_buttons.addWidget(self.load_model_button)
# 添加图片检测按钮
self.image_detect_button = QPushButton("💾图片检测")
self.image_detect_button.clicked.connect(self.detect_image)
self.image_detect_button.setEnabled(False)
self.image_detect_button.setFixedSize(120, 30)
hbox_buttons.addWidget(self.image_detect_button)
# 添加显示检测物体按钮
self.display_objects_button = QPushButton("🔍显示检测物体")
self.display_objects_button.clicked.connect(self.show_detected_objects)
self.display_objects_button.setEnabled(False)
self.display_objects_button.setFixedSize(120, 30)
hbox_buttons.addWidget(self.display_objects_button)
# 添加退出按钮
self.exit_button = QPushButton("❌退出")
self.exit_button.clicked.connect(self.exit_application)
self.exit_button.setFixedSize(120, 30)
hbox_buttons.addWidget(self.exit_button)
3.3.2 功能函数定义
检测图片并分别在左右窗口进行显示
def detect_image(self):
image_path, _ = QFileDialog.getOpenFileName(None, "选择图片文件", "", "图片文件 (*.jpg *.jpeg *.png)")
if image_path:
image = cv2.imread(image_path)
if image is not None:
self.current_results = self.worker.detect_image(image)
if self.current_results:
annotated_image = self.current_results[0].plot()
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 转换为 RGB
height1, width1, channel1 = image_rgb.shape
bytesPerLine1 = 3 * width1
qimage1 = QImage(image_rgb.data, width1, height1, bytesPerLine1, QImage.Format_RGB888)
pixmap1 = QPixmap.fromImage(qimage1)
self.label1.setPixmap(pixmap1.scaled(self.label1.size(), Qt.KeepAspectRatio))
annotated_image = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB) # 转换为 RGB
height2, width2, channel2 = annotated_image.shape
bytesPerLine2 = 3 * width2
qimage2 = QImage(annotated_image.data, width2, height2, bytesPerLine2, QImage.Format_RGB888)
pixmap2 = QPixmap.fromImage(qimage2)
self.label2.setPixmap(pixmap2.scaled(self.label2.size(), Qt.KeepAspectRatio))
加载模型及调用部分代码
def load_model(self):
model_path, _ = QFileDialog.getOpenFileName(None, "选择模型文件", "", "模型文件 (*.pt)")
if model_path:
self.model = YOLO(model_path)
return self.model is not None
return False
def detect_image(self, image):
results = self.model.predict(image)
return results
3.3.3 完整代码
完整代码如下,全部复制后粘贴进一个空白的py文件即可运行
import sys
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QPushButton, QHBoxLayout, QMessageBox, QFileDialog
from PyQt5.QtGui import QImage, QPixmap, QIcon
import cv2
from ultralytics import YOLO
class Worker:
def __init__(self):
self.model = None
def load_model(self):
model_path, _ = QFileDialog.getOpenFileName(None, "选择模型文件", "", "模型文件 (*.pt)")
if model_path:
self.model = YOLO(model_path)
return self.model is not None
return False
def detect_image(self, image):
results = self.model.predict(image)
return results
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("@author:笑脸惹桃花")
#self.setWindowIcon(QIcon("icon.png"))
self.setGeometry(300, 150, 800, 400)
# 创建两个 QLabel 分别显示左右图像
self.label1 = QLabel()
self.label1.setAlignment(Qt.AlignCenter)
self.label1.setMinimumSize(580, 450) # 设置大小
self.label1.setStyleSheet('border:3px solid #6950a1; background-color: black;') # 添加边框并设置背景颜色为黑色
self.label2 = QLabel()
self.label2.setAlignment(Qt.AlignCenter)
self.label2.setMinimumSize(580, 450) # 设置大小
self.label2.setStyleSheet('border:3px solid #6950a1; background-color: black;') # 添加边框并设置背景颜色为黑色
# 水平布局,用于放置左右两个 QLabel
layout = QVBoxLayout()
# layout.addWidget(self.label1)
hbox_video = QHBoxLayout()
hbox_video.addWidget(self.label1) # 左侧显示原始图像
hbox_video.addWidget(self.label2) # 右侧显示检测后的图像
layout.addLayout(hbox_video)
self.worker = Worker()
# 创建按钮布局
hbox_buttons = QHBoxLayout()
# 添加模型选择按钮
self.load_model_button = QPushButton("📁模型选择")
self.load_model_button.clicked.connect(self.load_model)
self.load_model_button.setFixedSize(120, 30)
hbox_buttons.addWidget(self.load_model_button)
# 添加图片检测按钮
self.image_detect_button = QPushButton("💾图片检测")
self.image_detect_button.clicked.connect(self.detect_image)
self.image_detect_button.setEnabled(False)
self.image_detect_button.setFixedSize(120, 30)
hbox_buttons.addWidget(self.image_detect_button)
# 添加显示检测物体按钮
self.display_objects_button = QPushButton("🔍显示检测物体")
self.display_objects_button.clicked.connect(self.show_detected_objects)
self.display_objects_button.setEnabled(False)
self.display_objects_button.setFixedSize(120, 30)
hbox_buttons.addWidget(self.display_objects_button)
# 添加退出按钮
self.exit_button = QPushButton("❌退出")
self.exit_button.clicked.connect(self.exit_application)
self.exit_button.setFixedSize(120, 30)
hbox_buttons.addWidget(self.exit_button)
layout.addLayout(hbox_buttons)
central_widget = QWidget()
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
self.current_results = None
def detect_image(self):
image_path, _ = QFileDialog.getOpenFileName(None, "选择图片文件", "", "图片文件 (*.jpg *.jpeg *.png)")
if image_path:
image = cv2.imread(image_path)
if image is not None:
self.current_results = self.worker.detect_image(image)
if self.current_results:
annotated_image = self.current_results[0].plot()
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 转换为 RGB
height1, width1, channel1 = image_rgb.shape
bytesPerLine1 = 3 * width1
qimage1 = QImage(image_rgb.data, width1, height1, bytesPerLine1, QImage.Format_RGB888)
pixmap1 = QPixmap.fromImage(qimage1)
self.label1.setPixmap(pixmap1.scaled(self.label1.size(), Qt.KeepAspectRatio))
annotated_image = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB) # 转换为 RGB
height2, width2, channel2 = annotated_image.shape
bytesPerLine2 = 3 * width2
qimage2 = QImage(annotated_image.data, width2, height2, bytesPerLine2, QImage.Format_RGB888)
pixmap2 = QPixmap.fromImage(qimage2)
self.label2.setPixmap(pixmap2.scaled(self.label2.size(), Qt.KeepAspectRatio))
def show_detected_objects(self):
if self.current_results:
det_info = self.current_results[0].boxes.cls
object_count = len(det_info)
object_info = f"识别到的物体总个数:{object_count}\n"
object_dict = {}
class_names_dict = self.current_results[0].names
for class_id in det_info:
class_name = class_names_dict[int(class_id)]
if class_name in object_dict:
object_dict[class_name] += 1
else:
object_dict[class_name] = 1
sorted_objects = sorted(object_dict.items(), key=lambda x: x[1], reverse=True)
for obj_name, obj_count in sorted_objects:
object_info += f"{obj_name}: {obj_count}\n"
self.show_message_box("识别结果", object_info)
else:
self.show_message_box("识别结果", "未检测到物体")
def show_message_box(self, title, message):
msg_box = QMessageBox(self)
msg_box.setWindowTitle(title)
msg_box.setText(message)
msg_box.exec_()
def load_model(self):
if self.worker.load_model():
self.image_detect_button.setEnabled(True)
self.display_objects_button.setEnabled(True)
def exit_application(self):
# 终止程序运行
sys.exit()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
3.4 界面展示
这样一个简单的ui界面就写好了
需要更加复杂更多功能的及其他需求可以私聊,遇到报错可以在评论区交流~