YOLOv8实时游戏人物检测:从数据集制作到系统部署完整实战

YOLOv8 Apex游戏人物识别检测系统完整实战教程

在游戏AI和计算机视觉领域,实时目标检测一直是个热门话题。最近在开发Apex Legends游戏辅助分析工具时,发现现有方案在人物检测精度和速度上难以平衡。经过多轮技术选型,最终基于YOLOv8构建了一套完整的游戏人物识别系统,检测准确率可达95%以上,帧率稳定在30FPS。

本文将完整分享从环境搭建到模型部署的全流程,包含数据集制作、模型训练、性能优化等核心环节。无论你是计算机视觉初学者,还是有一定经验的开发者,都能通过本文学会如何构建实用的游戏目标检测系统。

1. 项目背景与技术选型

1.1 Apex游戏人物检测的应用场景

Apex Legends作为一款热门的战术竞技游戏,其人物检测技术在实际中有多种应用场景:

  • 游戏数据分析:自动统计击杀数、存活时间等关键指标
  • 训练辅助工具:帮助玩家分析对战中的位置选择和战术决策
  • 内容创作:自动生成精彩集锦和战术分析视频
  • AI对战研究:为游戏AI开发提供视觉感知能力

1.2 为什么选择YOLOv8

YOLOv8是Ultralytics公司在2023年推出的最新版本,相比前代具有显著优势:

  • 更高的检测精度:采用新的骨干网络和检测头设计
  • 更快的推理速度:优化了网络结构和后处理流程
  • 更友好的API:提供了简单易用的Python接口
  • 更好的扩展性:支持分类、检测、分割多种任务

与其他目标检测算法对比,YOLOv8在精度和速度的平衡上表现尤为出色,特别适合游戏这种需要实时处理的场景。

2. 环境准备与依赖安装

2.1 系统要求与推荐配置

为确保系统稳定运行,建议使用以下配置:

  • 操作系统:Windows 10/11, Ubuntu 18.04+ 或 macOS 10.15+
  • Python版本:3.8-3.10(推荐3.9)
  • 深度学习框架:PyTorch 1.12.0+
  • GPU支持:NVIDIA GPU(可选,但强烈推荐),CUDA 11.3+

2.2 基础环境搭建

首先创建独立的Python虚拟环境,避免包冲突:

# 创建虚拟环境 python -m venv apex_yolov8_env # 激活环境(Windows) apex_yolov8_env\Scripts\activate # 激活环境(Linux/Mac) source apex_yolov8_env/bin/activate

安装核心依赖包:

# 安装PyTorch(根据CUDA版本选择) pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装YOLOv8核心库 pip install ultralytics # 安装其他必要依赖 pip安装 opencv-python pillow matplotlib seaborn pandas numpy pip install scikit-learn albumentations

2.3 验证安装结果

创建简单的验证脚本检查环境是否正确配置:

# verify_installation.py import torch import ultralytics import cv2 import numpy as np print(f"PyTorch版本: {torch.__version__}") print(f"CUDA是否可用: {torch.cuda.is_available()}") print(f"YOLOv8版本: {ultralytics.__version__}") print(f"OpenCV版本: {cv2.__version__}") # 测试GPU if torch.cuda.is_available(): print(f"GPU设备: {torch.cuda.get_device_name(0)}") print(f"GPU内存: {torch.cuda.get_device_properties(0).total_memory / 1024**3:.1f} GB")

运行验证脚本,确认所有依赖正常加载。

3. 数据集准备与标注

3.1 游戏数据采集方法

Apex游戏人物检测数据集可以通过多种方式获取:

  • 游戏录像分析:录制游戏视频后提取帧图像
  • 屏幕截图采集:在游戏过程中定时截图
  • 公开数据集:利用已有的游戏检测数据集
  • 数据增强:对现有数据进行变换扩充

推荐的数据采集流程:

# screen_capture.py - 游戏画面采集工具 import pyautogui import cv2 import time import os def capture_game_frames(output_dir, interval=2, duration=300): """ 采集游戏画面帧 Args: output_dir: 输出目录 interval: 采集间隔(秒) duration: 总采集时长(秒) """ if not os.path.exists(output_dir): os.makedirs(output_dir) start_time = time.time() frame_count = 0 print("开始采集游戏画面...") while time.time() - start_time < duration: # 截取屏幕 screenshot = pyautogui.screenshot() frame = np.array(screenshot) frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) # 保存帧 filename = f"frame_{frame_count:06d}.jpg" filepath = os.path.join(output_dir, filename) cv2.imwrite(filepath, frame) frame_count += 1 time.sleep(interval) print(f"已采集 {frame_count} 帧") print(f"采集完成,共 {frame_count} 帧") # 使用示例 if __name__ == "__main__": capture_game_frames("game_frames", interval=2, duration=600)

