塔吊下方站人检测数据集:VOC标注与YOLOv8实战指南

发布时间:2026/10/12 0:45:15
塔吊下方站人检测数据集:VOC标注与YOLOv8实战指南 简介这份资源面向从事工地安全监控、目标检测算法开发的研究者与工程师提供塔吊下方站人检测任务的图像数据集用于训练和验证识别塔吊作业区域人员的视觉模型降低误入危险区域引发事故的风险。压缩包共2000个文件包含1055张jpg图像与1055个xml标注文件整体约219.6MB图像与VOC格式标签一一对应标注由labelimg工具完成边界框与人物类别信息可直接用于Faster R-CNN、YOLO等检测框架的训练与评估。目前已有433人学习下载。数据集覆盖塔吊监控视角下的真实场景读者可据此完成数据预处理、模型训练、调参优化与mAP等指标验证并进一步部署到实时监控系统中构建高效且安全的工地智能管理方案兼具工程实用性与计算机视觉应用价值。1. 塔吊下方站人检测数据集1000 多张 VOC 标注图能直接跑通什么工地安全监控里塔吊吊装区域下方站人是最典型也最要命的风险场景。摄像头架好了算法却卡在第一步——没有标注数据。这份塔吊下方站人检测图像数据集1000 多张实拍图全部按 VOC 格式打好标签目标类别就是人。它解决的不是模型结构问题而是让你跳过从零标数据这个最耗时的环节直接把精力放在训练、调参和部署验证上。适合两类人一是做工地 AI 安全监控的算法工程师需要快速验证检测方案可行性二是带学生做课程设计或毕设的高校老师想要一份真实场景、标注完整、规模适中的数据集。VOC 格式意味着它能无缝接入 YOLO、Faster R-CNN、SSD 等主流检测框架不用再写格式转换脚本。1000 多张的量级不算大但胜在场景聚焦——全是塔吊下方区域背景干扰、光照变化、人员姿态都来自真实工地比拿公开数据集硬凑要靠谱得多。2. VOC 标注格式拆解Annotation、JPEGImages 和 ImageSets 到底怎么对应2.1 VOC 目录结构与文件对应关系拿到一份 VOC 数据集第一件事不是急着写训练脚本而是把目录结构摸清楚。标准 VOC 格式的目录长这样VOCdevkit/ └── VOC2007/ ├── Annotations/ # XML 标注文件每张图对应一个 ├── JPEGImages/ # 原始图像jpg 格式 ├── ImageSets/ │ └── Main/ # 训练/验证/测试集划分文件 ├── SegmentationClass/ # 分割任务用检测任务可忽略 └── SegmentationObject/Annotations 里的 XML 文件是核心。每个 XML 对应一张图记录了图像尺寸、目标类别和边界框坐标。塔吊下方站人检测这个场景类别只有一个person。但别小看这个只有一个类实际标注时最容易出问题的就是人的边界框——工人弯腰、被钢筋遮挡、只露出半个身子这些情况框怎么画直接决定模型学到什么。ImageSets/Main 目录下通常有 train.txt、val.txt、trainval.txt、test.txt 四个文件每行一个文件名不带扩展名。如果你拿到的数据集没有划分文件需要自己写脚本生成。常见做法是按 8:1:1 或 7:2:1 切分但工地场景有个坑同一段视频抽帧出来的图如果随机切分训练集和验证集会高度相似验证指标虚高。我一般会按拍摄时段或摄像头编号来切保证验证集里的场景和训练集不重叠。2.2 解析 XML 并转成 YOLO 格式的完整脚本VOC 转 YOLO 是最高频的操作。YOLO 的标签格式是每行class_id x_center y_center width height全部归一化到 0-1。下面这个脚本我用了很多次直接抄import xml.etree.ElementTree as ET import os from pathlib import Path # 类别映射塔吊站人检测只有 person 一类 CLASS_MAP {person: 0} def voc_to_yolo(xml_dir, img_dir, out_dir): xml_dir: Annotations 目录路径 img_dir: JPEGImages 目录路径用于读取图像宽高 out_dir: YOLO 标签输出目录 os.makedirs(out_dir, exist_okTrue) skipped 0 for xml_file in Path(xml_dir).glob(*.xml): tree ET.parse(xml_file) root tree.getroot() # 读取图像尺寸VOC XML 里有 size 节点 size root.find(size) img_w int(size.find(width).text) img_h int(size.find(height).text) lines [] for obj in root.findall(object): cls_name obj.find(name).text.strip() if cls_name not in CLASS_MAP: continue # 跳过不在类别表里的目标 bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 边界检查有些标注框会超出图像范围 xmin max(0, min(xmin, img_w)) xmax max(0, min(xmax, img_w)) ymin max(0, min(ymin, img_h)) ymax max(0, min(ymax, img_h)) if xmax xmin or ymax ymin: skipped 1 continue # 宽高为负的脏框直接丢 # 转成 YOLO 归一化中心坐标格式 x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{CLASS_MAP[cls_name]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) # 即使没有目标也写空文件YOLO 训练时作为负样本 out_file Path(out_dir) / (xml_file.stem .txt) out_file.write_text(\n.join(lines)) print(f转换完成跳过 {skipped} 个无效框) # 调用示例 voc_to_yolo( xml_dirVOCdevkit/VOC2007/Annotations, img_dirVOCdevkit/VOC2007/JPEGImages, out_dirlabels_yolo )这段代码有几个关键处理点。第一CLASS_MAP只保留 person如果 XML 里有其他类别比如 helmet、machinery会被自动跳过不会污染标签。第二边界检查那几行是血泪经验——VOC 标注工具偶尔会产出超出图像范围的框不裁剪的话归一化坐标会大于 1YOLO 训练时直接报错。第三空标签文件要保留YOLO 会把没有目标的图当作负样本对降低误检率有帮助。第四skipped计数用来快速判断数据质量如果跳过数量超过总数的 5%说明标注环节有问题得回头查。2.3 生成训练集划分文件的脚本如果数据集没带 ImageSets用下面这个脚本按比例切分import random from pathlib import Path def split_dataset(img_dir, out_dir, train_ratio0.7, val_ratio0.2): 按比例生成 train.txt / val.txt / test.txt 注意工地场景建议按摄像头或时段手动分组后再切避免同源数据泄漏 img_dir Path(img_dir) out_dir Path(out_dir) out_dir.mkdir(parentsTrue, exist_okTrue) # 只取 jpg 文件排除其他格式干扰 all_imgs sorted([f.stem for f in img_dir.glob(*.jpg)]) random.seed(42) # 固定种子保证可复现 random.shuffle(all_imgs) n len(all_imgs) n_train int(n * train_ratio) n_val int(n * val_ratio) train_list all_imgs[:n_train] val_list all_imgs[n_train:n_train n_val] test_list all_imgs[n_train n_val:] for name, lst in [(train, train_list), (val, val_list), (test, test_list)]: (out_dir / f{name}.txt).write_text(\n.join(lst)) print(ftrain: {len(train_list)}, val: {len(val_list)}, test: {len(test_list)}) split_dataset(VOCdevkit/VOC2007/JPEGImages, VOCdevkit/VOC2007/ImageSets/Main)random.seed(42)是为了让每次运行结果一致方便复现实验。但更重要的提醒在注释里如果 1000 多张图是从几段连续视频里抽帧来的随机切分会导致相邻帧分别进入训练集和验证集验证指标会虚高 5-10 个点。正确做法是先按视频段分组再在组间切分。这个坑我在三个项目里都踩过后来养成习惯拿到数据先看文件名规律如果是cam01_frame_001.jpg这种必须按 cam 编号分组。3. 用这份数据集训练 YOLOv8从环境配置到指标解读3.1 环境搭建与数据配置文件YOLOv8 是目前工地检测场景里落地最快的选择安装干净pip install ultralytics然后创建数据配置文件tower_crane.yamlpath: /data/tower_crane_dataset # 数据集根目录 train: images/train # 训练集图像目录 val: images/val # 验证集图像目录 test: images/test # 测试集图像目录 nc: 1 # 类别数只有 person names: 0: person目录结构需要整理成 YOLO 要求的形式tower_crane_dataset/ ├── images/ │ ├── train/ # 从 JPEGImages 拷贝对应文件 │ ├── val/ │ └── test/ └── labels/ ├── train/ # 从 labels_yolo 拷贝对应文件 ├── val/ └── test/写个脚本按 train.txt 里的文件名把图和标签分别拷到对应目录比手动拖拽靠谱。注意图像和标签文件名必须一一对应只是扩展名不同.jpg 对 .txt。3.2 训练命令与关键参数设置启动训练yolo detect train \ datatower_crane.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ device0 \ projectruns/tower_crane \ nameexp1参数逐个说。modelyolov8s.pt选 small 版本1000 多张图的量级用 n 可能欠拟合用 m 或 l 容易过拟合s 是平衡点。imgsz640是默认值如果塔吊下方人员在图中占比很小比如远景摄像头可以提到 1280但显存翻倍。batch16在 8G 显存上跑 640 尺寸刚好显存不够就降到 8。lr00.01是初始学习率YOLOv8 自带余弦退火一般不用改。patience20表示 20 轮验证指标不提升就早停防止过拟合。device0指定第一块 GPUCPU 训练的话去掉这个参数但速度会慢 20 倍以上。训练过程中重点看三个指标box_loss和cls_loss是否稳定下降mAP50是否持续上升。如果 loss 震荡剧烈先把 batch 调大或学习率减半。如果 mAP50 卡在某个值不动了检查验证集里是不是有大量遮挡严重或极小目标的图——这类样本本身就是检测难点不是模型问题。3.3 推理验证与结果分析训练完在测试集上跑推理yolo detect predict \ modelruns/tower_crane/exp1/weights/best.pt \ sourcetest_images/ \ conf0.25 \ iou0.45 \ saveTrueconf0.25是置信度阈值低于这个值的检测框不输出。工地安全场景建议调低到 0.15-0.2宁可误报也不能漏报——漏掉一个站在吊臂下方的人后果比多报几个假框严重得多。iou0.45是 NMS 的 IoU 阈值人员密集时适当调高到 0.5-0.6避免相邻工人被合并成一个框。看结果时别只盯着 mAP。把预测结果可视化出来重点检查三类图一是远处小目标有没有漏检二是被脚手架或材料遮挡的人有没有检出三是塔吊阴影或类似人形的物体有没有误检。这三类问题分别对应数据增强策略、模型容量和负样本数量比单纯看指标有用得多。4. 避坑与排查标注质量、类别失衡和过拟合的实战记录4.1 标注框贴边导致训练报错现象训练启动后报AssertionError: normalized coordinates out of range或者 loss 直接变成 NaN。原因VOC XML 里某些 bndbox 的坐标超出了图像实际宽高转换后归一化坐标大于 1 或小于 0。标注人员用工具画框时拖出了图像边界工具没有自动裁剪。解决在转换脚本里加边界裁剪就是第 2 章脚本里xmin max(0, min(xmin, img_w))那几行。另外训练前用脚本扫一遍所有标签文件检查是否有坐标值不在 [0,1] 范围内提前修掉比训练中途崩掉省时间。4.2 验证集指标虚高但实际部署效果差现象验证集 mAP50 跑到 0.92信心满满部署到工地摄像头实际漏检率超过 30%。原因数据集是从连续视频抽帧的相邻帧高度相似。随机切分后训练集和验证集里存在大量几乎一样的图模型相当于在背答案。另外如果所有图都来自同一时段比如都是白天模型没学过夜间或阴天场景。解决按视频段或摄像头编号分组切分确保验证集场景和训练集不重叠。如果数据来源单一至少按时间顺序切——前 70% 做训练后 30% 做验证。部署前用完全没参与训练的现场视频做一次盲测这个数字才可信。4.3 小目标漏检严重现象近处的人检测很准但塔吊远景摄像头里的人在画面中只有几十个像素几乎全部漏检。原因YOLOv8 默认 640 输入尺寸下最小的检测特征图是 80x80对应原图 8 像素的步长。如果人在原图中只有 20-30 像素高经过下采样后特征几乎消失。解决三个方向。一是提高输入尺寸到 1280显存不够就减小 batch。二是用切图推理把大图切成 640x640 的小块分别检测再合并适合固定摄像头场景。三是在训练时增加小目标的过采样把包含小目标的图复制多份加入训练集。我一般先试提高输入尺寸效果不够再上切图方案。4.4 负样本不足导致误检率高现象模型把塔吊挂钩、堆放的钢管、甚至地面上的阴影都框成人。原因训练集里全是包含人的正样本模型没见过没有人的场景学不会区分人形物体和真人。解决往训练集里加入不含人的塔吊下方场景图标签文件留空。数量不用多正样本的 10%-20% 就够。这些负样本图可以从监控视频里截取没有人经过的时段成本很低但效果立竿见影。另外数据增强里的 mosaic 和 mixup 也能在一定程度上缓解但不能替代真实负样本。4.5 类别映射写错导致训练标签全错现象训练 loss 正常下降但推理时所有框的类别都是错的或者置信度极低。原因VOC XML 里的类别名和 YAML 里的names没对齐。比如 XML 里写的是Person大写 P脚本里映射的是person导致所有目标被跳过标签文件全空。解决转换前先跑一行命令统计 XML 里所有出现的类别名grep -h name Annotations/*.xml | sort | uniq -c。确认类别名和映射表完全一致包括大小写和空格。这个检查花 10 秒钟能省几小时排查时间。5. 数据增强与模型微调把 1000 张图用出 5000 张的效果1000 多张图在检测任务里属于小数据集直接训练容易过拟合。但工地场景有个特点摄像头位置固定光照和天气变化是主要变量。针对这个特点做增强比通用增强策略更有效。YOLOv8 训练时默认开启 mosaic、mixup、HSV 增强和随机翻转。我一般会调整几个参数hsv_h0.015、hsv_s0.7、hsv_v0.4把色调、饱和度、明度的扰动范围拉大模拟不同时段的光照变化。degrees10做小角度旋转模拟摄像头轻微偏移。translate0.1和scale0.5让目标在画面中的位置和大小更多样。但flipud0.0要关掉垂直翻转——人倒过来在工地场景里不存在开了反而引入噪声。如果增强后还是过拟合试试冻结 backbone 做微调from ultralytics import YOLO model YOLO(yolov8s.pt) # 冻结前 10 层只训练检测头 for i, (name, param) in enumerate(model.model.named_parameters()): if i 10: param.requires_grad False model.train( datatower_crane.yaml, epochs50, imgsz640, batch16, lr00.001, # 微调时学习率降低 freeze10, # 官方参数冻结前 10 层 projectruns/tower_crane, namefinetune )冻结训练适合数据量少、和预训练数据分布接近的场景。COCO 数据集里本身就有大量 person 标注所以冻结 backbone 后检测头能快速适配塔吊场景。训练完解冻全部层再跑 20-30 轮低学习率精调通常比从头训练效果好 3-5 个点。验证增强效果有个简单方法训练两个模型一个开增强一个关增强在同一个盲测集上对比。如果增强后的模型在盲测集上 mAP 高但验证集 mAP 低说明增强起了正则化作用是好事。反过来如果两个集都低说明增强过头了把hsv和scale调小。最后说一个我踩过的坑有次为了提升小目标检测把imgsz从 640 提到 1280结果显存不够改成batch4训练极不稳定loss 震荡了 30 轮才收敛。后来改成batch8 梯度累积accumulate2等效 batch 16既省显存又稳定。从那以后我每次调输入尺寸都同步检查 batch 和累积步数的乘积保证等效 batch 不低于 16。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询