ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

YOLOv8停车位检测实战:数据集构建与模型部署全流程

YOLOv8停车位检测实战:数据集构建与模型部署全流程 简介本资源是专为停车位目标检测任务设计的YOLOv8格式数据集面向计算机视觉初学者、智能交通系统开发者及YOLO系列模型实践者适用于停车场自动化管理、车位状态识别等实际场景。数据集共1520张原始图像经标准化预处理EXIF定向校正、统一缩放至640×640与丰富增强含水平/垂直翻转、±15°旋转、亮度扰动、高斯模糊及椒盐噪声后扩展为完整训练体系压缩包内含479张JPG图像、1520个对应YOLOv8格式TXT标签文件及1个配置用YAML文件总计2000个文件整体大小164.36MB。已有162人下载学习资源结构清晰、开箱即用可直接用于YOLOv8模型训练、验证与测试全流程显著降低数据准备门槛加速停车位检测算法落地验证。 第一次做停车位检测的时候我在地下车库蹲了一下午手动框了几百张图回来训练完发现模型把旁边刷了漆的柱子也当成了车位。后来才明白停车位检测真正的难点不在“检测”本身而在“数据集怎么定义、标注怎么统一、正负样本怎么平衡”。这篇文章我就用YOLOv8这条线把停车位检测从数据准备、标注规范、训练调参到落地部署的完整流程拆开讲一遍所有步骤都是我自己实测跑通的方案适合刚入手目标检测、想用自有数据训练YOLOv8的开发者参考。1. 项目设计思路与方案选型1.1 停车位检测到底在解决什么问题停车位检测从功能上分其实是两个完全不同的任务一个是“固定车位识别”也就是识别某个车位是否被占用常用于停车场管理系统、车位引导大屏另一个是“可用车位发现”也就是在开放场景里找到哪些地方能停车常用于自动泊车或者代客泊车。两者的共同点是都要先找到车位区域区别在于前者还多了一个“占用状态分类”的步骤。落实到目标检测视角最直接的做法就是把“空车位”和“占用车位”分别当作不同类别来检测甚至可以把“占用”细分为“小轿车占用”“SUV占用”等。这种方法的好处是端到端输入图像直接输出车位框和状态不需要额外的后处理策略。缺点是对数据要求高尤其是“空车位”这个类别特征极其不稳定不同材质地面、光照、标线清晰度都会影响检测结果。我做这个项目时最终选了YOLOv8核心原因是它在精度和速度之间平衡得很好而且在同级别模型里对小目标的容忍度更高。停车位在图像里往往不是画面主体尤其是俯视角度或者远距离监控画面里车位占整个图像的比例可能只有几个百分点这种情况下YOLO系列的anchor-free改进比早期anchor-based方案更稳。1.2 为什么选YOLOv8而不是其他方案对比过几类常见的方案之后我简单梳理一下选型依据方案优势劣势适用场景传统图像处理边缘检测霍夫变换无需训练速度快对光照、遮挡极度敏感标线不清就废标线清晰的室内固定场景语义分割U-Net/DeepLabV3能精确到像素级车位区域标注成本高推理速度慢自动泊车、高精度车位定位YOLOv5/v8目标检测训练链路成熟推理快标注成本相对低车位框是矩形不能精确贴合倾斜车位停车场监控、车位引导旋转框检测MMRotate能输出带角度的检测框标注复杂生态不如YOLO倾斜车位占主流的室外场景我在实际对比后发现大部分商业停车场和路边停车场景矩形框加上适当的后处理已经能满足需求。如果车位倾斜角度特别大可以先把图像做透视矫正再做水平框检测效果比直接上旋转框检测更稳。而且YOLOv8的部署生态好从训练到ONNX再到OpenCV或者TensorRT都有现成路径这一点在项目落地时特别重要。1.3 数据集规划的总体思路停车位检测数据集和通用目标检测数据集有个明显的差异类别之间的区分度可能很低。一辆白色车停在灰色车位上车身的边缘和车位标线的边缘在图像里特别容易混淆。所以数据集规划时必须考虑三个核心点场景多样性室内停车场、室外露天停车场、路边划线车位、不同光线条件白天/夜晚/逆光、不同天气雨天反光、雪天遮挡。角度覆盖监控摄像头俯视、行车记录仪平视、手机拍摄斜视每种角度下同一类别的特征差异非常大。状态标注一致性空车位和占用车位的边界标准要不统一就导致模型学不到正确的特征。例如“占用”类别如果一部分框的是整车另一部分框的是车轮附近模型训练时会严重震荡。我自己在规划数据集时是按“采集场景-去重-初步筛选-标注-二次筛选”这个流程走的总共整理3000到5000张图标注2万到3万个目标框。后面我会详细展开每一步的关键操作这里先说结论真正决定模型上限的不是图片数量而是标注质量和场景覆盖面。2. 数据集构建与标注规范详解2.1 数据采集的渠道与注意事项停车位检测数据集的来源主要有三种自有采集、公开数据集、网络爬取。自有采集最可靠但成本高公开数据集省事但场景可能和你的应用不匹配网络爬取需要大量人工清洗否则脏数据会把训练结果搞崩。自有采集时建议把手机或运动相机固定在车辆挡风玻璃、车顶或手持支架上模拟摄像头安装高度。我用的方案是行车记录仪截帧因为行车记录仪视角和停车场监控视角比较接近而且分辨率足够。截帧时不要连续截取每隔2到3秒取一帧否则相邻帧高度相似训练集信息密度太低还容易造成过拟合。公开数据集方面可以找KITTI、BDD100K、Aeroscapes这些通用数据集中包含停车场景的部分来做迁移学习预热。但要注意标注格式可能不同YOLOv8用txt格式每行一个目标格式是“类别ID x_center y_center width height”全局归一化。转换格式时建议写脚本批量处理不要手动改。2.2 标注标准怎么定才不会被坑这是整个项目里最容易踩坑的环节。我见过很多同学标注时“凭感觉”结果是不同批次的标注标准偏差很大训练时损失函数死活降不下去。先确定一个基础原则标注对象是车位区域而不是车辆。对于“占用”类别框的中心可以放在车辆上但框的范围必须按车位标线来框。这样做的原因是模型在推理时才能用统一的坐标语义去判断“这个车位被占用了”而不是“这里有一辆车”。如果按车辆边界框标注两个不同距离的车位会训练出完全不同的目标尺度严重影响泛化能力。具体标注规则可以这样定类别0表示空车位类别1表示占用车位。空车位必须看到至少两条完整标线左线和底线否则不标注。占用车位要求车位内停有车辆不管车辆是否完全在画面内只要车位的标线可辨认就按车位外接矩形标注。标线完全模糊或被大面积遮挡的车位不标注不强行猜测。同一张图中空车位和占用车位都要尽量全部标注不要只标一部分否则会影响正负样本比例。标注工具我用的是LabelImg和X-AnyLabeling前者是老牌工具快捷键顺手后者支持半自动预标注能提高效率。半自动预标注的做法是先用一个初步训练好的模型对图片生成伪标注然后人工修正这样在大批量数据集上能节省一半以上的标注时间。2.3 YOLOv8数据集目录结构与格式转换YOLOv8的数据集目录有固定要求建议按下面的结构组织dataset/ ├── images/ │ ├── train/ # 训练集图片 │ └── val/ # 验证集图片 └── labels/ ├── train/ # 训练集标签txt └── val/ # 验证集标签txt每个txt文件名必须和对应图片文件名一致后缀是.txt不是.label。每行内容格式是class_id x_center y_center width height注意x_center、y_center、width、height都是归一化到0到1的浮点数不是像素坐标。如果你是其他格式的标注比如VOC的XML或者COCO的JSON需要写脚本转换。我推荐直接用ultralytics的转换脚本做基础处理再针对停车位场景微调。转换时容易忽略的一个问题是YOLOv8的类别ID必须从0开始连续递增不能跳号。如果标注工具导出的类别ID是从1开始的一定要在脚本里减1否则训练时会报类别越界的错误。2.4 数据增强策略与正负样本平衡数据增强是提升模型泛化能力的关键但增强策略必须贴合场景。停车位检测场景里最有效的增强手段依次是随机翻转水平翻转停车位左右对称水平翻转变换后语义不变能直接翻倍数据量。亮度对比度调整模拟早晚光照变化增强对光照变化的鲁棒性。HSV扰动调整色调、饱和度、明度模拟不同地面材质和灯光色温。随机裁剪和缩放模拟不同摄像头距离和焦距变化增强多尺度检测能力。不建议使用的增强包括大幅旋转停车位方向性太强、随机擦除容易把关键标线擦掉、马赛克增强权重调太高虽然Ultralytics默认开启了Mosaic但停车位目标尺度相对单一Mosaic对小目标提升明显对中尺度目标作用有限还会拉长训练时间。正负样本平衡方面空车位和占用车位的数量比例最好控制在1比1到1比2之间。我做过实验空车位数量严重不足时模型对占用车位的召回率很高但空车位的精度惨不忍睹很容易把地面反光、阴影、单车停放的位置误判为空车位。均衡数据的手段有两个一是采样时控制图片比例二是对少数类别做重复采样或适当复制粘贴增强。3. YOLOv8训练实操与关键参数调优3.1 环境配置与依赖安装YOLOv8的训练环境建议用Python 3.10及以上版本PyTorch按官方推荐安装对应CUDA版本的预编译包。网络原因可能较慢但代码库依赖比较简单核心就是ultralytics包和pytorch。我的环境配置大致如下python 3.10.12 torch 2.1.0 cu118 ultralytics 8.1.0 opencv-python 4.9.0安装命令很简单pip安装ultralytics会自动拉取大部分依赖。这里有一个坑如果你的显卡比较老比如GTX 1660 Ti这种图灵架构不带Tensor Core的卡建议把torch装成CPU版反而更快因为同代CPU性能不错的情况下省去了GPU和CPU之间的数据拷贝开销。当然这是权宜之计正常项目还是建议用支持CUDA的GPU。我测试过的配置里GTX 1660 Ti 6GB显存batch size设为8跑YOLOv8s是可以的batch size设为16就会报显存不足。如果你的显存只有4GB建议直接用YOLOv8n或者降分辨率到640x480训练。3.2 数据集配置文件与模型选择YOLOv8的数据集配置是一个yaml文件放在项目目录下即可。示例内容如下path: /path/to/dataset # 数据集根目录 train: images/train # 训练集图片相对路径 val: images/val # 验证集图片相对路径 nc: 2 # 类别数量 names: [empty, occupied] # 类别名称这里的path可以填相对路径或绝对路径。在训练时指定data参数指向这个yaml文件即可。模型选择方面YOLOv8官方提供了n、s、m、l、x五个型号从轻量到重量级。停车位检测属于中度复杂度任务YOLOv8s是性价比最高的选择。检测精度上在相同数据下m和l的mAP50可能比s高2到5个点但推理帧率下降明显部署到嵌入式设备几乎不现实。我的建议是先用s做基准再根据实际情况决定是否上m。3.3 训练参数详解与效果验证一个典型的停车位检测YOLOv8训练命令如下yolo detect train dataparking.yaml modelyolov8s.pt epochs100 imgsz640 batch8 device0 workers4epochs我推荐初始设100然后用早停机制在性能不再提升时自动停止。imgsz的默认640一般够用但如果你的数据集图片比较小或者车位区域很小可以试imgsz960这会对小目标检测有显著帮助代价是训练时间增加和显存占用提升。训练过程中要盯的关键指标不是训练集的loss而是验证集的mAP50和mAP50-95。mAP50是IoU阈值0.5时的平均精度mAP50-95是在0.5到0.95区间内多个阈值下的平均值后者更严格反映检测框的定位精度。停车位检测场景下mAP50高于0.9是比较理想的状态mAP50-95能达到0.7以上就已经很能打了。如果mAP50很高但mAP50-95很低说明检测框定位不够精确常见原因是标注框不够紧贴车位标线。还有一个实用技巧训练过程中直接跑一次验证集推理把预测结果可视化输出成图片来看。不要只看指标数字因为mAP高不代表所有困难场景都好。我曾经遇到过mAP500.93但模型对两个相邻空车位之间的分隔线完全没学会的情况从指标上完全看不出来只有看可视化结果才发现。3.4 损失函数曲线图的绘制与解读训练结束后训练日志里会输出loss和mAP变化数据用Ultralytics自带的plot工具或者直接把results.csv读出来用matplotlib画曲线。我习惯把train/box_loss、val/box_loss和mAP50画在同一张图上重点观察三点box_loss和cls_loss持续下降且val版本没有明显回升说明没有过拟合。mAP50在中期快速上升后期趋于平稳这是正常现象。如果mAP50在训练中出现剧烈波动大概率是数据标注噪声太大或batch size过小可以尝试增大batch size或降低学习率。一个判断训练是否收敛的朴素经验最后20个epoch的val/box_loss标准差小于0.01就可以认为基本收敛了。如果还不收敛再加epoch也就是过拟合没必要继续烧显卡。4. 推理部署、性能优化与常见问题排查4.1 模型导出与推理流程训练完成后把.pt模型导出为ONNX格式可以跨平台部署yolo export modelbest.pt formatonnx imgsz640导出ONNX之后可以用ONNX Runtime在CPU上推理也可以转成TensorRT在NVIDIA GPU上加速。对于边缘设备比如Jetson系列转成TensorRT后推理速度能提升2到3倍。但TensorRT转换对模型算子的支持有版本限制如果遇到不支持的算子可以先尝试更新TensorRT版本或者回到ONNX Runtime方案。在标准PC上YOLOv8s的ONNX模型用ONNX Runtime跑640x640输入推理耗时大约在30到50毫秒完全满足停车场道闸、监控摄像头这些场景的实时性要求。如果需要在嵌入式设备上跑建议改用YOLOv8n半精度FP16下帧率可达20到25帧。4.2 常用优化置信度阈值与NMS参数训练好的模型默认的置信度阈值是0.25但这个值在停车位检测场景下不一定合适。空车位的特征简单模型可能给出很高的置信度占用车位如果车辆颜色和地面接近置信度则可能偏低。我在实际测试中会把置信度阈值调到0.15到0.3之间重新验证宁可多输出一些候选框再通过后处理过滤也不要漏检。NMS的IoU阈值默认是0.45如果画面里相邻车位挨得很近这个值可能会导致两个相邻车位被合并成一个框。我建议把这个值调小到0.3或0.35这样相邻车位的框不容易互相抑制代价是可能出现重叠的假阳性需要在后处理里加一个基于车位尺寸约束的过滤规则比如框的宽高比必须在0.5到2.5之间。4.3 实际场景中的误检与漏检调优实际运行中停车位检测最容易出现两类问题一类是把地面阴影、水渍、轮胎印误检成空车位另一类是把倾斜车辆的两个车轮当成两个小目标。处理阴影误检的有效方案是增加一个“不可用车位”类别把阴影覆盖较多的车位单独标注并加入训练。模型学会区分阴影和水渍后误检率会明显下降。这里要注意不要试图用简单的颜色阈值或者HSV滤波去后处理因为不同地面材质和灯光条件下阴影的颜色特征不稳定学出来的规则很容易过拟合。处理车轮误检的另一个技巧是尽量标注完整车位框而不是按车辆的可视区域标注。之前我提到过这一点在推理阶段它会转化为一个好处模型输出的框尺度一致性高可以通过统计训练集的框宽高分布设定合理的尺寸过滤范围。对于我的数据集空车位的框宽度集中在0.3到0.45归一化后超出这个范围50%的检测结果直接丢弃能过滤掉大部分误检。4.4 常见问题速查表我把训练和部署过程中最常遇到的坑整理成了表格判断依据和解决办法都写在里面问题现象可能原因解决办法训练loss不下降或剧烈震荡标注框坐标误差过大类别ID不连续重新审查标注统一标注标准mAP50很高但推理时漏检严重测试图片场景与训练集差异过大增加目标场景数据做领域自适应推理结果大量重叠框NMS阈值过高或类别间特征太接近降低NMS IoU阈值到0.3增加尺寸约束GTX 1660 Ti训练时显存不足batch size过大或图像分辨率过高改用YOLOv8n或降低imgsz到480导出ONNX后推理速度反而慢CPU推理或模型未做半精度优化启用FP16或转TensorRT加速检测框比车位标线偏大偏小标注框没有紧贴标线区域重新贴边标注重点检查边缘是否多框了地面空车位和占用车位互相误判正负样本比例失衡或特征区分度不够增加空车位样本做好平衡4.5 部署场景的扩展思路停车位检测做完基础版本后很多场景可以继续扩展。例如把检测结果和时间戳关联起来实现车位的长时间占用分析或者用跟踪算法关联连续帧的检测框解决同一车位的重复计数问题再或者接上扬声器或LED指示牌做成实时的车位引导系统。我个人的经验是这个项目做到后面花在模型上的时间反而越来越少更多时间用在了数据处理和业务逻辑上。比如停车场出入口的车牌识别联动、空车位的路径规划引导这些都需要把检测结果和更上层的信息系统打通。如果你只是做一个毕业设计或者技术验证把模型和推理部署做好已经足够如果是商业落地项目务必留出充足的时间做场景适配测试因为现场的光线、摄像头角度、地面材质和你采集数据时的差异往往比想象中大得多。本文还有配套的精品资源点击获取
返回列表