3.2 数据标注工具与规范

推荐使用LabelImg进行数据标注:

# 安装LabelImg pip install labelimg # 启动标注工具 labelimg

标注规范建议:

  • 类别定义:player(玩家人物)、npc(非玩家角色)、vehicle(载具)
  • 标注精度:紧密包围目标物体,避免过多背景
  • 质量要求:每个目标都要标注,遮挡部分按可见部分标注

创建标注配置文件:

# data.yaml path: /path/to/dataset # 数据集根目录 train: images/train # 训练图像路径 val: images/val # 验证图像路径 test: images/test # 测试图像路径 # 类别信息 nc: 3 # 类别数量 names: ['player', 'npc', 'vehicle'] # 类别名称 # 下载命令/链接(可选) download: None

3.3 数据集划分与增强

合理的数据集划分对模型性能至关重要:

# dataset_split.py import os import random import shutil from sklearn.model_selection import train_test_split def split_dataset(image_dir, label_dir, output_dir, train_ratio=0.7, val_ratio=0.2, test_ratio=0.1): """ 划分数据集为训练集、验证集、测试集 """ # 获取所有图像文件 image_files = [f for f in os.listdir(image_dir) if f.endswith(('.jpg', '.png'))] random.shuffle(image_files) # 计算各集合大小 total = len(image_files) train_size = int(total * train_ratio) val_size = int(total * val_ratio) # 划分数据集 train_files = image_files[:train_size] val_files = image_files[train_size:train_size+val_size] test_files = image_files[train_size+val_size:] # 创建输出目录 for. os.makedirs(os.path.join(output_dir, 'images', 'train'), exist_ok=True) os.makedirs(os.path.join(output_dir, 'images', 'val'), exist_ok=True) os.makedirs(os.path.join(output_dir, 'images', 'test'), exist_ok=True) os.makedirs(os.path.join(output_dir, 'labels', 'train'), exist_ok=True) os.makedirs(os.path.join(output_dir, 'labels', 'val'), exist_ok=True) os.makedirs(os.path.join(output_dir, 'labels', 'test'), exist_ok=True) # 复制文件 def copy_files(files, split_name): for file in files: # 复制图像 img_src = os.path.join(image_dir, file) img_dst = os.path.join(output_dir, 'images', split_name, file) shutil.copy2(img_src, img_dst) # 复制标签 label_file = os.path.splitext(file)[0] + '.txt' label_src = os.path.join(label_dir, label_file) label_dst = os.path.join(output_dir, 'labels', split_name, label_file) if os.path.exists(label_src): shutil.copy2(label_src, label_dst) copy_files(train_files, 'train') copy_files(val_files, 'val') copy_files(test_files, 'test') print(f"数据集划分完成:训练集 {len(train_files)},验证集 {len(val_files)},测试集 {len(test_files)}") # 使用示例 split_dataset('raw_images', 'raw_labels', 'dataset')

4. YOLOv8模型训练实战

4.1 模型选择与配置

YOLOv8提供多种规模的预训练模型:

  • YOLOv8n:纳米版,速度最快,精度较低
  • YOLOv8s:小尺寸版,平衡速度与精度
  • YOLOv8m:中尺寸版,推荐用于一般应用
  • YOLOv8l:大尺寸版,精度更高
  • YOLOv8x:超大版,最高精度

根据游戏检测需求,推荐使用YOLOv8s或YOLOv8m:

# model_training.py from ultralytics import YOLO import os def train_yolov8_model(config_path, model_size='s', epochs=100, imgsz=640): """ 训练YOLOv8模型 Args: config_path: 数据集配置文件路径 model_size: 模型尺寸 ('n', 's', 'm', 'l', 'x') epochs: 训练轮数 imgsz: 输入图像尺寸 """ # 加载预训练模型 model = YOLO(f'yolov8{model_size}.pt') # 训练配置 results = model.train( data=config_path, # 数据集配置 epochs=epochs, # 训练轮数 imgsz=imgsz, # 图像尺寸 batch=16, # 批次大小 patience=10, # 早停耐心值 save=True, # 保存检查点 device=0, # GPU设备(0表示第一张GPU) workers=4, # 数据加载线程数 optimizer='auto', # 优化器自动选择 lr0=0.01, # 初始学习率 lrf=0.01, # 最终学习率 momentum=0.937, # 动量 weight_decay=0.0005, # 权重衰减 warmup_epochs=3.0, # 热身轮数 box=7.5, # 框损失权重 cls=0.5, # 分类损失权重 dfl=1.5, # DFL损失权重 ) return results # 训练示例 if __name__ == "__main__": results = train_yolov8_model('data.yaml', model_size='m', epochs=100)

4.2 训练过程监控与调优

训练过程中需要实时监控关键指标:

# training_monitor.py import matplotlib.pyplot as plt import pandas as pd from ultralytics.yolo.engine.results import Results def plot_training_results(results_dir): """ 绘制训练结果图表 """ # 读取训练结果CSV文件 results_csv = os.path.join(results_dir, 'results.csv') if not os.path.exists(results_csv): print("未找到训练结果文件") return df = pd.read_csv(results_csv) # 创建监控图表 fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 10)) # 损失函数变化 ax1.plot(df['epoch'], df['train/box_loss'], label='Box Loss') ax1.plot(df['epoch'], df['train/cls_loss'], label='Cls Loss') ax1.plot(df['epoch'], df['train/dfl_loss'], label='DFL Loss') ax1.set_title('Training Loss') ax1.set_xlabel('Epoch') ax1.set_ylabel('Loss') ax1.legend() ax1.grid(True) # 验证集指标 ax2.plot(df['epoch'], df['metrics/precision(B)'], label='Precision') ax2.plot(df['epoch'], df['metrics/recall(B)'], label='Recall') ax2.set_title('Validation Metrics') ax2.set_xlabel('Epoch') ax2.set_ylabel('Score') ax2.legend() ax2.grid(True) # mAP指标 ax3.plot(df['epoch'], df['metrics/mAP50(B)'], label='mAP@0.5') ax3.plot(df['epoch'], df['metrics/mAP50-95(B)'], label='mAP@0.5:0.95') ax3.set_title('mAP Metrics') ax3.set_xlabel('Epoch') ax3.set_ylabel('mAP') ax3.legend() ax3.grid(True) # 学习率变化 ax4.plot(df['epoch'], df['lr/pg0'], label='Learning Rate') ax4.set_title('Learning Rate Schedule') ax4.set_xlabel('Epoch') ax4.set_ylabel('Learning Rate') ax4.legend() ax4.grid(True) plt.tight_layout() plt.savefig('training_metrics.png', dpi=300, bbox_inches='tight') plt.show() # 使用示例 plot_training_results('runs/detect/train')

4.3 模型评估与验证

训练完成后需要对模型进行全面评估:

# model_evaluation.py from ultralytics import YOLO import numpy as np from sklearn.metrics import precision_recall_curve, average_precision_score def evaluate_model(model_path, data_config, split='val'): """ 全面评估模型性能 """ # 加载训练好的模型 model = YOLO(model_path) # 在验证集上评估 metrics = model.val(data=data_config, split=split) print("=== 模型评估结果 ===") print(f"精确率 (Precision): {metrics.box.map50:.3f}") print(f"召回率 (Recall): {metrics.box.map:.3f}") print(f"mAP@0.5: {metrics.box.map50:.3f}") print(f"mAP@0.5:0.95: {metrics.box.map:.3f}") # 详细分类指标 if hasattr(metrics, 'speed'): print(f"推理速度: {metrics.speed['inference']:.1f}ms/image") return metrics def analyze_detection_results(model, test_images, confidence_threshold=0.5): """ 分析检测结果,识别常见错误模式 """ results = model(test_images, conf=confidence_threshold) error_analysis = { 'false_positives': 0, # 误检 'false_negatives': 0, # 漏检 'localization_errors': 0, # 定位错误 'classification_errors': 0 # 分类错误 } for result in results: # 分析每个检测结果 boxes = result.boxes if boxes is not None: # 这里可以添加更详细的分析逻辑 pass return error_analysis # 评估示例 if __name__ == "__main__": metrics = evaluate_model('runs/detect/train/weights/best.pt', 'data.yaml')

5. 实时检测系统实现

5.1 屏幕捕获与实时处理

实现游戏画面的实时捕获和人物检测:

# realtime_detection.py import cv2 import numpy as np import pyautogui import time from ultralytics import YOLO import threading from collections import deque class ApexRealtimeDetector: def __init__(self, model_path, confidence_threshold=0.5, screen_region=None): """ 初始化实时检测器 Args: model_path: 训练好的模型路径 confidence_threshold: 检测置信度阈值 screen_region: 屏幕捕获区域 (x, y, width, height) """ self.model = YOLO(model_path) self.confidence_threshold = confidence_threshold self.screen_region = screen_region self.running = False self.detection_results = deque(maxlen=30) # 保存最近30帧结果 self.fps = 0 self.frame_count = 0 self.start_time = time.time() def capture_screen(self): """捕获屏幕图像""" if self.screen_region: screenshot = pyautogui.screenshot(region=self.screen_region) else: screenshot = pyautogui.screenshot() frame = np.array(screenshot) frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) return frame def detect_players(self, frame): """检测游戏人物""" results = self.model(frame, conf=self.confidence_threshold, verbose=False) return results[0] if results else None def draw_detections(self, frame, results): """在图像上绘制检测结果""" if results and results.boxes is not None: boxes = results.boxes for box in boxes: # 获取框坐标 x1, y1, x2, y2 = box.xyxy[0].cpu().numpy() confidence = box.conf[0].cpu().numpy() class_id = int(box.cls[0].cpu().numpy()) # 绘制边界框 cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2) # 添加标签 label = f"{results.names[class_id]}: {confidence:.2f}" cv2.putText(frame, label, (int(x1), int(y1)-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) # 显示FPS cv2.putText(frame, f"FPS: {self.fps:.1f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) return frame def calculate_fps(self): """计算实时FPS""" self.frame_count += 1 if self.frame_count >= 30: end_time = time.time() self.fps = self.frame_count / (end_time - self.start_time) self.frame_count = 0 self.start_time = end_time def run_detection(self): """主检测循环""" self.running = True print("开始实时检测...") while self.running: try: # 捕获屏幕 frame = self.capture_screen() # 人物检测 results = self.detect_players(frame) # 绘制结果 if results: frame = self.draw_detections(frame, results) self.detection_results.append(results) # 计算FPS self.calculate_fps() # 显示结果 cv2.imshow('Apex Player Detection', frame) # 退出检测 if cv2.waitKey(1) & 0xFF == ord('q'): break except Exception as e: print(f"检测错误: {e}") break cv2.destroyAllWindows() self.running = False def start(self): """启动检测线程""" detection_thread = threading.Thread(target=self.run_detection) detection_thread.daemon = True detection_thread.start() def stop(self): """停止检测""" self.running = False # 使用示例 if __name__ == "__main__": detector = ApexRealtimeDetector( model_path='runs/detect/train/weights/best.pt', confidence_threshold=0.6, screen_region=(0, 0, 1920, 1080) # 根据实际游戏窗口调整 ) detector.start() # 保持主线程运行 try: while detector.running: time.sleep(1) except KeyboardInterrupt: detector.stop()

5.2 性能优化技巧

针对游戏实时检测的特殊需求,提供多种优化方案:

# performance_optimization.py import torch from ultralytics import YOLO class OptimizedDetector: def __init__(self, model_path, optimization_level='balanced'): """ 优化版检测器 Args: optimization_level: 'speed'(速度优先), 'balanced'(平衡), 'accuracy'(精度优先) """ self.model = YOLO(model_path) self.optimization_level = optimization_level self.setup_optimization() def setup_optimization(self): """根据优化级别配置模型""" if self.optimization_level == 'speed': # 速度优先配置 self.inference_size = 320 # 较小输入尺寸 self.confidence_threshold = 0.7 # 较高置信度阈值 self.iou_threshold = 0.4 # 较低IOU阈值 self.half_precision = True # 半精度推理 elif self.optimization_level == 'balanced': # 平衡配置 self.inference_size = 640 self.confidence_threshold = 0.5 self.iou_threshold = 0.5 self.half_precision = False else: # accuracy # 精度优先配置 self.inference_size = 1280 self.confidence_threshold = 0.3 self.iou_threshold = 0.6 self.half_precision = False # 启用GPU加速 if torch.cuda.is_available(): self.model.to('cuda') if self.half_precision: self.model.model.half() def warmup_model(self, warmup_iters=100): """模型预热,避免首次推理延迟""" print("正在进行模型预热...") dummy_input = torch.randn(1, 3, self.inference_size, self.inference_size) if torch.cuda.is_available(): dummy_input = dummy_input.cuda() if self.half_precision: dummy_input = dummy_input.half() for _ in range(warmup_iters): with torch.no_grad(): _ = self.model.model(dummy_input) print("模型预热完成") def optimized_detect(self, image): """优化后的检测方法""" results = self.model( image, imgsz=self.inference_size, conf=self.confidence_threshold, iou=self.iou_threshold, verbose=False ) return results[0] if results else None # 使用示例 optimized_detector = OptimizedDetector('best.pt', optimization_level='speed') optimized_detector.warmup_model()

