恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
安全帽检测实战:VOC/COCO/YOLO格式转换与跨平台YOLO11训练脚本
首页
资讯中心
/
安全帽检测实战:VOC/COCO/YOLO格式转换与跨平台YOLO11训练脚本
安全帽检测实战:VOC/COCO/YOLO格式转换与跨平台YOLO11训练脚本
发布时间:2026/9/19 3:07:52
简介面向工地与公共场所监控场景的安全帽检测任务这份资源整合了1000张真实场景图片的安全帽检测数据集覆盖工地行人佩戴、高空作业、遮挡与严重遮挡等多样情况划分为佩戴安全帽helmet与未佩戴安全帽head两类。数据集全部采用LabelImg标注同时提供VOCxml、COCOjson、YOLOtxt三种主流格式可直接用于YOLO等目标检测算法的训练与评估。配套附赠YOLO11一键训练脚本支持GPU、CPU以及MacM芯片多平台运行并给出博主训练日志供参考适合正在做安全帽检测项目或需要监控场景数据补充的开发者。资源包内为1个PDF文件大小6.11MB内含数据集详细介绍与百度网盘获取方式目前已有885人学习下载可作为算法验证或项目落地的便捷参考。1. 安全帽检测的数据集为什么关键在格式对齐做安全帽检测的第一道坎从来不是模型选型而是数据。许多团队在工地、工厂或园区采集了上千张现场照片却把 80% 的时间耗在标注格式转换、类别名不一致、训练脚本跑不起来这类事上。一套带 VOC、COCO、YOLO 三种格式标签的安全帽检测数据集加上一份能适配 GPU、CPU、Mac 三平台的 YOLO11 训练脚本解决的就是“拿到数据之后 10 分钟内跑通第一次训练”这个目标。这套组合的真正价值在于你不需要先会写 XML 解析器不用懂 JSON 标注结构也暂时不需要理解 YOLO 的归一化坐标数据集已经替你完成了最绕的那一步。你只需要确认字段含义、选对模型尺寸、跑起脚本然后把精力留给更有价值的部分——调阈值、筛难例、看误检。对刚入门目标检测的人它是一份标准答案对已经跑过若干模型的人值得关注的是三格式数据如何互相校验、YOLO11 在 CPU 和 Mac 上的速度差异以及哪些参数在不同算力平台上必须分开调。下面按“数据格式 → 训练脚本 → 实际跑通 → 验证优化”的顺序完整过一遍。2. VOC、COCO、YOLO 三种格式的真实差异与互相转换2.1 三种格式的目录结构和核心字段VOCPascal VOC格式是最传统的一种。标注文件是 XML和图片一一对应放在Annotations目录图片放JPEGImages还有一个ImageSets/Main目录里的 txt 文件来划分训练集和验证集。COCO 格式则是把所有标注装进一个 JSON 文件。结构分images、annotations、categories三大块。images记录每张图的宽高和文件名annotations是每个目标的边界框和类别 idcategories是 id 到类别名的映射。边界框的坐标是左上角 x、左上角 y、宽度 w、高度 h注意不是中心点。YOLO 格式最简洁每个图片对应一个同名 txt 文件每行一个目标排列顺序是class_id x_center y_center width height坐标全部归一化到 0 到 1 之间。以安全帽检测为例类别建议只保留helmet和head两类——戴帽子的头归helmet没戴帽子的头归head。如果数据集里把每个工人的身体也标了训练时会引入大量背景噪声严重干扰小尺寸头部的检测。2.2 为什么不能只准备一种格式只准备一种格式行不行大部分时候也行但会卡住工具链。Ultralytics YOLO11 原生吃 YOLO 格式需要跑检测精度对比时COCO API 只认 COCO JSON如果要接 Data Augmentation 的旧 pipelineXML 支持又最直接。一图三格式的核心收益不是“全”而是可以交叉验证。同一张图的三个标注文件面积、类别数、坐标应该完全一致。转换脚本写完以后跑一遍对比能自动化找出标注里最隐蔽的问题——比如某张图在 VOC 里标了 3 个头到 YOLO 格式却只剩 2 行 txt这类脏数据用人工检查几乎不可能找全。常见做法是用labelme或labelImg标注原始数据然后脚本转出三种格式。其实没有谁标准化地支持三种导出多数场景是自己维护一个转换脚本。下面给一个可复用的方向从 COCO JSON 同时生成 VOC XML 和 YOLO txt。2.3 一个同时输出三种格式的转换脚本下面这段 Python 脚本的思路是先从 COCO JSON 读取全部标注落到内存里的统一结构再同时写出 VOC XML 和 YOLO txt。这种做法避免重复解析也保证坐标换算只做一次出错概率最低。import json import os import xml.etree.ElementTree as ET from xml.dom import minidom def coco_to_voc_yolo(coco_json_path, output_dir): with open(coco_json_path, r, encodingutf-8) as f: coco json.load(f) images {img[id]: img for img in coco[images]} categories {cat[id]: cat[name] for cat in coco[categories]} cat_id_to_yolo_id {cat_id: idx for idx, cat_id in enumerate(sorted(categories.keys()))} voc_ann_dir os.path.join(output_dir, Annotations) yolo_label_dir os.path.join(output_dir, labels) os.makedirs(voc_ann_dir, exist_okTrue) os.makedirs(yolo_label_dir, exist_okTrue) for ann in coco[annotations]: img_info images[ann[image_id]] img_w, img_h img_info[width], img_info[height] x, y, w, h ann[bbox] # COCO的bbox是[x, y, w, h]左上角坐标 x_center (x w / 2) / img_w y_center (y h / 2) / img_h norm_w w / img_w norm_h h / img_h yolo_line f{cat_id_to_yolo_id[ann[category_id]]} {x_center:.6f} {y_center:.6f} {norm_w:.6f} {norm_h:.6f} yolo_txt os.path.join(yolo_label_dir, img_info[file_name].replace(.jpg, .txt)) with open(yolo_txt, a, encodingutf-8) as yf: yf.write(yolo_line \n) # VOC XML 部分用追加模式写入同一张图的多目标 # 建议实际用 dict 聚合后一次性写入避免频繁 IO这个脚本最重要的一段是坐标换算逻辑。COCO 的 bbox 四元组是[x, y, width, height]中心点坐标转 YOLO 时先算出中心再除以图片宽高。如果你从labelImg直接导出 YOLO 格式坐标已经是归一化的就不需要再除一次。最容易错的位置就在这里不少人转完格式后训练 loss 不降查半天发现坐标放大了一个比例尺。2.4 数据集划分的一个实战建议1000 张图不算多划分比例建议 8:1:1也就是训练 800 张、验证 100 张、测试 100 张。很多脚本只分 train 和 val最后模型对没见过的场景表现如何完全没有感知这对安全帽这种场景很危险——工地环境差异极大。划分的时候有一个原则同一个场景、同一段时间连拍的图片必须进同一个集合。如果训练集里有某工地 50 张连续帧验证集里恰好也有这个工地那验证分数会虚高。常见做法是先从文件名提取场景 id按场景划分再在场景内部随机抽样。3. 跨 GPU / CPU / Mac 的 YOLO11 训练脚本怎么组织3.1 脚本设计的目标一个“一键训练脚本”要解决的根本问题是环境差异。GPU 机器上跑 CUDAMac 上走 MPS纯 CPU 机器只能硬算。三种环境对 batch size、workers 数量的容忍度差别很大脚本的第一件事就是自动探测设备再按设备分配默认参数。YOLO11 是 Ultralytics 框架的模型系列API 设计和 YOLOv8 一脉相承。安装方式很简单pip install ultralytics即可。脚本里不需要显式指定模型结构通过yolo11n.pt、yolo11s.pt这类预训练权重文件名直接加载。3.2 完整的一键训练脚本下面这个脚本可以在三平台运行核心自动判断部分在detect_device函数里。mps是 Apple Silicon 的 GPU 加速接口Intel 芯片的 Mac 只有 CPU。#!/bin/bash # train_yolo11.sh - 跨平台 YOLO11 安全帽检测训练脚本 # 1. 清理上一次的残留日志 rm -rf runs/detect/helmet # 2. 根据平台配置 torch 环境变量 if [[ $(uname) Darwin ]]; then export PYTORCH_ENABLE_MPS_FALLBACK1 DEVICEmps BATCH_SIZE16 WORKERS2 else # Linux 下检查 NVIDIA GPU if command -v nvidia-smi /dev/null; then DEVICE0 BATCH_SIZE32 WORKERS8 else DEVICEcpu BATCH_SIZE8 WORKERS2 fi fi # 3. 执行训练 yolo detect train \ modelyolo11n.pt \ datadata.yaml \ epochs100 \ batch$BATCH_SIZE \ imgsz640 \ device$DEVICE \ workers$WORKERS \ projectruns/detect \ namehelmet \ patience20 \ save_period10分段拆开解释。第一步删runs/detect/helmet是为了保证这次训练从头开始否则 Ultralytics 会把新结果写成helmet2日志乱了不说加载最佳权重时还可能指错路径。第二步的设备判断里PYTORCH_ENABLE_MPS_FALLBACK1是 Mac 上最容易漏掉的一个环境变量。YOLO11 的某些算子 MPS 后端没有实现如果不设这个变量训练会在前向传播时报 “not implemented” 错误设置了之后自动落到 CPU 计算代价是慢一些但至少能跑通。第三步的命令参数里patience20是早停轮数。具体含义是连续 20 个 epoch 验证集 mAP 没有提升就终止训练。1000 张图用yolo11n这个 nano 版本通常 60 到 80 个 epoch 就收敛patience20能省时间。3.3 平台差异的参数对照表参数NVIDIA GPUApple Silicon (MPS)纯 CPUbatch size32168workers822预期单 epoch 耗时1000张图20-40秒1-2分钟4-8分钟内存占用4-6GB3-4GB2-3GB这个表是经验值前提是图片尺寸 640 乘 640。如果你的显卡是 8GB 显存以下batch size 从 32 降到 24 甚至 16别硬撑。workers在 Windows 上建议不超过 4否则 DataLoader 可能报错Linux 则无所谓。Mac 上 batch size 调到 32 也不会快MPS 后端的算力上限在那里反而会导致显存溢出。3.4 数据配置文件的几个必须注意的字段data.yaml是训练脚本能跑通的另一个关键。Ultralytics 训练时读这个文件决定类别名和数据路径。下面是一个安全帽检测的配置path: /absolute/path/to/dataset train: images/train val: images/val test: images/test nc: 2 names: 0: helmet 1: headpath字段必须写绝对路径。这个看起来低级实际是训练时报 “AssertionError: train dataset not found” 最常见的根因。相对路径在命令行里看起来对但 Ultralytics 会在path的基础上拼train值最终解析出来的路径和你预期不一定一致。另外注意names的索引顺序必须和 YOLO 标签 txt 里的 class_id 一致——如果第 0 类是head但标签文件里 0 是helmet训练不会报错只是模型学到的语义是反的推理时输出的类别名永远对不上。4. 从启动训练到读懂日志和报错4.1 第一次训练时的预期输出脚本启动后终端会先输出一堆模型结构信息然后出现一个进度条。真正需要关注的是每个 epoch 结束后的那行指标。格式大致如下Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 79/100 3.2G 0.732 0.318 1.021 18 640box_loss是边界框回归损失cls_loss是分类损失dfl_loss是分布聚焦损失。三个值都应该整体呈下降趋势允许震荡但如果到第 40 个 epoch 还在高位震荡不降大概率是标签文件有问题——先随机挑一张训练图手工比对该图的 YOLO txt 坐标是否落在画面有效区域内。训练结束后runs/detect/helmet/weights/目录下会生成两个权重文件best.pt是验证集 mAP 最高的那一个last.pt是最后一个 epoch 的结果。迁移学习或断点续训时用last.pt实际部署和测试一律用best.pt。4.2 常见报错与应对策略跑一次训练会遇到的报错基本集中在几个固定位置。最常见的是CUDA out of memory这通常不是显存真的不够而是batch size太大或者workers太多。把 batch size 减半把workers改成 4问题能解决大半。如果还报错就加一行import torch torch.cuda.empty_cache()另一个高频报错是标签文件为空。YOLO 格式的 txt 文件如果是 0 字节训练时不会报错但损失会变成 NaN。检查方式很简单find dataset/labels -name *.txt -size 0 -exec ls -la {} \;把空文件所在的对应图片从训练集中去掉或者重新标注比排查其它问题省时得多。4.3 精度看哪些指标训练日志最后一行会输出 mAP50、mAP50-95 的数值。mAP50 是 IoU 阈值 0.5 下的平均精度mAP50-95 是 0.5 到 0.95 分十个档位的平均值。1000 张图训练出来的模型mAP50 能到 0.85 以上算合格mAP50-95 会低不少通常在 0.5 到 0.65 之间两者差距大是正常的。安全帽检测更关键的是召回率漏掉一个没戴帽子的人头比误报严重得多。训练日志里那个表格如果包含 P精确率和 R召回率优先看 R 值。R 值偏低就降低置信度阈值做推理或增加没戴帽子样本的占比。5. 推理验证脚本与一个极值参数让模型更实用的三个调整5.1 本地推理与指标复查模型训练完别急着部署先写一个推理脚本验证实际效果。下面这段代码在单张图上输出检测结果并绘制边界框。from ultralytics import YOLO model YOLO(runs/detect/helmet/weights/best.pt) results model.predict( sourcetest_images/site_a_001.jpg, conf0.4, iou0.5, devicemps, saveTrue, projectinference_results, namehelmet_test ) for r in results: boxes r.boxes for box in boxes: cls int(box.cls[0]) conf float(box.conf[0]) xyxy box.xyxy[0].tolist() print(f类别: {model.names[cls]}, 置信度: {conf:.3f}, 坐标: {xyxy})conf0.4是最关键的参数。训练日志里的 mAP 是在多个置信度下计算的平均值实际推理时必须自己定阈值。安全帽检测里漏检的风险远大于误检建议把 conf 压到 0.25 到 0.3。代价是误检变多但宁可多框一个背景也不要漏一个裸奔的头部。IOU 阈值 0.5 是默认值如果画面里人头密集可以提高到 0.6 减少重叠框。5.2 用小目标参数调整锚框策略1000 张图里头部和帽子大多是小目标。YOLO11 的原生结构对 8 倍下采样的特征层更敏感如果画面中帽子尺寸普遍小于 32 像素可以考虑把imgsz从 640 提升到 800 或 960。这会增加显存占用但在 GPU 上值得。有一个非常便宜的经验做法——把推理图的尺寸调大不重新训练yolo detect predict modelbest.pt sourcetest.jpg imgsz960 conf0.3有时能白捡 2 到 3 个点的 mAP。这种技巧在模型轻量化、小目标检测这类话题里常被提到适合安全帽这类目标尺寸极端不均衡的场景。5.3 类别不平衡的最省事解法数据集里如果戴帽子的样本是没戴帽子的 5 倍模型会偏向预测helmet。最省事的解法不是调损失函数而是直接调推理阈值——为每个类别设置不同的conf。YOLO11 内置的predict命令不支持分类别阈值但可以用model.predict后处理对head类的置信度手动减去 0.1 再参与阈值判定相当于变相提高了head的召回。从工程角度这三种格式加三平台脚本加上推理验证构成了一条完整的闭环。数据是别人整理好的但要清楚每条边界训练脚本能跑通只是开始真正决定上线效果好坏的是推理阈值和类别先验的合理设置。本文还有配套的精品资源点击获取