前言
交通标志识别是一项重要的任务。YOLOv8是前沿的目标检测技术,它基于先前 YOLO 版本在目标检测任务上的成功,进一步提升性能和灵活性。
我们将使用YOLOv8训练中国交通标志数据集,完成一个多目标检测实战项目。可实时检测图像标志,并提供可视化演示界面 。
YOLOv8具体改进如下:
- Backbone:使用的依旧是CSP的思想,不过YOLOv5中的C3模块被替换成了C2f模块,实现了进一步的轻量化,同时YOLOv8依旧使用了YOLOv5等架构中使用的SPPF模块;
- PAN-FPN:毫无疑问YOLOv8依旧使用了PAN的思想,不过通过对比YOLOv5与YOLOv8的结构图可以看到,YOLOv8将YOLOv5中PAN-FPN上采样阶段中的卷积结构删除了,同时也将C3模块替换为了C2f模块;
- Decoupled-Head:是不是嗅到了不一样的味道?是的,YOLOv8走向了Decoupled-Head;
- Anchor-Free:YOLOv8抛弃了以往的Anchor-Base,使用了Anchor-Free的思想;
- 损失函数:YOLOv8使用VFL Loss作为分类损失,使用DFL Loss+CIOU Loss作为分类损失;
- 样本匹配:YOLOv8抛弃了以往的IOU匹配或者单边比例的分配方式,而是使用了Task-Aligned Assigner匹配方式
数据集来源:https://github.com/csust7zhangjm/CCTSDB
加载模型
from ultralytics import YOLO
# model = YOLO('yolov8n.yaml') # 从YAML创建一个新模型
model = YOLO('weights/yolov8s.pt') # 加载预训练模型(推荐用于训练)
# model = YOLO('yolov8s.yaml').load('weights/yolov8s.pt') # 从YAML构建并转移权重
# 训练模型
model.train(data="../datasets-train/sign.yaml",
imgsz=640, # 输入图像的大小为整数或 w,h
epochs=50, # 要训练的次数
batch=16, # 每批次的图像数量(AutoBatch 为 -1)
device=0, # 要运行的设备,即 cuda device=0 或 device=0,1,2,3 或 device=cpu
workers=0, # 用于数据加载的工作线程数(如果是 DDP,则为每个 RANK)
resume=False) # True的时候则从上一个检查点恢复训练
主窗口向yolo实例发送执行信号
class MainWindow(QMainWindow, Ui_MainWindow):
main2yolo_begin_sgl = Signal()
def __init__(self, parent=None):
super(MainWindow, self).__init__()
self.setupUi(self)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setWindowFlags(Qt.FramelessWindowHint)
UIFuncitons.uiDefinitions(self)
UIFuncitons.shadow_style(self, self.Class_QF, QColor(0, 205, 102))
UIFuncitons.shadow_style(self, self.Target_QF, QColor(123, 104, 238))
UIFuncitons.shadow_style(self, self.Fps_QF, QColor(0, 205, 102))
UIFuncitons.shadow_style(self, self.Model_QF, QColor(123, 104, 238))
self.model_box.clear()
self.pt_list = os.listdir('./models')
self.pt_list = [file for file in self.pt_list if file.endswith('.pt') or file.endswith('.engine')]
self.pt_list.sort(key=lambda x: os.path.getsize('./models/' + x)) # 按文件大小排序
self.model_box.clear()
self.model_box.addItems(self.pt_list)
self.Qtimer_ModelBox = QTimer(self) # 计时器:每2秒监视模型文件更改一次
self.Qtimer_ModelBox.timeout.connect(self.ModelBoxRefre)
self.Qtimer_ModelBox.start(2000)
# Yolo-v8 thread
self.yolo_predict = YoloPredictor() # 实例化yolo检测
self.select_model = self.model_box.currentText()
self.yolo_predict.new_model_name = "./models/%s" % self.select_model
self.yolo_thread = QThread()
self.yolo_predict.yolo2main_trail_img.connect(lambda x: self.show_image(x, self.pre_video))
self.yolo_predict.yolo2main_box_img.connect(lambda x: self.show_image(x, self.res_video))
self.yolo_predict.yolo2main_status_msg.connect(lambda x: self.show_status(x))
self.yolo_predict.yolo2main_fps.connect(lambda x: self.fps_label.setText(x))
self.yolo_predict.yolo2main_class_num.connect(lambda x: self.Class_num.setText(str(x)))
self.yolo_predict.yolo2main_target_num.connect(lambda x: self.Target_num.setText(str(x)))
self.yolo_predict.yolo2main_progress.connect(lambda x: self.progress_bar.setValue(x))
self.main2yolo_begin_sgl.connect(self.yolo_predict.run)
self.yolo_predict.moveToThread(self.yolo_thread)
# 模型参数
self.model_box.currentTextChanged.co