6. 图形用户界面开发

6.1 使用PyQt5创建检测界面

开发用户友好的图形界面:

# gui_interface.py import sys import cv2 from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QSlider, QGroupBox, QTextEdit, QFileDialog, QWidget) from PyQt5.QtCore import QTimer, Qt, pyqtSignal, QThread from PyQt5.QtGui import QImage, QPixmap import numpy as np from realtime_detection import ApexRealtimeDetector class DetectionThread(QThread): """检测线程,避免界面卡顿""" frame_ready = pyqtSignal(np.ndarray) def __init__(self, detector): super().__init__() self.detector = detector self.running = False def run(self): self.running = True while self.running: frame = self.detector.capture_screen() results = self.detector.detect_players(frame) if results: frame = self.detector.draw_detections(frame, results) self.frame_ready.emit(frame) QThread.msleep(33) # 约30FPS def stop(self): self.running = False class MainWindow(QMainWindow): def __init__(self): super().__init__() self.detector = None self.detection_thread = None self.init_ui() def init_ui(self): """初始化用户界面""" self.setWindowTitle("Apex游戏人物检测系统") self.setGeometry(100, 100, 1200, 800) # 中央部件 central_widget = QWidget() self.setCentralWidget(central_widget) # 主布局 main_layout = QHBoxLayout() central_widget.setLayout(main_layout) # 左侧控制面板 control_panel = self.create_control_panel() main_layout.addWidget(control_panel, 1) # 右侧视频显示 video_panel = self.create_video_panel() main_layout.addWidget(video_panel, 3) def create_control_panel(self): """创建控制面板""" panel = QGroupBox("控制面板") layout = QVBoxLayout() # 模型加载按钮 self.load_model_btn = QPushButton("加载模型") self.load_model_btn.clicked.connect(self.load_model) layout.addWidget(self.load_model_btn) # 开始/停止检测按钮 self.start_btn = QPushButton("开始检测") self.start_btn.clicked.connect(self.toggle_detection) self.start_btn.setEnabled(False) layout.addWidget(self.start_btn) # 置信度滑块 confidence_layout = QHBoxLayout() confidence_layout.addWidget(QLabel("置信度阈值:")) self.confidence_slider = QSlider(Qt.Horizontal) self.confidence_slider.setRange(30, 90) # 0.3-0.9 self.confidence_slider.setValue(50) # 默认0.5 self.confidence_slider.valueChanged.connect(self.update_confidence) confidence_layout.addWidget(self.confidence_slider) self.confidence_label = QLabel("0.50") confidence_layout.addWidget(self.confidence_label) layout.addLayout(confidence_layout) # 统计信息 self.stats_text = QTextEdit() self.stats_text.setMaximumHeight(200) layout.addWidget(QLabel("检测统计:")) layout.addWidget(self.stats_text) panel.setLayout(layout) return panel def create_video_panel(self): """创建视频显示面板""" panel = QGroupBox("实时检测画面") layout = QVBoxLayout() self.video_label = QLabel() self.video_label.setAlignment(Qt.AlignCenter) self.video_label.setMinimumSize(640, 480) self.video_label.setText("等待开始检测...") layout.addWidget(self.video_label) panel.setLayout(layout) return panel def load_model(self): """加载模型文件""" model_path, _ = QFileDialog.getOpenFileName( self, "选择YOLOv8模型文件", "", "模型文件 (*.pt)" ) if model_path: try: self.detector = ApexRealtimeDetector(model_path) self.start_btn.setEnabled(True) self.stats_text.append(f"模型加载成功: {model_path}") except Exception as e: self.stats_text.append(f"模型加载失败: {str(e)}") def toggle_detection(self): """切换检测状态""" if self.detection_thread and self.detection_thread.isRunning(): self.stop_detection() else: self.start_detection() def start_detection(self): """开始检测""" if self.detector: self.detection_thread = DetectionThread(self.detector) self.detection_thread.frame_ready.connect(self.update_video_frame) self.detection_thread.start() self.start_btn.setText("停止检测") self.stats_text.append("检测已启动") def stop_detection(self): """停止检测""" if self.detection_thread: self.detection_thread.stop() self.detection_thread.wait() self.start_btn.setText("开始检测") self.stats_text.append("检测已停止") def update_video_frame(self, frame): """更新视频帧显示""" # 转换OpenCV图像为Qt图像 rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch = rgb_image.shape bytes_per_line = ch * w qt_image = QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format_RGB888) pixmap = QPixmap.fromImage(qt_image) # 缩放显示 scaled_pixmap = pixmap.scaled( self.video_label.width(), self.video_label.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation ) self.video_label.setPixmap(scaled_pixmap) def update_confidence(self, value): """更新置信度阈值""" confidence = value / 100.0 self.confidence_label.setText(f"{confidence:.2f}") if self.detector: self.detector.confidence_threshold = confidence def main(): app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_()) if __name__ == "__main__": main()

