news 2026/10/1 11:03:31

泊车位检测数据集:YOLOv8训练与VOC/COCO/YOLO标签格式详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
泊车位检测数据集:YOLOv8训练与VOC/COCO/YOLO标签格式详解

简介:面向目标检测开发者和课程学习者,这份YOLO泊车位数据集包含1000张真实场景的高质量图片,场景丰富,采用LabelImg标注,框质量高,并提供VOC、COCO、YOLO三种格式标签分别存放,兼容常见检测框架,可直接用于主流YOLO系列模型训练、验证与评估,省去格式转换环节。包内共2000个文件,涵盖xml/txt标注文件、环境搭建与训练教程html文档、数据划分py脚本和模型yaml配置等,压缩包约238.49MB,目录结构清晰,便于按格式和用途检索。配套Linux和Windows环境搭建教程、训练案例教程,以及训练集/验证集/测试集划分脚本,可一键按需拆分数据,快速跑通从环境配置到模型训练的全流程。目前已有507人学习使用,适合做泊车位检测项目、课程设计或入门目标检测的读者参考。

1. 泊车位检测为什么绕不开这份1000张图的数据集

做自动泊车、车位引导或者智慧停车项目时,第一步就把很多人卡住了:没有自己的泊车位图片,拿什么去喂YOLO?这份数据集直接给到了1000张泊车位图片,而且每个目标都配套VOC、COCO、YOLO三种格式的标签文件,连划分脚本和训练教程都放在压缩包里。也就是说,从解压到跑通YOLOv8训练,中间不需要再自己找数据、转格式、手写划分。适合刚入目标检测的新手用来走通完整流程,也适合急着出一版泊车位检测原型的工程师直接拿去做基线。它解决的核心问题不是算法多难,而是“数据准备和格式转换”这个最容易被低估的坑。

2. 拆解三种标签格式:VOC、COCO、YOLO到底各存了什么

2.1 VOC格式:XML里的object逐个拆解

VOC格式的标签是XML文件,每个图片对应一个同名XML。打开后你会看到一堆<object>节点,每个节点描述一个目标。

<annotation> <folder>VOC2007</folder> <filename>parking_012.jpg</filename> <size> <width>1920</width> <height>1080</height> <depth>3</depth> </size> <object> <name>parking_space</name> <bndbox> <xmin>300</xmin> <ymin>400</ymin> <xmax>800</xmax> <ymax>600</ymax> </bndbox> <difficult>0</difficult> </object> </annotation>

上面这段XML是这份数据集里很典型的泊车位框。bndbox四个值记录目标左上角和右下角的像素坐标,是绝对值而非归一化值。difficult为0表示这个车位可用,如果标成1,通常表示被车遮挡或者太远连人眼都难确认,训练时YOLO会默认忽略这类框。泊车位检测里一个车位就是一个object,类别名就是parking_space。

2.2 COCO格式:JSON里的categories与annotations

COCO格式把整份数据集的标注集中到一个JSON文件里,结构分为images、annotations和categories三个大数组。

{ "images": [ { "id": 1, "file_name": "parking_012.jpg", "width": 1920, "height": 1080 } ], "annotations": [ { "id": 1, "image_id": 1, "category_id": 1, "bbox": [300, 400, 500, 200], "area": 100000, "iscrowd": 0 } ], "categories": [ { "id": 1, "name": "parking_space" } ] }

注意COCO的bbox跟VOC不一样,它是[x, y, width, height],也就是左上角坐标加上框的宽高。area在泊车位场景里可以直接用width*height计算,iscrowd这个字段对泊车位来说基本是0,因为车位很少出现密集重叠到无法单个标注的情况。如果后续你想用COCO预训练模型或者做实例分割,这个JSON就是基础。

2.3 YOLO格式:txt里的class和归一化坐标

YOLO格式是训练时真正会读入的标签。每张图片对应一个同名的txt文件,每一行代表一个目标。

0 0.2865 0.4630 0.2604 0.1852

