基于YOLOv8/YOLOv5与PySide6的车型识别检测系统开发实战

发布时间:2026/9/3 8:32:40
基于YOLOv8/YOLOv5与PySide6的车型识别检测系统开发实战 这次我们来看一个比较典型的视觉落地项目基于 YOLOv8 / YOLOv5 PySide6 的车型识别检测系统检测目标包括轿车、SUV、跑车、卡车。这类系统在很多场景里都有需求比如停车场出入口、二手车评估、交通流量统计、汽车后市场 APP 的车辆信息自动录入。项目本身并不神秘本质就是把 YOLO 目标检测模型接到 PySide6 桌面界面上再配合图片、视频、摄像头输入完成检测结果的可视化展示和结果导出。很多读者关心的问题其实是三个第一用 YOLOv8 还是 YOLOv5第二PySide6 界面怎么做能不能实时显示检测框第三训练自己的车型数据集效果怎么样。这篇文章会把这些都拆开来讲先给核心能力速览再给环境准备、代码结构、训练流程、界面联调、接口扩展和排错思路。如果你手里已经有一批车型图片想尽快做出一个能用的桌面检测工具这篇文章可以收藏备用。先说结论如果你的显卡显存不大或者想在 CPU 机器上快速验证YOLOv5 是更稳的选择如果追求更高的检测精度并且显卡驱动和 PyTorch 版本比较新YOLOv8 是趋势。PySide6 只是界面框架负责把模型推理结果画出来它本身不参与模型训练。整个项目的难点不在 PySide6而在数据集质量和模型训练效果。下面直接进入正题。1. 核心能力速览能力项说明项目类型目标检测 桌面 GUI 应用检测模型YOLOv8 / YOLOv5二者可切换界面框架PySide6Qt for Python检测目标轿车、SUV、跑车、卡车输入方式单张图片、批量图片、视频文件、摄像头实时流输出内容检测框、类别标签、置信度、统计计数、结果图片硬件需求GPU 优先CPU 可运行但推理速度较慢显存占用取决于模型规格和输入分辨率需按本机实际测试启动方式命令行启动 Python 脚本API 接口可自行扩展 FastAPI / Flask 服务批量任务支持批量图片目录遍历检测定制能力可替换数据集训练新车型类别从使用角度讲这套系统适合谁适合有基础 Python 经验、想把 YOLO 检测模型快速做成桌面工具的人。它帮你解决的是“模型训练好之后怎么给非技术用户用”的问题也适合自己手写 UI 去练习 PySide6 与模型推理的结合。2. 适用场景与使用边界车型识别检测系统可以帮助完成以下工作停车场出入口车辆类型统计区分轿车与 SUV。二手车平台车辆照片自动打标签节省人工录入时间。道路监控视频中的车辆分类、计数和跟踪。汽车相关软件里对用户上传图片做车型分类和展示。但需要明确使用边界。第一车型识别不等于车牌识别也不等于车辆品牌型号识别。YOLO 检测的是“车是什么车型大类”比如这辆车是轿车还是 SUV。要识别具体品牌型号需要更细粒度的数据集和分类模型。第二模型精度依赖训练数据。网上公开的车型数据集如果只覆盖少数几个类别实拍场景里出现卡车、跑车的比例低检测效果就会明显下降。不要指望一个通用权重能解决所有现场问题。第三涉及摄像头采集、人脸和车牌信息时要注意隐私和合规。检测系统如果部署在公共区域或用于商业用途需要确认是否涉及个人信息采集遵守当地法律法规。对于收集到的车辆图片也要在授权范围内使用不得用于非法爬取或数据滥用。第四项目属于本地部署方案适合离线环境。如果要做成 Web 服务或云端接口需要额外开发并发控制、访问认证和模型服务化部署不能直接把 PySide6 桌面程序丢到服务器上。3. 环境准备与前置条件在动手写代码之前先把环境梳理清楚。下面是一套通用清单具体版本号建议按当前官方文档确认。3.1 操作系统Windows 10/11、Ubuntu 20.04 及以上都可以。PySide6 对 Windows 和 Linux 都支持macOS 也可以跑但 GPU 训练最好用 NVIDIA 显卡环境。3.2 Python 版本建议使用 Python 3.9 到 3.11。PySide6 和 ultralytics 对 Python 3.12 的支持需要确认保险起见用 3.10。3.3 GPU 与驱动训练模型推荐 NVIDIA 显卡显存越大越好。使用 CUDA 环境时需要安装匹配的 NVIDIA 驱动再用 pip 安装对应版本的 PyTorch。示例# 查看显卡驱动和 CUDA 版本 nvidia-smi如果没有 NVIDIA 显卡也可以用 CPU 跑推理但训练大模型会很慢。YOLOv5 和 YOLOv8 都支持 CPU 推理适合低频率的图片检测任务。3.4 Python 依赖安装创建虚拟环境后安装以下依赖pip install ultralytics pip install PySide6 pip install opencv-python pip install torch torchvision如果使用 YOLOv5 的分支代码可以用 git clone 方式安装git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt注意YOLOv8 是 ultralytics 库的一部分安装ultralytics后即可使用。YOLOv5 也可以直接用ultralytics加载也可以使用原 repo 的detect.py。3.5 模型权重文件YOLOv8 官方预训练权重yolov8n.pt、yolov8s.pt、yolov8m.pt等。YOLOv5 官方预训练权重yolov5s.pt、yolov5m.pt等。自己训练的车型权重best.pt放在项目weights目录下。官方预训练权重包含 COCO 80 类其中就有车相关的类别但不一定能细分为轿车、SUV、跑车、卡车。要精确识别这四类需要用自建数据集训练。3.6 数据集组织准备训练数据时推荐使用 YOLO 格式。目录结构datasets/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/每张图片对应一个同名的.txt标签文件标签内容格式为class_id x_center y_center width height坐标是归一化后的值范围 0 到 1。例如0 0.5 0.5 0.8 0.6表示类别 0轿车的检测框中心在 (0.5, 0.5)宽 0.8高 0.6。4. 项目结构设计与代码实现一个完整的车型识别检测系统建议按下面的结构组织代码vehicle_detect/ ├── main.py # 程序入口 ├── config.py # 模型路径、类别名等配置 ├── detector.py # YOLO 检测封装 ├── ui/ │ ├── __init__.py │ └── main_window.py # PySide6 主窗口 ├── utils/ │ ├── __init__.py │ └── image_utils.py # 图像处理工具 ├── weights/ │ └── best.pt # 训练好的权重 ├── datasets/ │ └── vehicle.yaml # 数据集配置 └── outputs/ # 检测结果输出4.1 检测器封装先封装一个Detector类统一处理模型加载和推理。这样在 UI 里调用比较方便也能支持 YOLOv5 / YOLOv8 切换。# detector.py from ultralytics import YOLO import cv2 import numpy as np class Detector: def __init__(self, model_path: str, conf_thres: float 0.25): self.model YOLO(model_path) self.conf_thres conf_thres def detect_image(self, image: np.ndarray): 输入 BGR 图像返回检测结果列表。 每个结果包含box, class_id, class_name, confidence results self.model.predict( sourceimage, confself.conf_thres, verboseFalse ) detections [] if len(results) 0: return detections result results[0] names result.names for box in result.boxes: x1, y1, x2, y2 box.xyxy[0].tolist() conf float(box.conf[0]) cls_id int(box.cls[0]) detections.append({ box: [int(x1), int(y1), int(x2), int(y2)], class_id: cls_id, class_name: names[cls_id], confidence: conf }) return detections def draw_detections(self, image: np.ndarray, detections: list): 在图像上画检测框和标签 for det in detections: x1, y1, x2, y2 det[box] label f{det[class_name]} {det[confidence]:.2f} color (0, 255, 0) cv2.rectangle(image, (x1, y1), (x2, y2), color, 2) cv2.putText( image, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2 ) return image这里使用的是ultralytics库。如果你要用 YOLOv5 原版可以改用torch.hub.load或直接调用detect.py不过统一使用 ultralytics 可以同时加载 YOLOv8 和 YOLOv5 的.pt权重YOLOv5 权重需要转换或兼容。4.2 PySide6 主窗口主窗口需要包含以下区域左侧功能按钮包括选择图片、选择视频、打开摄像头、批量检测、模型切换。中间图像显示区用QLabel或QGraphicsView显示检测结果。右侧检测结果列表记录每个目标的类别和置信度。底部状态栏显示模型名称、检测耗时、FPS 等信息。为了不阻塞界面推理应该放到子线程中执行通过信号槽把结果传回主线程。下面给一个简单的窗口骨架# ui/main_window.py import sys from PySide6.QtWidgets import ( QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QListWidget, QFileDialog, QMessageBox, QComboBox ) from PySide6.QtCore import Qt, QThread, Signal from PySide6.QtGui import QPixmap, QImage import cv2 class DetectThread(QThread): image_ready Signal(object) def __init__(self, detector, image): super().__init__() self.detector detector self.image image def run(self): detections self.detector.detect_image(self.image) result_image self.detector.draw_detections( self.image.copy(), detections ) self.image_ready.emit((result_image, detections)) class MainWindow(QMainWindow): def __init__(self, detector): super().__init__() self.detector detector self.setWindowTitle(车型识别检测系统) self.resize(1200, 700) central QWidget() self.setCentralWidget(central) layout QHBoxLayout(central) # 左侧控制区 left_layout QVBoxLayout() self.btn_image QPushButton(选择图片) self.btn_video QPushButton(选择视频) self.btn_camera QPushButton(打开摄像头) self.btn_batch QPushButton(批量检测) self.model_combo QComboBox() self.model_combo.addItems([yolov8s.pt, yolov5s.pt, best.pt]) self.result_list QListWidget() left_layout.addWidget(self.model_combo) left_layout.addWidget(self.btn_image) left_layout.addWidget(self.btn_video) left_layout.addWidget(self.btn_camera) left_layout.addWidget(self.btn_batch) left_layout.addWidget(QLabel(检测结果)) left_layout.addWidget(self.result_list) left_layout.addStretch() # 中间图像显示区 self.image_label QLabel(请选择图片或视频) self.image_label.setAlignment(Qt.AlignCenter) self.image_label.setMinimumSize(800, 600) self.image_label.setStyleSheet(border: 1px solid #ccc;) layout.addLayout(left_layout, 1) layout.addWidget(self.image_label, 4) # 绑定事件 self.btn_image.clicked.connect(self.select_image) def select_image(self): file_path, _ QFileDialog.getOpenFileName( self, 选择图片, , 图片文件 (*.jpg *.jpeg *.png *.bmp) ) if not file_path: return image cv2.imread(file_path) if image is None: QMessageBox.warning(self, 错误, 图片读取失败) return # 使用子线程推理 self.thread DetectThread(self.detector, image) self.thread.image_ready.connect(self.on_image_ready) self.thread.start() def on_image_ready(self, data): result_image, detections data # 展示结果列表 self.result_list.clear() for det in detections: self.result_list.addItem( f{det[class_name]} {det[confidence]:.2f} f{det[box]} ) # 显示图像 rgb_image cv2.cvtColor(result_image, cv2.COLOR_BGR2RGB) h, w, ch rgb_image.shape bytes_per_line ch * w qimg QImage( rgb_image.data, w, h, bytes_per_line, QImage.Format_RGB888 ) pixmap QPixmap.fromImage(qimg) pixmap pixmap.scaled( self.image_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation ) self.image_label.setPixmap(pixmap)这个骨架已经能支撑图片检测的基本流程。视频检测和摄像头检测需要增加视频流读取逻辑通常的做法是使用cv2.VideoCapture循环读取帧再丢给检测线程通过信号把结果帧送回来。这里不展开全部代码读者可以在这个框架基础上扩展。4.3 程序入口# main.py import sys from PySide6.QtWidgets import QApplication from detector import Detector from ui.main_window import MainWindow def main(): app QApplication(sys.argv) # 加载模型初始化时可以用 yolo 官方权重 detector Detector( model_pathweights/best.pt, conf_thres0.25 ) window MainWindow(detector) window.show() sys.exit(app.exec()) if __name__ __main__: main()启动命令python main.py如果第一次运行模型权重缺失会直接报错。先下载一个官方权重放进去再切换到自己的best.pt。5. 车型检测模型训练与数据集准备5.1 YOLOv8 还是 YOLOv5YOLOv8 是 ultralytics 团队目前主推的版本支持更灵活的模型配置、更强的数据增强也支持实例分割、姿态估计等任务。YOLOv5 虽然名字带 v5但社区生态成熟部署资料多很多老项目仍在用。对于车型识别这种目标检测任务两者都能做。选择建议如下做新项目、追求更高精度优先 YOLOv8。依赖旧代码、公司已有 YOLOv5 推理环境继续用 YOLOv5。显存有限可以使用yolov8n或yolov5s这种轻量模型。需要快速集成到 PySide6 界面两者没有差别。5.2 准备车型数据集收集轿车、SUV、跑车、卡车图片时要注意类别平衡和场景多样性。理想情况下每类图片数量不少于 1000 张。如果数据不足可以通过翻转、旋转、亮度调整、随机裁剪等方式做数据增强。标注工具可以使用 LabelImg 或 LabelStudio。标注后导出 YOLO 格式。注意跑车和轿车在视觉上容易混淆需要明确标注规则。例如双门轿跑算跑车还是轿车两厢小型车算轿车还是 SUV这些规则应该在标注文档里写清楚避免标注人员前后不一致。5.3 编写数据集配置文件vehicle.yaml内容示例# vehicle.yaml path: datasets/vehicle train: images/train val: images/val names: 0: sedan 1: suv 2: sports_car 3: truck类别顺序要和训练时一致。如果使用中文类别名需要注意 ultralytics 对中文标签的支持程度更稳妥的做法是用英文标签在界面显示时再做中英文映射。5.4 训练命令使用 ultralytics 训练 YOLOv8yolo detect train datadatasets/vehicle.yaml modelyolov8s.pt epochs100 imgsz640 batch16使用 YOLOv5 原仓库训练可以进入 yolov5 目录后执行python train.py --data ../datasets/vehicle.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100训练过程中观察results.png查看 loss 曲线和 mAP 曲线。当 mAP 曲线趋于平稳时可以提前结束训练。训练完成后runs/detect/train/weights/best.pt就是最佳模型。5.5 验证模型效果用验证集做测试yolo detect val datadatasets/vehicle.yaml modelweights/best.pt重点关注 mAP50 和 mAP50-95。对车型识别来说mAP50 达到 0.85 以上算可用追求更高标准可以继续优化数据和模型。6. PySide6 界面功能测试与效果验证部署好项目后按下面流程测试功能。6.1 单张图片检测选择一张包含多辆车的图片点击“选择图片”。预期结果图片中每辆车都有矩形检测框。检测框旁显示类别和置信度。右侧列表显示每个目标的详情。图片加载和推理期间界面不卡死。如果检测框错乱或类别错误优先排查模型权重是否正确加载。类别名映射是否和训练配置一致。置信度阈值是否过高或过低。图片中车辆是否被严重遮挡。6.2 视频文件检测点击“选择视频”程序读取视频流逐帧执行检测并显示结果。这里需要关注两点推理速度是否跟得上视频帧率。画面是否出现卡顿和延迟。如果推理速度跟不上可以降低输入分辨率或者每隔几帧推理一次。6.3 摄像头实时检测打开摄像头后程序从摄像头读取帧进行实时检测。这个场景适合停车场道闸、门口车辆统计等。注意摄像头画面可能包含行人、车牌等敏感信息测试时要使用授权的测试场景和个人设备不能把摄像头对准未经同意的公共区域和他人隐私空间。6.4 批量图片检测批量检测通常用于存量图片的自动打标。建议输入一个文件夹程序遍历所有图片检测结果保存为标注文件和可视化结果图。批量检测代码模板# batch_detect.py import os import cv2 from detector import Detector def batch_detect(detector, input_dir, output_dir): os.makedirs(output_dir, exist_okTrue) supported (.jpg, .jpeg, .png, .bmp) for filename in os.listdir(input_dir): if not filename.lower().endswith(supported): continue path os.path.join(input_dir, filename) image cv2.imread(path) if image is None: print(f[跳过] {filename}) continue detections detector.detect_image(image) result_image detector.draw_detections(image.copy(), detections) # 保存可视化结果 out_path os.path.join(output_dir, filename) cv2.imwrite(out_path, result_image) # 保存检测信息到 txt txt_path os.path.splitext(out_path)[0] .txt with open(txt_path, w, encodingutf-8) as f: for det in detections: x1, y1, x2, y2 det[box] f.write( f{det[class_name]} {det[confidence]:.4f} f{x1} {y1} {x2} {y2}\n ) print(f[完成] {filename} 检测到 {len(detections)} 个目标) if __name__ __main__: det Detector(weights/best.pt) batch_detect(det, inputs, outputs)批量任务建议加入日志和失败重试。对于成百上千张图片如果中途中断要记录已处理文件名下次继续处理未完成的文件。7. 接口 API 与批量任务扩展如果需要在其他系统里调用车型识别能力可以把模型推理封装成 HTTP API。常见做法是使用 FastAPI 或 Flask。下面给一个 FastAPI 的示例。# api_server.py import io import numpy as np import cv2 from fastapi import FastAPI, UploadFile, File from detector import Detector app FastAPI() detector Detector(weights/best.pt) app.post(/detect) async def detect(file: UploadFile File(...)): content await file.read() image cv2.imdecode( np.frombuffer(content, np.uint8), cv2.IMREAD_COLOR ) detections detector.detect_image(image) return { count: len(detections), detections: detections } if __name__ __main__: import uvicorn uvicorn.run(app, host0.0.0.0, port8000)启动pip install fastapi uvicorn python api_server.py测试请求curl -X POST http://127.0.0.1:8000/detect \ -F filetest_car.jpg接口返回 JSON可以直接给前端或后端调用。注意示例中的detections列表包含 numpy 类型数据FastAPI 返回时可能要转成 Python 原生类型。更规范的做法是在返回值里单独定义 Pydantic 模型或者先把box、class_id等字段转成int和float。批量任务接口也可以设计为传入图片路径列表服务端依次检测后返回结果。考虑到并发问题最好引入任务队列避免显卡显存溢出。还应该加上访问控制。不要直接把 API 暴露到公网建议只监听127.0.0.1或者通过 Nginx 做限流和认证。涉及商业使用时还要做请求日志和结果审计。8. 资源占用与性能观察8.1 显存占用观察方法在推理过程中可以用命令查看 GPU 显存占用nvidia-smi也可以使用torch.cuda.memory_allocated()在代码里输出。import torch if torch.cuda.is_available(): print(torch.cuda.memory_allocated() / 1024**2, MB)显存占用主要由模型参数量和输入分辨率决定。n系列模型最小s次之m、l、x依次增大。640x640 输入下yolov8s的显存占用通常不会很高如果输入分辨率提升到 1280显存会明显增加。实际占用还要看推理批次大小不能一概而论。8.2 CPU 推理与 GPU 推理差异没有独立显卡时CPU 也能跑 YOLO但速度较慢。在 PySide6 界面里做单张图片检测CPU 推理 1 到 3 秒是可以接受的做视频实时检测就吃力了可能出现明显掉帧。如果只能用 CPU建议使用yolov8n或yolov5s。图片推理前先letterbox缩放到 640 或 480。减少界面刷新频率只在检测完成后更新画面。避免多线程同时推理防止 CPU 资源争抢。8.3 性能优化建议推理时使用半精度fp16在部分 GPU 上能加快速度。开启halfTrue前先确认 GPU 支持。对视频流检测可以跳帧处理。检测前对图片做缩放不直接使用大图。PySide6 界面显示时再进行缩放避免在推理和显示之间重复转换大图。9. 常见问题与排查方法下面整理成一张表格遇到问题直接对照排查。问题现象可能原因排查方式解决方案启动程序后没有窗口PySide6 依赖缺失或入口代码报错查看控制台错误日志重新安装 PySide6检查 main.py 代码模型加载失败权重文件路径错误或文件损坏检查weights/best.pt是否存在文件大小是否正常替换模型文件确认路径检测结果为空置信度阈值过高、模型类别不匹配、图片太模糊调低conf_thres到 0.1 测试调整阈值检查类别映射界面卡死推理放在主线程阻塞了事件循环检查是否使用了 QThread把推理放到子线程用信号槽回传结果图片显示不出来图像通道转换错误或 QImage 格式不对检查是否 BGR 转 RGB用cv2.cvtColor转换后再创建 QImage摄像头打不开摄像头被占用或索引错误检查设备管理器换摄像头索引重试指定正确的cv2.VideoCapture参数显存不足模型过大、输入分辨率过高、并发推理运行nvidia-smi查看显存换小模型降低分辨率加队列限制并发CPU 推理非常慢没有使用 GPU或者模型参数量大查看推理日志和资源监视器使用yolov8n缩小输入尺寸YOLOv5 权重无法加载权重是旧格式或 ultralytics 版本不兼容打印模型加载异常尝试用 YOLOv5 原仓库加载或转换权重API 返回 JSON 序列化失败numpy 类型不能直接序列化查看服务端错误日志调用时把 numpy 类型转成 Python 原生类型批量任务中途卡住某张图读取失败、显存溢出、文件权限不够给批量脚本加日志记录已处理文件跳过失败文件增加重试机制排查问题时先看控制台输出再看日志文件。测试阶段建议把verboseTrue打开可以看到每个目标的坐标和置信度方便定位问题。10. 最佳实践与使用建议到这里整个系统的搭建和测试流程已经梳理完了。最后给几条实际项目里比较有用的建议。第一先跑通最小系统。不要一上来就写完整界面和摄像头逻辑。先写一个命令行检测脚本输入一张图片输出检测结果。确认模型没问题再封装 PySide6 界面。第二保留一组合适的默认参数。置信度阈值默认 0.25IOU 阈值默认 0.45这些参数要在不同场景下测试后固定下来。界面里的模型切换不要只改文件路径还要同步更新类别列表。第三模型文件、输入素材、输出结果分目录管理。建议所有权重放在weights测试图片放在inputs结果统一输出到outputs避免散落在命令执行目录里。第四批量任务要加日志和失败重试。批量处理大量图片时一个坏文件可能导致整个程序退出。在代码里逐张捕获异常记录失败文件名让程序跑完再统一检查。第五接口服务要限制访问范围。如果自己开发 API默认监听127.0.0.1不要暴露公网。如果需要局域网访问加上简单的 Token 认证避免被人随意调用消耗算力。第六涉及人脸、车牌、声音、版权素材时必须确认授权。车型识别本身不涉及人脸但摄像头画面可能拍到行人、车牌和隐私场景。商业项目部署前一定要做合规审查。第七发布或商用前要做效果复核。训练时用验证集测的是模型理想状态真实场景的天气、光照、角度都会影响效果要准备一套真实场景测试集做最终验收。11. 总结与下一步做车型识别检测系统最核心的不是 PySide6 界面而是模型和数据的匹配度。先收集好轿车、SUV、跑车、卡车四类数据训练一个能用的 YOLO 权重再把它接到 PySide6 界面里整套系统才算真正落地。第一步建议验证单张图片检测因为这一步能把环境、模型、推理流程全部跑通。最容易踩的坑是界面线程阻塞和类别映射不一致代码写完后重点检查这两处。后续扩展方向也很明确把检测结果接入数据库做车辆统计加入 ByteTrack 做多目标跟踪或者用 DeepSORT 统计车流。如果你对批量图片打标、API 服务化感兴趣也可以直接在这套代码基础上加一个 FastAPI 接口让其他系统远程调用车型识别能力。先动手跑通一个最小版本后面再逐步加功能。

相关新闻