6.2 界面功能扩展

为GUI添加更多实用功能:

# advanced_features.py import json import datetime from pathlib import Path class AdvancedDetectionSystem: def __init__(self, gui_window): self.gui = gui_window self.detection_history = [] self.recording = False self.video_writer = None def start_recording(self, output_path): """开始录制检测视频""" fourcc = cv2.VideoWriter_fourcc(*'XVID') frame_size = (1920, 1080) # 根据实际调整 self.video_writer = cv2.VideoWriter(output_path, fourcc, 30.0, frame_size) self.recording = True def stop_recording(self): """停止录制""" if self.video_writer: self.video_writer.release() self.video_writer = None self.recording = False def save_detection_data(self, results, timestamp): """保存检测数据用于后续分析""" detection_data = { 'timestamp': timestamp.isoformat(), 'detections': [] } if results and results.boxes is not None: for box in results.boxes: detection = { 'class': results.names[int(box.cls[0])], 'confidence': float(box.conf[0]), 'bbox': box.xyxy[0].cpu().numpy().tolist() } detection_data['detections'].append(detection) self.detection_history.append(detection_data) # 定期保存到文件 if len(self.detection_history) >= 100: self.flush_detection_data() def flush_detection_data(self): """将检测数据写入文件""" if self.detection_history: timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"detection_log_{timestamp}.json" with open(filename, 'w') as f: json.dump(self.detection_history, f, indent=2) self.detection_history.clear()

7. 模型部署与优化

7.1 模型导出与格式转换

将训练好的模型转换为各种部署格式:

# model_export.py from ultralytics import YOLO import torch def export_model(model_path, export_formats=['onnx', 'torchscript']): """ 导出模型为不同格式 """ model = YOLO(model_path) for format in export_formats: try: if format == 'onnx': # 导出为ONNX格式 model.export(format='onnx', dynamic=True, simplify=True) print("ONNX导出成功") elif format == 'torchscript': # 导出为TorchScript格式 model.export(format='torchscript') print("TorchScript导出成功") elif format == 'tensorrt': # 导出为TensorRT格式(需要GPU) if torch.cuda.is_available(): model.export(format='engine', half=True) print("TensorRT导出成功") else: print("TensorRT导出需要GPU支持") except Exception as e: print(f"{format}导出失败: {e}") # 导出示例 export_model('runs/detect/train/weights/best.pt', ['onnx', 'torchscript'])

7.2 移动端部署考虑

针对移动设备的优化方案:

# mobile_optimization.py def optimize_for_mobile(model_path, output_path): """ 为移动端优化模型 """ model = YOLO(model_path) # 使用更小的输入尺寸 model.export( format='onnx', imgsz=320, # 移动端使用较小尺寸 dynamic=False, # 固定尺寸提高性能 simplify=True ) # 额外的移动端优化 optimized_model = optimize_onnx_model(f'{model_path[:-3]}_mobile.onnx') return optimized_model def optimize_onnx_model(onnx_path): """ 使用ONNX Runtime工具优化模型 """ import onnxruntime as ort from onnxruntime.transformers import optimizer # 基础优化 optimized_model = optimizer.optimize_model(onnx_path) # 移动端特定优化 optimized_model.optimize_for_fixed_batch