这一行里第一个数字是类别ID,因为只有泊车位一个类别,所以是0。后面四个数字分别是目标的中心点x、中心点y、框宽w、框高h,全部除以图片宽高做了归一化,取值范围在0到1之间。这就是YOLO训练时输入的标准格式。如果图片宽1920、高1080,这个txt对应的实际像素框就是中心点(550, 500),宽500,高200。

2.4 三种格式怎么互相转换:一份数据三份标签的意义

格式存储方式坐标表示训练适用
VOC每个图片一个XMLxmin, ymin, xmax, ymax绝对值老牌检测模型、数据可视化
COCO全部标注一个JSONx, y, width, height绝对值Mask R-CNN、Detectron2、实例分割
YOLO每个图片一个txtcx, cy, w, h归一化YOLO全系、RT-DETR

这份数据集直接给全三种格式,最大的意义不是让你去选一个用,而是省掉转换脚本的调试成本。实际转换过程中最常出问题的就是坐标系的混用:VOC转YOLO要把(xmin, ymin, xmax, ymax)换算成中心点加宽高,COCO转YOLO则必须先把绝对宽高转成归一化。一步算错,框就飘了。有了三种现成标签,你可以用VOC格式做校验可视化,用COCO格式做通用模型的直接训练,用YOLO格式跑YOLOv8/YOLOv11,互相对照,出了问题很容易定位是哪一环节的坐标算错。

3. 用划分脚本切分数据集:训练/验证/测试的比例与随机种子

3.1 划分脚本的核心逻辑

做目标检测训练时,数据切分不是简单粗暴地把文件分开,它需要保证图片和标签严格同步。很多新手只把图片挪走了,标签没跟上,训练时直接报错No labels in xxx。这份数据集里的划分脚本解决的就是这个同步问题。脚本的逻辑很简单:遍历所有图片文件名,按设定比例随机拆成训练、验证、测试三份,然后把对应的标签文件路径写进三个txt文件里。同一份文件名在三个txt中不能重复,这是脚本的基本底线。

3.2 Python实现train/val/test划分脚本

网上能下载到的划分脚本大多长这样,核心逻辑完全可以拿来自用:

import os import random from sklearn.model_selection import train_test_split # 数据集路径 data_dir = "parking_dataset" image_dir = os.path.join(data_dir, "images") label_dir = os.path.join(data_dir, "yolo_labels") # 收集所有图片文件名,不带后缀 img_files = [f.split(".")[0] for f in os.listdir(image_dir) if f.endswith(".jpg")] print(f"共找到 {len(img_files)} 张图片") # 按7:2:1划分训练、验证、测试 train_files, test_files = train_test_split(img_files, test_size=0.1, random_state=42) train_files, val_files = train_test_split(train_files, test_size=0.222, random_state=42) # 将划分结果写入txt for split, files in [("train", train_files), ("val", val_files), ("test", test_files)]: with open(f"{split}.txt", "w") as f: for name in files: img_path = os.path.join(image_dir, name + ".jpg") label_path = os.path.join(label_dir, name + ".txt") # 确保图片和标签都存在才写入 if os.path.exists(img_path) and os.path.exists(label_path): f.write(img_path + "\n") print(f"{split} 数量: {len(files)}") print("划分完成,请检查 train.txt / val.txt / test.txt")

test_size=0.1先分出10%的测试集,剩余90%再按0.222分出20%验证集,实际比例约7:2:1。random_state=42固定随机种子,这样每次运行脚本得到的划分结果一致,方便复现模型效果。脚本里os.path.exists检查双重保证图片和标签路径都有效,这一步非常关键,很多数据集里存在孤儿图片或者孤儿标签,漏掉检查会让后续训练白跑几小时。

3.3 划分后必须检查的三件事

划分完成不是直接开练,先花两分钟做三个检查。第一是类别平衡:统计三个txt文件里各自的类别数量,泊车位数据一般单类别,如果验证集里样本特别少,模型的验证分数波动会很大。第二是场景覆盖:泊车位场景往往包含室内地下车库和室外露天停车场,如果全部室外图都被分进训练集,验证集就失真了。第三是文件对应:随机挑一个txt文件里的第一个路径,确认图片能正常打开且有同名标签文件。

