公司动态
从YOLOv5数据集到实战部署:构建鲁棒停车位识别系统全流程解析
简介本资源是面向人工智能与计算机视觉初学者及项目实践者的停车位识别专用YOLOv5训练数据集适用于停车场智能管理、空位检测等实际场景的模型训练与算法验证。数据源自真实监控环境下的PKLot数据集涵盖晴天、阴天、雨天三类光照与天气条件共12416张高质量停车场图像每张图均标注停车位状态空置/占用并统一转换为YOLO格式的边界框标注.txt及配套配置文件.yaml便于直接导入YOLOv5框架训练。压缩包总计24834个文件含12416张JPG图像、12417个对应标签文本及1个数据集配置YAML文件整体大小866.09MB结构规范、开箱即用。已有2587人学习下载读者可直接获得完整标注数据、多场景覆盖样本及标准化目录组织显著降低数据预处理门槛加速目标检测模型的训练迭代与部署验证。1. 项目概述从一份数据集开始聊聊停车位识别的那些事儿最近在整理硬盘翻出来一个老文件名字就叫“停车位识别yolov5数据集.zip”。这让我想起了几年前做智慧停车项目时那段没日没夜标注数据、调参训练的日子。今天我就以这份数据集为引子和大家深入聊聊如何从零开始构建一个真正能用的停车位识别系统。这不仅仅是丢给你一个压缩包那么简单我会把背后的技术选型、数据处理的坑、模型训练的细节以及如何让模型在实际场景中“跑起来”的经验都掰开揉碎了讲清楚。无论你是刚接触计算机视觉的学生还是正在寻找落地方案的工程师相信这篇从实战中总结出来的长文都能给你带来实实在在的启发和帮助。停车位识别听起来简单不就是判断一个框里有没有车嘛。但真做起来你会发现这里面门道不少光照变化、车辆遮挡、车位线磨损、不同车型尺度差异……任何一个细节没处理好都可能让模型的准确率惨不忍睹。而这一切的起点就是一份高质量的数据集。我们常说的“数据决定上限模型逼近上限”在停车位识别这个任务上体现得淋漓尽致。接下来我就带你一步步拆解这个任务看看这份数据集里应该有什么我们又该如何用它“喂”出一个聪明的模型。2. 核心需求与场景拆解停车位识别到底要解决什么问题在动手处理数据或写一行代码之前我们必须先想明白停车位识别系统最终要在什么环境下工作它需要输出什么信息只有明确了需求我们准备数据、设计模型才有方向。2.1 典型应用场景分析停车位识别主要服务于两大类场景室内停车场和室外路侧停车。对于室内停车场环境相对可控。摄像头通常是固定安装的视角俯瞰光照条件虽然也有变化比如白天靠自然光晚上靠灯光但不会出现极端的逆光或暴雨天气。这里的挑战更多在于车辆密度高时的遮挡问题以及不同颜色、不同车型轿车、SUV、小型货车的车辆都需要被准确识别。此外一些高端停车场还需要识别车牌号与车位状态绑定实现自动计费和车辆引导。室外路侧停车则复杂得多。摄像头可能安装在路灯杆或建筑立面上视角多为斜侧俯视。你需要面对的变化包括从清晨到黄昏的光照剧烈变化、夜间照明不足、雨雪雾等恶劣天气、树木或建筑物的阴影遮挡、行驶中车辆的临时闯入干扰以及车位线因常年碾压导致的模糊不清。这就要求我们的模型必须具备强大的鲁棒性。2.2 功能需求定义一个完整的停车位识别系统其输出不仅仅是“有车”或“无车”的二元判断。从功能上细化它需要提供车位状态检测这是最核心的功能。识别每个划定车位内是否停有车辆。输出应为每个车位的ID和其对应的状态占用/空闲。车辆定位与计数在无法预先知道车位坐标的情况下如临时停车区系统需要能检测出图像中所有车辆的位置并统计数量。这通常用目标检测框来实现。车位线检测可选但重要对于需要动态管理或初始化的停车场系统可能需要从图像中自动检测出车位线的位置从而确定车位的坐标。这可以是一个语义分割任务或关键点检测任务。数据类型输出结果需要以结构化的方式输出通常是JSON或XML格式包含每个检测框的坐标通常是YOLO格式的归一化中心点x,y和宽高w,h、类别置信度、车位ID等方便后端系统调用。2.3 技术需求推导基于以上场景和功能我们对数据集和模型提出了明确的技术要求模型轻量化与实时性识别结果需要实时或近实时地反馈到车位引导屏或用户APP上。这意味着模型不能太大推理速度要快。这也是为什么YOLOv5这类单阶段检测器在此领域备受青睐它在精度和速度间取得了很好的平衡。小目标检测能力在俯瞰视角下尤其是大型停车场全景图中单个车辆可能只占图像的几十分之一属于小目标。数据集必须包含足够多、多尺度的小车辆样本模型也需要有针对小目标优化的设计如更密集的检测头。遮挡与截断处理车辆之间会互相遮挡车辆也可能被停车场柱子、收费亭等物体部分遮挡。数据集需要包含大量遮挡样本并正确标注可见部分。模型则需要有一定的抗遮挡能力。光照不变性数据集必须覆盖一天中不同时段、不同天气条件下的场景让模型学习到车辆的本质特征如形状、轮廓而非依赖于特定的亮度或颜色。3. 数据集深度解析你的“停车位识别yolov5数据集.zip”里应该有什么现在让我们打开这个想象中的“停车位识别yolov5数据集.zip”。一个合格的、能用于训练工业级模型的数据集绝不仅仅是几百张带标注的图片。它是一个有严格组织的系统工程。3.1 数据集目录结构规范一个标准的YOLOv5格式数据集解压后的目录结构应该清晰如下parking_space_dataset/ ├── images/ │ ├── train/ │ │ ├── parking_lot_001.jpg │ │ ├── parking_lot_002.jpg │ │ └── ... │ └── val/ │ ├── parking_lot_101.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── parking_lot_001.txt │ │ ├── parking_lot_002.txt │ │ └── ... │ └── val/ │ ├── parking_lot_101.txt │ └── ... ├── data.yaml └── README.md (可选但推荐)images/train/和images/val/分别存放训练集和验证集的图片文件。格式通常为.jpg或.png。labels/train/和labels/val/存放与图片一一对应的标注文件。每个.txt文件与图片同名。data.yaml这是数据集的“说明书”是YOLOv5训练时读取的关键配置文件。README.md说明数据集的来源、标注规范、类别定义、许可协议等信息体现专业性。3.2 标注文件格式详解YOLO格式的标注文件.txt内容很简单但每一行都至关重要。每一行代表一个目标物体格式为class_id x_center y_center width heightclass_id类别索引从0开始。例如我们定义0: car车辆1: parking_space空车位。注意对于纯车位状态识别你可能只标注车位并用0: occupied,1: free来表示状态。但更通用的做法是检测车辆间接判断车位状态。x_center, y_center边界框中心点的x和y坐标已归一化即除以图片宽度和高度后的值范围0-1。width, height边界框的宽度和高度同样已归一化。举个例子一张800x600的图片上有一辆车其边界框左上角在(200, 100)右下角在(400, 300)。那么 中心点 x (200 400)/2 / 800 300 / 800 0.375 中心点 y (100 300)/2 / 600 200 / 600 ≈ 0.333 宽度 w (400 - 200) / 800 200 / 800 0.25 高度 h (300 - 100) / 600 200 / 600 ≈ 0.333 对应的标注行就是0 0.375 0.333 0.25 0.333注意一个常见的坑是标注时框选范围。对于车辆建议框住整个可见车身包括后视镜但不必紧贴轮胎地面线可以适当留一点空隙这有助于模型学习到一定的空间容错。对于空车位通常有两种做法一是标注出车位线的四个角点更适合透视变换后做空位判断二是直接标注整个车位区域。在YOLO格式中我们通常采用第二种用一个矩形框标出整个车位区域类别为“空车位”。3.3 data.yaml 文件配置这个文件告诉YOLOv5你的数据集在哪、有什么类别。一个典型的data.yaml内容如下# 数据集路径相对于训练脚本的位置或绝对路径 path: ../parking_space_dataset train: images/train val: images/val # 类别数量 nc: 2 # 类别名称列表 names: [car, parking_space] # 可选下载地址/说明 # download: ...3.4 数据质量与多样性检查拿到一个数据集第一件事不是急着训练而是“望闻问切”检查其质量。我通常会做以下几件事可视化检查写一个简单的Python脚本随机读取一些图片和对应的标注文件将边界框画在图片上显示出来。检查标注框是否准确、有无漏标、错标例如把垃圾桶标成车。统计分布分析类别平衡统计训练集和验证集中各个类别的实例数量。如果“车”的样本数是“空车位”的10倍模型就会严重偏向于预测“车”需要对“空车位”进行过采样或数据增强。尺度分布计算所有边界框的宽高像素值绘制分布直方图。看看小目标比如宽高32像素和中大目标的比例。如果小目标极少那么模型在远距离车位上就会表现很差。位置分布检查目标是否均匀分布在图像各个区域还是都集中在中央。这关系到模型是否学到了全局特征。多样性评估人工浏览图片确保覆盖了不同天气晴、阴、雨、夜、不同时段早、中、晚、不同停车场类型地上、地下、路边、不同车型和颜色。如果数据集全是白天的晴天图片那么这个模型晚上基本就“瞎”了。4. 基于YOLOv5的模型训练全流程实操假设我们现在有了一份整理好的“停车位识别yolov5数据集.zip”接下来就是如何用它训练一个模型。这里我以YOLOv5s小型模型为例展示从环境搭建到模型导出的完整流程。4.1 环境准备与依赖安装首先需要一个Python环境3.8推荐使用Anaconda管理。然后克隆YOLOv5官方仓库并安装依赖。# 1. 克隆YOLOv5仓库 git clone https://github.com/ultralytics/yolov5 cd yolov5 # 2. 创建并激活conda环境可选但推荐 conda create -n yolov5 python3.8 conda activate yolov5 # 3. 安装依赖包 (使用国内镜像加速) pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple这里有个实操心得requirements.txt里的torch和torchvision默认会从PyPI安装CPU版本。如果你有NVIDIA GPU并需要CUDA加速最好先去 PyTorch官网 根据你的CUDA版本获取对应的安装命令。例如对于CUDA 11.8pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118安装完后再执行pip install -r requirements.txt它会跳过已安装的torch。4.2 数据准备与配置文件修改将你的parking_space_dataset文件夹放在合适的位置例如与yolov5项目目录同级。然后修改data.yaml中的路径。假设目录结构如下projects/ ├── yolov5/ └── parking_space_dataset/ ├── images/ ├── labels/ └── data.yaml那么data.yaml里的path可以写为path: ../parking_space_dataset4.3 模型训练与关键参数解析训练命令的核心是train.py脚本。一个基础的训练命令如下python train.py --img 640 --batch 16 --epochs 100 --data ../parking_space_dataset/data.yaml --weights yolov5s.pt --project runs/train --name parking_det_v1让我解释一下这些关键参数以及我通常会如何调整--img 640输入图像的尺寸。YOLOv5会自动将图片缩放到这个尺寸进行训练。为什么是640这是一个在速度和精度之间取得较好平衡的常用尺寸。对于停车场景如果摄像头分辨率高且小目标多可以尝试增大到960甚至1280但会显著增加显存消耗和训练时间。反之如果追求极致的速度如嵌入式设备可以降到416或320。--batch 16批次大小。一次迭代送入模型的图片数量。这个值越大训练越稳定但需要更多显存。你需要根据你的GPU显存来调整。RTX 3090 (24GB) 可以跑到batch32甚至更大而GTX 1660 (6GB) 可能只能跑到batch8。如果出现CUDA out of memory错误首先降低batch其次降低--img。--epochs 100训练轮数。模型会完整遍历训练集100次。如何判断是否足够需要观察训练过程中的损失loss曲线和验证集指标mAP。通常当验证集mAP在连续10-20个epoch内不再上升时就可以提前停止了使用--patience参数可以实现早停。--data .../data.yaml指定我们刚才配置的数据集描述文件路径。--weights yolov5s.pt指定预训练权重。强烈建议使用预训练权重yolov5s.pt是在COCO大型数据集上预训练好的它已经学会了识别“车”等通用物体的基本特征。从这个点开始训练迁移学习比从零开始随机初始化权重要快得多、好得多。这就是为什么你的数据集中“车”的类别名最好就叫car和COCO数据集里一致这样可以最大程度利用预训练知识。--project和--name指定训练日志、模型权重、可视化结果保存的目录。所有输出都会保存在runs/train/parking_det_v1/下非常清晰。进阶参数调整调参重点--hyp指定超参数配置文件。YOLOv5有一个默认的data/hyps/hyp.scratch-low.yaml文件里面定义了学习率、数据增强强度等一大堆超参数。对于停车位检测我通常会调整数据增强部分比如增加hsv_h色调增强来模拟不同光照增加translate平移来提升模型对车辆位置变化的鲁棒性。你可以复制一份默认的hyp文件进行修改然后通过--hyp my_hyp.yaml来指定。--rect矩形训练。如果你的数据集图片尺寸不一开启这个选项后训练时会将一个batch内的图片统一缩放到相同尺寸保持长宽比并用灰色填充边缘而不是直接拉伸变形。这可以小幅提升精度并减少计算量。--resume从上次中断的训练继续。非常实用的功能如果你的训练意外中断可以使用--resume runs/train/parking_det_v1/weights/last.pt来继续训练。4.4 训练过程监控与评估训练开始后控制台会输出日志同时会在runs/train/parking_det_v1/目录下生成一系列重要文件weights/保存了最佳模型 (best.pt) 和最后一个epoch的模型 (last.pt)。results.png这是一张综合图表是调参的核心依据。它包含了损失曲线train/box_loss,train/obj_loss,train/cls_loss应该随着epoch增加而平稳下降。val/开头的验证集损失也应该同步下降。如果验证集损失很早就开始上升而训练集损失还在降说明模型过拟合了需要增加数据增强、减少模型复杂度或使用早停。性能指标metrics/mAP_0.5和metrics/mAP_0.5:0.95。mAP_0.5是IoU阈值为0.5时的平均精度比较宽松mAP_0.5:0.95是IoU阈值从0.5到0.95步长0.05的平均值更严格。我们主要看后者它应该随着训练逐步上升并最终趋于平稳。confusion_matrix.png混淆矩阵。可以直观看到模型最容易把哪两类搞混。例如是否把“空车位”可能是画了线的矩形区域错误地预测为“车”val_batchX_labels.jpg和val_batchX_pred.jpg随机抽取的验证集图片分别显示了真实的标注框和模型的预测框。这是最直观的检查方式训练过程中可以时不时看看模型预测得准不准有没有漏检或误检。5. 模型优化与部署实战技巧训练出一个模型文件.pt只是第一步如何让它在实际应用中又快又准地运行才是真正的挑战。5.1 模型测试与性能评估训练结束后使用detect.py脚本在你自己收集的一些新图片或视频上测试模型效果python detect.py --weights runs/train/parking_det_v1/weights/best.pt --source ../test_images/ --conf 0.25 --iou 0.45 --save-txt--source可以是一张图片、一个视频文件、一个包含图片的文件夹甚至是摄像头索引如0表示电脑自带摄像头。--conf 0.25置信度阈值。只有预测框的置信度高于0.25才会被显示出来。这个值需要根据实际场景调整。如果设得太高如0.7可能会漏掉一些模糊的车辆设得太低则会出现很多误检比如把阴影当成车。通常从0.25开始根据测试结果微调。--iou 0.45非极大值抑制NMS的IoU阈值。用于合并重叠的预测框。值越小合并越严格留下的框越少。--save-txt将预测结果以YOLO格式保存为.txt文件方便后续程序处理。5.2 模型优化策略如果测试结果不理想别急着重新标注数据可以尝试以下优化路径数据增强强化这是提升模型鲁棒性性价比最高的方法。在hyp.yaml文件中可以适当增强以下参数hsv_h/hsv_s/hsv_v模拟不同光照和颜色变化。translate/scale模拟车辆在不同位置、不同距离大小的情况。mosaic: 1.0默认开启的马赛克增强将四张图拼成一张训练极大地提升了小目标检测和上下文理解能力强烈建议保持开启。mixup: 0.1以较小比例开启MixUp增强可以增加正则化效果防止过拟合。模型结构微调YOLOv5提供了--cfg参数允许你指定模型结构配置文件。对于小目标多的停车场景可以考虑将浅层特征图如P3的检测头利用得更充分或者借鉴YOLOv8的架构使用更高效的C2f模块。但这需要一定的模型架构知识。超参数调优学习率 (lr0)、权重衰减 (weight_decay) 是影响训练收敛的关键。如果训练不稳定损失震荡可以降低学习率如果模型在验证集上表现一直上不去可能是陷入了局部最优可以尝试稍微增大学习率或使用余弦退火调度器YOLOv5默认已使用。5.3 模型部署与加速训练好的.pt文件是PyTorch模型要在生产环境尤其是资源受限的边缘设备如RK3568、RV1106中部署通常需要转换和优化。模型导出YOLOv5提供了export.py脚本可以将模型导出为多种格式。python export.py --weights runs/train/parking_det_v1/weights/best.pt --include onnx engine--include onnx导出为ONNX格式。ONNX是一种开放的模型交换格式可以被TensorRT、OpenVINO、NCNN等多种推理引擎支持。--include engine在有TensorRT环境的机器上可以直接导出为TensorRT的.engine文件这是性能最优的格式。TensorRT加速针对NVIDIA GPU如果你在服务器或Jetson等设备上部署强烈建议使用TensorRT。它会对模型进行图层融合、精度校准FP16/INT8、内核自动调优能获得数倍甚至数十倍的推理速度提升。你可以使用trtexec工具将ONNX模型转换为TensorRT引擎。OpenVINO加速针对Intel CPU/GPU对于Intel平台的CPU或集成显卡OpenVINO工具包能提供最佳的优化。边缘设备部署如RK3568瑞芯微的RK3568芯片通常使用其自家的RKNN工具链。流程一般是PyTorch - ONNX - RKNN。你需要使用RKNN Toolkit2将ONNX模型转换为.rknn格式并在C或Python中调用RKNN运行时库进行推理。这里最大的坑在于算子支持YOLOv5中的某些操作如Focus新版本已替换为Conv或激活函数如SiLU可能不被RKNN完全支持需要寻找替代方案或自定义算子。5.4 构建完整应用流程模型部署好后还需要一个应用流程来处理视频流并输出结果。一个典型的Python处理循环如下import cv2 import torch from utils.general import non_max_suppression, scale_boxes # 1. 加载模型 model torch.hub.load(ultralytics/yolov5, custom, pathruns/train/parking_det_v1/weights/best.pt, devicecpu) # 或 cuda # 2. 打开视频源 cap cv2.VideoCapture(parking_lot.mp4) # 或摄像头ID while True: ret, frame cap.read() if not ret: break # 3. 推理 results model(frame) # YOLOv5 封装了预处理和推理 # 4. 后处理 (results已经包含了NMS) detections results.xyxy[0] # 获取检测结果 [x1, y1, x2, y2, conf, cls] # 5. 业务逻辑统计车位状态 car_count 0 for det in detections: x1, y1, x2, y2, conf, cls_id det if int(cls_id) 0: # 假设0是‘车’ car_count 1 # 可以在这里画框 cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2) # 6. 显示或发送结果 cv2.putText(frame, fCars: {car_count}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) cv2.imshow(Parking Detection, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()6. 避坑指南与常见问题排查在这一行做久了踩过的坑比写过的代码都多。下面这些经验希望能帮你省下大量调试时间。6.1 数据准备阶段的坑坑1标注不一致。不同的人对“车辆”的边界框范围理解不同有的紧贴车体有的包含阴影。解决方案制定详细的《标注规范文档》包含示例图并在标注前对所有人进行培训校准。可以使用CVAT、LabelImg等工具的统一模板功能。坑2类别定义模糊。比如一辆正在驶入车位、一半在车位内的车算“占用”还是“空闲”解决方案在业务逻辑层定义清晰规则。例如规定“车辆边界框与车位区域IoU大于0.5即视为占用”并在标注时遵循此规则或者在后续处理中根据检测框与预设车位线的位置关系进行判断。坑3数据泄露。不小心将同一停车场、不同时间但角度几乎相同的图片分别放入了训练集和验证集导致验证指标虚高。解决方案严格按场景或视频序列划分数据集。如果数据来自多个停车场确保同一个停车场的所有图片只出现在训练集或验证集之一。6.2 模型训练阶段的坑问题1损失不下降或NaN。可能原因学习率设置过高数据标注有严重错误如坐标超出0-1范围批次大小太小梯度不稳定。排查首先检查数据标注用可视化脚本看看。然后大幅降低学习率如从0.01降到0.001试试。确保批次大小在硬件允许范围内尽可能大。问题2验证集mAP很低但训练集损失正常。可能原因严重的过拟合。模型只记住了训练集的特例没有学到泛化特征。解决① 增加数据增强的强度在hyp文件中调整。② 如果数据集本身很小尝试收集更多数据。③ 使用更小的模型如从YOLOv5m换到YOLOv5s。④ 在模型中添加Dropout层需修改模型结构文件。⑤ 使用早停--patience参数。问题3小目标检测效果差。可能原因数据集中小目标样本不足模型输入尺寸--img太小小目标在下采样中信息丢失严重。解决① 增加输入尺寸如从640到960。② 在数据集中主动补充远距离、小车辆的图片。③ 检查模型结构确保用于检测小目标的特征图如P3通道数足够可以尝试修改模型配置文件增加该检测头的宽度。6.3 部署与应用阶段的坑坑1训练精度高部署后效果差。可能原因A领域偏移。训练数据是晴天白天部署环境是地下车库。解决必须在部署前用目标环境的数据即使没标注对模型进行测试必要时进行微调fine-tuning。可能原因B预处理/后处理不一致。训练时YOLOv5有自动的预处理归一化、BGR-RGB等自己写部署代码时漏掉了。解决仔细核对推理代码中的预处理步骤必须与训练时保持一致。可以直接使用YOLOv5提供的model.preprocess和model.postprocess方法。坑2边缘设备上推理速度慢。排查先用性能分析工具如RKNN的profiling看耗时主要在哪个阶段。通常是模型推理本身。优化① 使用量化。将FP32模型量化为INT8速度通常能提升2-3倍精度损失可控。TensorRT和RKNN都支持INT8量化但需要一部分校准数据。② 优化模型结构。尝试YOLOv5n纳米级或专门为边缘设备设计的模型如NanoDet。③ 降低输入分辨率。这是最直接有效的方法但会牺牲小目标检测精度需要权衡。坑3误检和漏检的实时处理。场景树叶晃动、行人走过、灯光闪烁可能被误检为车深色车辆在夜间可能漏检。策略单纯靠单帧检测很难完美解决。引入时间上下文信息是关键。例如对一个车位区域连续10帧中有8帧以上都检测到车才判定为“占用”从“占用”变为“空闲”也需要连续多帧无车才切换状态。这能有效过滤瞬时干扰。从一份名为“停车位识别yolov5数据集.zip”的文件出发我们实际上走完了一个完整的计算机视觉项目闭环需求分析、数据工程、模型训练、优化调参、部署落地和问题排查。每一个环节都有无数的细节和选择而经验就来自于在每一个岔路口做出的判断和踩过的坑。这份数据集只是一个起点真正的价值在于你如何用它去定义问题、解决问题并最终让一个模型在真实的场景中稳定、可靠地工作。记住没有一劳永逸的模型只有持续迭代的优化。当你发现模型在雨天表现不佳时就去补充雨天的数据当它在某个特定车位总是误检时就去分析那个位置的图像特征。这个过程本身就是AI工程实践中最有魅力的部分。本文还有配套的精品资源点击获取