本文的可视化界面对于YOLOv11/Ultralytics/YOLOv8的检测、分割、分类、姿势估算(detection, segmentation, obb, classification, and pose estimation)等均可正常显示。本次新增了图片及视频的保存,可以选择传入文件夹进行检测并显示,可以对本地摄像头或者云摄像头获取的视频进行分段保存,本文仅针对图像处理部分给出代码示例,所有代码只需要在根目录下新建一个main.py即可正常运行,对于视频及摄像头处理可以根据图像处理进行修改后实现功能,或者私聊我获取成品,之前购买过的可私信我免费获取最新的代码。
目录
1.准备工作
1.1 YOLOv11(Ultralytics)源码获取
1.2 YOLOv11环境配置
2.完整界面展示
2.1 主界面展示
2.2 功能展示
2.3 完整功能展示
3.界面实现
3.1 相关库
3.2 导入库
3.3 功能实现
3.3.1 添加按钮
3.3.2 功能函数定义
3.3.3 完整代码
3.4 界面展示
1.准备工作
1.1 YOLOv11(Ultralytics)源码获取
源代码文件获取请查看之前文章,或者点此下载,压缩包内为整合源码及权重文件夹。
YOLOv11官方地址为
https://github.com/ultralytics/ultralytics
1.2 YOLOv11环境配置
环境异常请根据下文配置相应python环境,再尝试使用本文提供的可视化界面
目标检测:YOLOv11(Ultralytics)环境配置,适合0基础纯小白,超详细-CSDN博客文章浏览阅读4k次,点赞28次,收藏67次。YOLO11是Ultralytics公司YOLO系列实时目标检测器的最新迭代版本,它以尖端的准确性、速度和效率重新定义了可能实现的性能。在之前YOLO版本取得的显著进步基础上,YOLO11在架构和训练方法上进行了重大改进,使其成为各种计算机视觉任务中的通用选择。除了传统的目标检测外,YOLO11 还支持目标跟踪、实例分割、姿态估计、OBB定向物体检测(旋转目标检测)等视觉任务。如果已经会配置YOLOv8的环境,本文不需要重复配置,下载最新的YOLOv11训练文件即可。_yolov11https://blog.csdn.net/qq_67105081/article/details/143270109?spm=1001.2014.3001.5502建议使用Anaconda3+pycharm,下载8.3.20版本源码。
2.完整界面展示
2.1 主界面展示
界面整体分为三部分,左右图像展示框以及下方功能按钮,下图为运行后界面展示
2.2 功能展示
首先选择模型,选择完之后可以分别点击图片检测选择单张图片检测后显示在界面上,可点击保存到指定位置,点击文件夹检测可以选择一个文件夹后将其按照一定的速度展示,文件夹检测会将检测结果自动保存,视频检测完可以选择保存视频,也可以在检测过程中将视频分段保存,摄像头可选本地和云摄像头,本地会自动获取摄像头编号可选择,云摄像头则需要输入ip后开始检测,均可点击保存为视频。检测之后的图像会实时显示在界面上,左边显示原始图像,右边显示检测后的图像。
也可以选择视频进行检测,效果如下图,可以点击查看当前检测到的所有物体
2.3 完整功能展示
每个按钮的功能及云摄像头的调用都试了一下,效果如下图
有其它需求可私信联系定制。
3.界面实现
本文仅对图片检测进行展示,如需其它功能界面请私聊获取。
3.1 相关库
除了yolov8所用库之外,本文所用到的额外库为pyqt5,输入指令进行安装
pip install PyQt5
3.2 导入库
我这里导入的是以下这些,同官方源码兼容。
import sys
import os
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QPushButton, QHBoxLayout, QFileDialog, QMessageBox
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.select_image)
self.image_detect_button.setEnabled(False)
self.image_detect_button.setFixedSize(120, 30)
hbox_buttons.addWidget(self.image_detect_button)# 添加图片文件夹检测按钮
self.folder_detect_button = QPushButton("️📁文件夹检测")
self.folder_detect_button.clicked.connect(self.detect_folder)
self.folder_detect_button.setEnabled(False)
self.folder_detect_button.setFixedSize(120, 30)
hbox_buttons.addWidget(self.folder_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.save_button = QPushButton("💾保存检测结果")
self.save_button.clicked.connect(self.save_detection)
self.save_button.setEnabled(False)
self.save_button.setFixedSize(120, 30)
hbox_buttons.addWidget(self.save_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):if image_path:print(image_path)image = cv2.imread(image_path)if image is not None:if self.flag == 0:results = self.worker.model.predict(image)elif self.flag == 1:results = self.worker.model.predict(image_path, save=True)self.worker.detection_type = "image"if results:self.current_results = resultsself.worker.current_annotated_image = results[0].plot()annotated_image = self.worker.current_annotated_imageimage_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)height1, width1, channel1 = image_rgb.shapebytesPerLine1 = 3 * width1qimage1 = 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)height2, width2, channel2 = annotated_image.shapebytesPerLine2 = 3 * width2qimage2 = QImage(annotated_image.data, width2, height2, bytesPerLine2, QImage.Format_RGB888)pixmap2 = QPixmap.fromImage(qimage2)self.label2.setPixmap(pixmap2.scaled(self.label2.size(), Qt.KeepAspectRatio))self.save_button.setEnabled(True)
加载模型部分代码
def load_model(self):model_path, _ = QFileDialog.getOpenFileName(None, "选择模型文件", "", "模型文件 (*.pt)")if model_path:self.model = YOLO(model_path)return self.model is not Nonereturn False
选择图片/文件夹部分代码
def select_image(self):image_path, _ = QFileDialog.getOpenFileName(None, "选择图片文件", "", "图片文件 (*.jpg *.jpeg *.png)")self.flag = 0if image_path:self.detect_image(image_path)def detect_folder(self):folder_path = QFileDialog.getExistingDirectory(self, "选择图片文件夹")self.flag = 1if folder_path:image_paths = []for filename in os.listdir(folder_path):if filename.lower().endswith((".jpg", ".jpeg", ".png")):image_path = os.path.join(folder_path, filename)image_paths.append(image_path)for image_path in image_paths:self.detect_image(image_path)
3.3.3 完整代码
完整代码如下,全部复制后粘贴进一个空白的py文件即可运行,想要调整文件夹下图片切换速度可以修改 cv2.waitKey(300) 的参数,1秒为1000
import sys
import os
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QPushButton, QHBoxLayout, QFileDialog, QMessageBox
from PyQt5.QtGui import QImage, QPixmap, QIcon
import cv2
from ultralytics import YOLOclass Worker:def __init__(self):self.model = Noneself.current_annotated_image = Noneself.detection_type = Nonedef load_model(self):model_path, _ = QFileDialog.getOpenFileName(None, "选择模型文件", "", "模型文件 (*.pt)")if model_path:self.model = YOLO(model_path)if self.model:return Trueelse:return Falsedef detect_objects(self, frame):det_info = []class_ids = frame[0].boxes.clsclass_names_dict = frame[0].namesfor class_id in class_ids:class_name = class_names_dict[int(class_id)]det_info.append(class_name)return det_infodef save_image(self, image):if image is not None:file_name, _ = QFileDialog.getSaveFileName(None, "保存图片", "", "JPEG (*.jpg);;PNG (*.png);;All Files (*)")if file_name:cv2.imwrite(file_name, image)class MainWindow(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("@author:笑脸惹桃花")#self.setWindowIcon(QIcon("icon.png"))self.setGeometry(300, 150, 1200, 600)# 创建两个 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;') # 添加边框并设置背景颜色为黑色# 水平布局,用于放置左右两个 QLabellayout = QVBoxLayout()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.select_image)self.image_detect_button.setEnabled(False)self.image_detect_button.setFixedSize(120, 30)hbox_buttons.addWidget(self.image_detect_button)# 添加图片文件夹检测按钮self.folder_detect_button = QPushButton("️📁文件夹检测")self.folder_detect_button.clicked.connect(self.detect_folder)self.folder_detect_button.setEnabled(False)self.folder_detect_button.setFixedSize(120, 30)hbox_buttons.addWidget(self.folder_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.save_button = QPushButton("💾保存检测结果")self.save_button.clicked.connect(self.save_detection)self.save_button.setEnabled(False)self.save_button.setFixedSize(120, 30)hbox_buttons.addWidget(self.save_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)def save_detection(self):detection_type = self.worker.detection_typeif detection_type == "image":self.save_detection_results()def select_image(self):image_path, _ = QFileDialog.getOpenFileName(None, "选择图片文件", "", "图片文件 (*.jpg *.jpeg *.png)")self.flag = 0if image_path:self.detect_image(image_path)def detect_folder(self):folder_path = QFileDialog.getExistingDirectory(self, "选择图片文件夹")self.flag = 1if folder_path:image_paths = []for filename in os.listdir(folder_path):if filename.lower().endswith((".jpg", ".jpeg", ".png")):image_path = os.path.join(folder_path, filename)image_paths.append(image_path)for image_path in image_paths:self.detect_image(image_path)def detect_image(self, image_path):if image_path:print(image_path)image = cv2.imread(image_path)if image is not None:if self.flag == 0:results = self.worker.model.predict(image)elif self.flag == 1:results = self.worker.model.predict(image_path, save=True)self.worker.detection_type = "image"if results:self.current_results = resultsself.worker.current_annotated_image = results[0].plot()annotated_image = self.worker.current_annotated_imageimage_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)height1, width1, channel1 = image_rgb.shapebytesPerLine1 = 3 * width1qimage1 = 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)height2, width2, channel2 = annotated_image.shapebytesPerLine2 = 3 * width2qimage2 = QImage(annotated_image.data, width2, height2, bytesPerLine2, QImage.Format_RGB888)pixmap2 = QPixmap.fromImage(qimage2)self.label2.setPixmap(pixmap2.scaled(self.label2.size(), Qt.KeepAspectRatio))self.save_button.setEnabled(True)cv2.waitKey(300) # 修改图片切换时间def save_detection_results(self):if self.worker.current_annotated_image is not None:self.worker.save_image(self.worker.current_annotated_image)def show_detected_objects(self):frame = self.current_resultsif frame:det_info = self.worker.detect_objects(frame)if det_info:object_count = len(det_info)object_info = f"识别到的物体总个数:{object_count}\n"object_dict = {}for obj in det_info:if obj in object_dict:object_dict[obj] += 1else:object_dict[obj] = 1sorted_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.folder_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_())
使用本代码仅需在Ultralytics文件夹中新建一个main.py或者其它名字的py文件然后运行即可,运行有报错可以发在评论区,看到都会及时回复。
3.4 界面展示
这样一个简单的ui界面就写好了
需要更多功能的及其他需求可以私聊,遇到报错可以在评论区交流~