3.4 同步三种格式的划分

这份数据集的划分脚本一般是一个py文件,跑完只生成训练列表txt,不会去复制或移动原文件。真正训练时YOLOv8只需要train.txt里写的图片路径,标签路径会自动根据图片路径推导。但如果你计划用VOC或者COCO格式去训练其他模型,就得保证划分列表对三种格式都适用。常见做法是保留一份图片文件清单,三个训练脚本都读这份清单,而不是各自维护一套路径。我一般会把train.txt / val.txt / test.txt里的路径统一改为图片绝对路径,再把标签目录名从images换成labels交给YOLO自动推导,这样无论怎么切换格式都不需要重新划分。

4. 用YOLOv8在泊车位数据集上跑通训练:参数与命令

4.1 环境准备:conda创建虚拟环境并安装ultralytics

拿到数据后第一件事是搭环境。强烈建议用conda建独立环境,别把YOLO装到基础Python环境里,免得和TensorFlow、PyTorch老版本打架。

conda create -n parking python=3.10 -y conda activate parking pip install ultralytics

ultralytics这个包已经集成了YOLOv5、YOLOv8和YOLOv11,一条命令就能下载训练好的预训练模型权重。这里不需要手动去下载单独的模型文件,训练时指定model=yolov8n.pt,首次运行会自动从官方地址拉取。如果网络条件不理想,也可以提前手动把权重文件放到当前目录。

4.2 准备YAML配置文件与数据集目录结构

YOLOv8训练需要先准备一个data.yaml文件,描述数据集路径和类别信息。这份数据集解压后典型的目录结构是images/和labels/分别存放图片和YOLO格式标注。

# parking.yaml path: /home/you/parking_dataset train: train.txt val: val.txt test: test.txt nc: 1 names: ['parking_space']

path是数据集根目录绝对路径,train和val指向之前划分脚本生成的txt文件。这里有个容易踩的坑:如果txt里写的是绝对路径,train字段填train.txt即可;如果txt里写的是相对路径,就得在这里补上images/前缀。nc: 1指的是只有泊车位一个类别,names里的类别名必须和训练标签中的类别ID对应上,顺序不能错。

4.3 启动训练:训练命令与关键参数说明

环境配好、数据就位后,一行命令就能跑起来:

yolo train data=parking.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16 device=0

epochs=100代表完整遍历训练集100轮,泊车位检测这类单类别任务一般60轮就能收敛,100轮是为了观察过拟合趋势。imgsz=640把输入图片等比缩放到640x640,这个值不是越大越好,图片太大显存占用暴涨,太小会丢失小目标的细节。batch=16是每批送入的图片数,显存不足时报错CUDA out of memory就把它降到8或者4。device=0指定第一块GPU训练。数据集里1000张图,单卡训练一轮大概一两分钟,整体几小时能完成。

4.4 训练结束后看什么:metrics、混淆矩阵、验证集推理

训练默认会在runs/detect/train/下输出结果。头一个看results.csv,里面每一行是每一轮的train_loss、val_loss、mAP50等指标。泊车位检测重点关注mAP50-95,它比mAP50更严格,反映框位置的精准度。再看confusion_matrix.png,能直观看到有没有把车位误检为背景或者漏检。最后用一句命令跑验证集推理:

yolo predict model=runs/detect/train/weights/best.pt source=test_images/ save=True

注意这里source要指向测试集图片目录,save=True会把检测框画在图上保存下来。肉眼扫一遍这些图,比单看数字更能判断模型真实水平。

5. 泊车位数据集训练避坑与常见问题排查

5.1 标签文件为空导致训练报错“No labels”

现象:训练启动后没报错,但打印出WARNING ⚠️ no labels found in datasets/train/images/parking_001.jpg,有大量图片没参与训练。

原因:标签文件名和图片名没有一一对应,或者标签文件是空的。有些标注工具导出的txt只有一行换行符,看起来存在,实际没有任何目标。

解决:写个小脚本统计所有空标签文件,并把对应的图片从训练目录挪出去,不要留在里面浪费训练时间。

import os label_dir = "labels" empty_files = [] for f in os.listdir(label_dir): path = os.path.join(label_dir, f) if os.path.getsize(path) == 0: empty_files.append(f) print(f"空标签文件数量: {len(empty_files)}") for f in empty_files: print(f)

5.2 训练过程中BN层崩溃

现象:训练到几十轮时,train_loss突然变成nan,或者metrics全部归零,之后无法恢复。

原因:BN层崩溃通常由训练不稳定引起,常见诱因是学习率太大或者batch太小。batch=4时BN统计量方差特别大,容易产生数值溢出。

解决:把batch调到16以上,或者降低初始学习率lr0=0.001。另一个有效手段是开启cache=True,把图片直接缓存到显存,减少IO波动。

yolo train data=parking.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16 lr0=0.001 cache=True

5.3 类别数量对不上导致训练报错

现象:训练时报AssertionError: impossible to satisfy constraints,或者加载权重时提示类别数不匹配。

原因:data.yaml里nc和names的定义与实际标签ID对不上。这张数据集里类别名虽然只有一种,但如果标签tx里出现类别ID为1或2的框,而nc=1,就会出问题。

解决:打开几个txt文件看一眼里面第一位数字最大值,把nc改为最大值加1,names按顺序列出所有类别名。

5.4 分割线或车位线被数据增强搞丢

现象:训练完发现验证框总比实际车位小一圈,或者漏检侧方停车的车位线。

原因:YOLO默认开启hsv_h、hsv_s、hsv_v色彩增强,以及随机旋转degrees。泊车位检测依赖车位线的颜色和方向,增强过头会让这些特征失真。

解决:在训练命令里调整增强参数:

yolo train data=parking.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16 hsv_h=0.0 hsv_s=0.2 hsv_v=0.2 degrees=5

5.5 不同格式转换时坐标越界

现象:用VOC的XML转成YOLO txt时,某些行出现x_center大于1或者w为负值的情况。

原因:标注时框的左上角坐标大于右下角坐标,或者目标跨越图片边缘导致宽高计算超出范围。很多标注工具允许画出界框,转换脚本没有做裁剪。

解决:转换时加边界裁剪逻辑:

x_center = (xmin + xmax) / 2 / width y_center = (ymin + ymax) / 2 / height w = (xmax - xmin) / width h = (ymax - ymin) / height x_center = min(max(x_center, 0), 1) y_center = min(max(y_center, 0), 1) w = min(w, 1) h = min(h, 1)

6. 泊车位检测的进阶验证与优化:从mAP曲线到数据扩充

6.1 用混淆矩阵判断漏检与误检

训练结束后,别急着部署。先打开runs/detect/train/confusion_matrix.png,看清四个象限:真正例是预测为泊车位且真实就是泊车位,假负例是真实车位但模型没检测出来。泊车位检测最常见的漏检发生在车位线模糊的地面,比如水泥地上磨损严重的白线。如果假负例集中在某个特定停车场,说明训练数据里那个场景的样本不够。

6.2 批量可视化测试集结果找规律

写一个批量预测脚本,把所有测试图片的检测结果拼成一张大图,快速浏览:

from ultralytics import YOLO import os import cv2 model = YOLO("runs/detect/train/weights/best.pt") test_dir = "test_images" output_dir = "pred_output" os.makedirs(output_dir, exist_ok=True) for img_name in os.listdir(test_dir): result = model.predict(os.path.join(test_dir, img_name), conf=0.25) annotated = result[0].plot() cv2.imwrite(os.path.join(output_dir, img_name), annotated) print("预测结果已保存到 pred_output 目录")

conf=0.25是置信度阈值,低于这个分数的框会被滤掉。泊车位检测建议用0.3到0.4之间,太低会把地面阴影当车位,太高会漏掉远处的小车位。跑完后把输出目录里的图按“正常”“漏检”“误检”分三堆,能快速定位模型的系统性问题。

6.3 数据扩充的方向:不是无脑加图

泊车位检测的数据扩充,最先加的不是更多车位图片,而是场景多样性。地下车库的灯光偏黄、垂直车位和斜车位角度差异大、雨天反光严重,这些都比单纯增加图片数量更能提升泛化能力。实际操作上,我会把这1000张图按室内/室外、垂直/平行/斜向分档,统计每个子类的数量,少于50张的子类优先补数据。用YOLO自带的YOLO("yolov8n.pt")去给新拍的视频抽帧是低成本打标思路,但抽出来的帧之间相似度太高,直接进训练集反而会导致过拟合,每10秒抽一帧比较合适。

最后的建议是先跑通默认参数再谈调优。这份数据集已经给了三种格式标签和划分脚本,训练教程里也写好了命令,第一次训练直接按默认参数跑完,看结果再调。我自己吃过的亏是上来就调imgsz=1280、batch=32,结果显存溢出后开始怀疑数据有问题,折腾半天才发现只是硬件扛不住。把基线跑出来,再一步步加分辨率、加增强,每一步动一项参数,对比着看mAP变化,才是在这个数据集上做优化的正确姿势。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 11:01:21

豆包AI图片去水印完全指南:从裁切到智能修复

你在豆包里生成一张挺满意的图&#xff0c;放进PPT或者文章里当配图时&#xff0c;却发现角落多了一行“豆包AI生成”的小字——这就是豆包图片去水印问题最常见的出场方式。别慌&#xff0c;这不是什么疑难杂症&#xff0c;用对方法&#xff0c;几分钟就能处理干净。这篇内容&…

作者头像 李华
网站建设 2026/10/1 11:01:04

复杂跨学科技术难题求解中的第一性原理拆解与极限假设Prompt实战

复杂跨学科技术难题求解中的第一性原理拆解与极限假设Prompt实战在面对跨越材料科学、量子力学、高能物理、微电子半导体与生物信息学的世界级复杂跨学科技术难题&#xff08;如高能电池固态电解质离子电导率物理瓶颈、超高温超导机理探索、EUV 光刻胶高灵敏度与抗崩塌线宽折衷…

作者头像 李华
网站建设 2026/10/1 10:59:04

微信个人号API对接实战:HTTP接口调用与稳定架构

写微信个人号API对接这话题&#xff0c;得先泼一盆冷水&#xff1a;目前微信官方没有任何直接面向个人号的API&#xff0c;你们四处打听到的“API接口”“对接方案”&#xff0c;一般只有两条路——要么是企业微信开放平台的能力封装&#xff0c;要么是第三方合规服务商把个人号…

作者头像 李华
网站建设 2026/10/1 10:58:18

.NET6 WebApi JWT 鉴权实战:从登录签发到 Swagger 调试

简介&#xff1a;针对.NET6平台WebApi开发中的用户鉴权需求&#xff0c;这份资源提供了一套基于JWT的完整示例源码&#xff0c;适合熟悉C#语法、希望在接口层快速加入身份验证能力的开发者参考。示例从初始化WebApi项目开始&#xff0c;依次演示引入令牌处理类库、实现用户登录…

作者头像 李华
网站建设 2026/10/1 10:57:55

一文带你初识C++和命名空间

1. 初识CC语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大的程序&#xff0c;需要高度的抽象和建模时&#xff0c;C语言则不合适。为了解决软件危机&#xff0c; 20世纪80年代&#xff0c; 计算机界提出了OOP(objectorient…

作者头像 李华
网站建设 2026/10/1 10:57:03

PHP 8.4怎么实现API接口数据加密传输

前言先澄清一个常见误解&#xff1a;把请求体加密并不等于「传输安全」。HTTPS&#xff08;TLS&#xff09;解决的恰恰就是传输安全——防窃听、防篡改、防中间人。如果只做应用层加密却不上 HTTPS&#xff0c;中间人完全可以降级、替换公钥、重放到你的接口。那应用层再加密一…

作者头像 李华