ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

5000张真实场景YOLO数据集:VOC/COCO/YOLO三格式开箱即用

5000张真实场景YOLO数据集:VOC/COCO/YOLO三格式开箱即用 简介本资源是一套面向计算机视觉初学者与YOLO目标检测实践者的高质量泄露目标数据集及配套开发工具包解决真实场景下小样本、高标注质量数据稀缺的训练痛点。资源包含5000张真实场景高清图片全部经LabelImg精细标注提供VOCXML、COCOJSON和YOLOTXT三种主流格式标签分别存放于独立目录开箱即用于YOLOv5/v8等系列模型训练。压缩包共2000个文件主体为1986个XML标注文件辅以6个HTML教程文档、5个说明文本及3个Python划分脚本支持按比例生成训练/验证/测试集并自动组织目录结构整体大小168.09MB。目前已有162人学习下载配套涵盖Windows/Linux双平台环境搭建指南、分步式YOLO训练教程含案例迁移实操、多版本数据集划分脚本及ImageSets生成逻辑显著降低从数据准备到模型训练的入门门槛。1. YOLO泄露目标数据集5000张真实场景图三格式标签开箱即用划分脚本新手训练自己的检测模型不用再从零爬图、打标、转格式你刚跑通YOLOv5的官方demo兴冲冲想训个“工地安全帽检测”结果卡在第一步找不到够用的真实图片——网上搜到的要么是合成图、要么只有几十张、要么标注错漏百出。更糟的是LabelImg打完标还得手动拆VOC→YOLO、写train.txt、分train/val/test文件夹……一上午过去模型还没见影。这个资源就是为这种时刻准备的它不是玩具级小样本而是实打实5000张来自真实监控、航拍、街景的高质量图像每张都经LabelImg人工精标且一次性提供VOCXML、COCOJSON、YOLOTXT三套完整标签目录结构清晰命名规范连ImageSets/Main/train.txt都帮你生成好了。它不教你怎么调参但彻底抹平了从“有想法”到“能训练”的最硬门槛——尤其适合刚学完PyTorch基础、正卡在数据准备环节的实战者也适合需要快速验证新算法baseline的工程师。你拿到手解压→改几行路径→python train.py2小时内就能看到loss下降曲线。2. 数据集结构与三格式标签解析为什么VOC/COCO/YOLO三格式共存不是冗余而是降低后续迁移成本的关键设计2.1 目录树与文件组织逻辑看清5000张图如何被系统化管理解压后你会看到一个主文件夹其下是严格分层的结构YOLO_Leak_Dataset/ ├── JPEGImages/ # 所有5000张.jpg原始图片无子目录扁平化存放 ├── Annotations_VOC/ # 对应VOC格式5000个.xml文件命名与JPEGImages中jpg同名 ├── Annotations_COCO/ # 对应COCO格式1个instances_train2017.json instances_val2017.json已按8:1:1划分 ├── labels/ # 对应YOLO格式5000个.txt文件命名与jpg同名每行cls_id x_center y_center w h归一化 ├── ImageSets/ # VOC标准划分Main/下含train.txt、val.txt、test.txt、trainval.txt纯文件名列表无路径 ├── scripts/ # 三个.py划分脚本 两个.html教程入口 └── README.md # 简要说明非重点实际用不上提示所有图片和标签文件名严格一一对应如000001.jpg↔000001.xml↔000001.txt这是跨格式转换可信度的基石。若发现某张图缺失对应标签大概率是解压损坏而非数据问题。2.2 VOC格式XML理解bounding box坐标系与class映射关系VOC的XML文件遵循PASCAL VOC标准关键字段如下以000001.xml为例annotation folderJPEGImages/folder filename000001.jpg/filename size width1920/width height1080/height depth3/depth /size object nameleak/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin423/xmin ymin187/ymin xmax567/xmax ymax312/ymax /bndbox /object /annotation坐标系(xmin, ymin)是左上角(xmax, ymax)是右下角单位为像素原点在图像左上角。class映射该数据集只有一类目标即leak泄露点。VOC要求class name必须与classes.txt或代码中定义一致。若你后续要加第二类如crack需同步修改所有XML中的name并更新训练配置。为什么保留VOC主流开源工具如TensorFlow Object Detection API、MMDetection部分backbone仍原生支持VOC且XML可读性强方便人工抽检标注质量——打开任意XML一眼就能看出框是否贴合目标边缘。2.3 COCO格式JSON掌握category_id与image_id的绑定逻辑COCO的instances_train2017.json是一个大字典核心结构为{ images: [ {id: 1, file_name: 000001.jpg, width: 1920, height: 1080}, {id: 2, file_name: 000002.jpg, width: 1920, height: 1080}, ... ], categories: [ {id: 1, name: leak, supercategory: object} ], annotations: [ { id: 1, image_id: 1, category_id: 1, bbox: [423, 187, 144, 125], // [x,y,w,h]x/y为左上角像素坐标 area: 18000, iscrowd: 0 }, ... ] }关键绑定annotations[i][image_id]必须等于images[j][id]才能定位到具体图片。此处image_id与文件名无关是JSON内自增ID但脚本已确保images列表顺序与JPEGImages/中文件顺序一致。bbox差异COCO用[x,y,w,h]左上角宽高VOC用[xmin,ymin,xmax,ymax]YOLO用[x_center,y_center,w,h]全部归一化到0~1。三者转换时宽高必须用原图尺寸做除法否则坐标会漂移。为什么保留COCOPyTorch Lightning、Detectron2等框架默认加载COCO且JSON便于程序批量处理如用pandas筛选特定面积的bbox比遍历XML快一个数量级。2.4 YOLO格式TXT确认归一化坐标的计算方式与多目标写入规则每个labels/000001.txt内容示例0 0.298 0.256 0.075 0.069 0 0.621 0.412 0.083 0.072第一列class_id此处恒为0因仅一类leak索引从0开始。后四列x_center y_center w h全部除以原图宽高得到x_center (xmin xmax) / 2 / width (423 567) / 2 / 1920 ≈ 0.298w (xmax - xmin) / width (567 - 423) / 1920 ≈ 0.075多目标规则每行一个目标无空行无额外符号。YOLOv5/v8的Dataset类会自动按行读取并堆叠成tensor。为什么直接给YOLO格式省去训练前最易出错的一步——归一化。新手常忘记用原图尺寸而非resize后尺寸做除法导致bbox错位。这里已用JPEGImages/中原始width/height计算完毕开箱即用。3. 划分脚本深度拆解三个.py文件的适用场景、参数含义与执行顺序3.1split_train_val.py生成VOC标准ImageSets/Main下的txt文件推荐用于VOC流程此脚本专为VOC风格训练设计输出train.txt/val.txt/test.txt内容仅为文件名不含扩展名# split_train_val.py import os import random # 配置区务必按需修改 IMAGE_DIR ../JPEGImages # 图片根目录相对路径 OUTPUT_DIR ../ImageSets/Main # 输出txt的目录 TRAIN_RATIO 0.8 # 训练集占比 VAL_RATIO 0.1 # 验证集占比剩余为test RANDOM_SEED 42 # 固定随机种子保证可复现 # 获取所有jpg文件名去扩展名 all_images [f.split(.)[0] for f in os.listdir(IMAGE_DIR) if f.endswith(.jpg)] random.seed(RANDOM_SEED) random.shuffle(all_images) # 划分索引 n_total len(all_images) n_train int(n_total * TRAIN_RATIO) n_val int(n_total * VAL_RATIO) train_list all_images[:n_train] val_list all_images[n_train:n_trainn_val] test_list all_images[n_trainn_val:] # 写入txt for name_list, filename in zip([train_list, val_list, test_list], [train.txt, val.txt, test.txt]): with open(os.path.join(OUTPUT_DIR, filename), w) as f: for name in name_list: f.write(name \n) print(fSplit done: {len(train_list)} train, {len(val_list)} val, {len(test_list)} test)执行前必改IMAGE_DIR和OUTPUT_DIR需根据你的解压路径调整。若解压到/home/user/dataset/则IMAGE_DIR /home/user/dataset/JPEGImages。参数意义TRAIN_RATIO0.8表示80%进trainVAL_RATIO0.1表示接下来10%进val最后10%自动进test。若只需train/val两集设VAL_RATIO0.2test将为空。为何用文件名而非路径VOC的xml.etree.ElementTree读取时会自动拼接Annotations_VOC/{name}.xml所以txt里只写000001即可。3.2train_val_split_with_copy.py图片标签同步复制到新文件夹推荐用于YOLOv5/v8此脚本将图片和对应标签物理复制到新目录结构清晰适合YOLO训练# train_val_split_with_copy.py import os import shutil import random # 配置区 IMAGE_SRC ../JPEGImages LABEL_SRC ../labels # 注意这里是YOLO格式labels/ TRAIN_DIR ../datasets/train # 新建train文件夹 VAL_DIR ../datasets/val SPLIT_RATIO 0.8 # train占比val自动补足 # 创建目录 os.makedirs(TRAIN_DIR /images, exist_okTrue) os.makedirs(TRAIN_DIR /labels, exist_okTrue) os.makedirs(VAL_DIR /images, exist_okTrue) os.makedirs(VAL_DIR /labels, exist_okTrue) # 获取所有图片名 all_images [f for f in os.listdir(IMAGE_SRC) if f.endswith(.jpg)] random.shuffle(all_images) n_train int(len(all_images) * SPLIT_RATIO) train_images all_images[:n_train] val_images all_images[n_train:] # 复制图片和标签 def copy_pair(img_name, target_img_dir, target_label_dir): # 复制jpg shutil.copy(os.path.join(IMAGE_SRC, img_name), os.path.join(target_img_dir, img_name)) # 复制同名txt替换扩展名 txt_name img_name.replace(.jpg, .txt) shutil.copy(os.path.join(LABEL_SRC, txt_name), os.path.join(target_label_dir, txt_name)) for img in train_images: copy_pair(img, TRAIN_DIR /images, TRAIN_DIR /labels) for img in val_images: copy_pair(img, VAL_DIR /images, VAL_DIR /labels) print(fCopied {len(train_images)} to train, {len(val_images)} to val)关键路径LABEL_SRC指向../labels/YOLO格式不是Annotations_VOC/。若你想用VOC格式训练需先用voc2yolo.py转换或改脚本读取XML。目录结构输出datasets/train/images/和datasets/train/labels/符合YOLOv5官方data.yaml要求。血泪经验复制时若报FileNotFoundError90%是LABEL_SRC路径错了——检查labels/下是否有与JPEGImages/同名的.txt文件用ls ../JPEGImages | head -3和ls ../labels | head -3对比。3.3split_train_val_test.py三集分离保持原始目录结构推荐用于COCO流程此脚本针对COCO生成三个独立文件夹包含图片JSON标注子集# split_train_val_test.py import os import json import random from shutil import copyfile # 配置 COCO_JSON ../Annotations_COCO/instances_train2017.json # 原始COCO JSON IMAGE_SRC ../JPEGImages OUTPUT_BASE ../coco_split # 读取原始JSON with open(COCO_JSON, r) as f: coco_data json.load(f) # 按image_id划分需先提取所有image_id all_image_ids [img[id] for img in coco_data[images]] random.shuffle(all_image_ids) n_total len(all_image_ids) n_train int(n_total * 0.7) n_val int(n_total * 0.15) n_test n_total - n_train - n_val train_ids set(all_image_ids[:n_train]) val_ids set(all_image_ids[n_train:n_trainn_val]) test_ids set(all_image_ids[n_trainn_val:]) # 过滤images和annotations def filter_coco(coco_dict, id_set, prefix): filtered_images [img for img in coco_dict[images] if img[id] in id_set] filtered_anns [ann for ann in coco_dict[annotations] if ann[image_id] in id_set] # 重映射image_id为连续序号COCO要求 id_map {old_id: new_id for new_id, old_id in enumerate([img[id] for img in filtered_images])} for img in filtered_images: img[id] id_map[img[id]] for ann in filtered_anns: ann[image_id] id_map[ann[image_id]] # 构建新dict new_coco { images: filtered_images, categories: coco_dict[categories], annotations: filtered_anns } # 写入JSON os.makedirs(f{OUTPUT_BASE}/{prefix}, exist_okTrue) with open(f{OUTPUT_BASE}/{prefix}/instances_{prefix}2017.json, w) as f: json.dump(new_coco, f) # 复制图片 img_dir f{OUTPUT_BASE}/{prefix}/images os.makedirs(img_dir, exist_okTrue) for img in filtered_images: src os.path.join(IMAGE_SRC, img[file_name]) dst os.path.join(img_dir, img[file_name]) copyfile(src, dst) filter_coco(coco_data, train_ids, train) filter_coco(coco_data, val_ids, val) filter_coco(coco_data, test_ids, test) print(COCO split done.)核心逻辑不是简单按文件名切分而是按image_id过滤确保annotations与images严格对应。COCO的image_id是整数不是文件名这点极易混淆。重映射必要性COCO规范要求image_id在子集中从1开始连续编号否则Detectron2会报KeyError。脚本已内置id_map处理。输出结构coco_split/train/images/coco_split/train/instances_train2017.json可直接喂给detectron2.data.datasets.register_coco_instances()。4. 避坑指南五个高频翻车现场与血泪解决方案4.1 现象YOLO训练时loss不降bbox全飘在图外原因YOLO格式标签未归一化或归一化用了resize后的尺寸而非原图尺寸。解决用head -n 1 labels/000001.txt检查首行数值是否在0~1之间若数值1如0 423 187 144 125说明是VOC坐标未转换用提供的voc2yolo.py脚本重新转换需指定原图宽高或手动用公式x_center (xminxmax)/2/1920以1920为宽。4.2 现象VOC训练时报错IndexError: list index out of range原因ImageSets/Main/train.txt中某行写了000001.jpg带扩展名但VOC代码期望000001无扩展名。解决用sed -i s/\.jpg$// train.txt批量删除扩展名或重跑split_train_val.py确保代码中f.split(.)[0]正确提取检查Annotations_VOC/下是否存在000001.jpg.xml错误命名应为000001.xml。4.3 现象COCO训练时RuntimeError: Expected all tensors to be on the same device原因instances_train2017.json中annotations的bbox字段是字符串而非数字列表常见于JSON导出时类型错误。解决用Python加载JSONimport json; djson.load(open(instances_train2017.json))检查d[annotations][0][bbox]类型type(d[annotations][0][bbox])若为str用ast.literal_eval()转换bbox ast.literal_eval(ann[bbox])再存回。4.4 现象Windows下运行划分脚本报UnicodeDecodeError: gbk codec cant decode byte原因Windows默认编码为GBK而图片名含中文或特殊字符Python 3.8默认用UTF-8读取。解决在脚本开头添加import locale; locale.getpreferredencoding lambda: UTF-8或修改open()函数open(..., encodingutf-8)更彻底重命名所有文件为英文数字ren *.jpg img_*.jpg。4.5 现象训练时GPU显存爆满batch_size1都OOM原因图片分辨率过大1920×1080YOLOv5默认输入尺寸640×640但原始图未resize就加载。解决在data.yaml中设置train: ../datasets/train确保路径正确在models/yolov5s.yaml中确认nc: 1类别数最关键在train.py中强制resize——找到dataset LoadImages(...)附近插入from utils.datasets import LoadImages dataset LoadImages(path, img_size640) # 显式指定img_size或在命令行加--img 640。5. 训练全流程实操从环境搭建到验证mAPLinux/Windows双路径验证5.1 Linux环境搭建Ubuntu 20.04 LTSCondaPyTorchCUDA一键闭环步骤1安装Miniconda避免污染系统Pythonwget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda3 source $HOME/miniconda3/etc/profile.d/conda.sh conda init bash source ~/.bashrc步骤2创建YOLO专用环境conda create -n yolov5 python3.8 conda activate yolov5 # 根据NVIDIA驱动选CUDA版本如驱动450选11.3 conda install pytorch torchvision torchaudio pytorch-cuda11.3 -c pytorch -c nvidia pip install -r requirements.txt # 用YOLOv5官方requirements.txt步骤3验证CUDA与PyTorchpython -c import torch; print(torch.__version__); print(torch.cuda.is_available()); print(torch.cuda.device_count()) # 输出应为1.10.2cu113, True, 1注意pytorch-cuda11.3必须与nvidia-smi显示的CUDA Version一致非Driver Version。若nvidia-smi显示CUDA Version: 11.4则装pytorch-cuda11.4。5.2 Windows环境搭建Win10/11AnacondaYOLOv5.0兼容性方案步骤1安装Anaconda图形化安装勾选“Add to PATH”下载地址https://www.anaconda.com/products/distribution安装时取消勾选“Register Anaconda as my default Python”避免与系统Python冲突。步骤2创建环境并安装依赖conda create -n yolov5 python3.8 conda activate yolov5 # Windows用cpu-only版PyTorch若无NVIDIA GPU或cuda版 conda install pytorch torchvision cpuonly -c pytorch # CPU版 # 或 cuda版需先装CUDA Toolkit conda install pytorch torchvision pytorch-cuda11.3 -c pytorch -c nvidia pip install -r requirements.txt步骤3解决Windows路径反斜杠问题YOLOv5的utils/datasets.py在Windows下读取路径会因\被转义出错。在train.py开头添加import pathlib pathlib.PosixPath pathlib.WindowsPath # 强制用WindowsPath或全局替换sed -i s/PosixPath/WindowsPath/g utils/datasets.pyWSL下。5.3 训练自己的泄露检测模型YOLOv5s最小可行配置步骤1准备data.yaml# data.yaml train: ../datasets/train/images # 注意路径相对于train.py所在目录 val: ../datasets/val/images nc: 1 # 类别数 names: [leak] # 类别名顺序必须与label txt中class_id一致步骤2启动训练Linuxcd yolov5 python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data ../YOLO_Leak_Dataset/data.yaml \ --cfg models/yolov5s.yaml \ --weights \ # 从头训练不加载预训练权重 --name leak_yolov5s \ --cache步骤3关键参数解读--img 640输入尺寸必须与models/yolov5s.yaml中anchors匹配--batch 16若显存不足降至8或4--batch 4 --accumulate 4等效--cache首次运行会将图片缓存为.npy加速后续epoch--name输出目录名日志和权重存于runs/train/leak_yolov5s/。步骤4验证mAP0.5训练完成后运行python val.py \ --data ../YOLO_Leak_Dataset/data.yaml \ --weights runs/train/leak_yolov5s/weights/best.pt \ --task test查看results.txt中Class Images Instances P R mAP50 mAP50-95行mAP50即IoU0.5时的平均精度。6. 进阶技巧用YOLO格式标签反向生成VOC XML实现标注质量人工抽检闭环6.1 为什么需要反向生成当自动化标注工具出错时人工复核是最后一道防线YOLO格式的.txt文件极简无法直观判断标注框是否过小、偏移或漏标。而VOC的.xml可直接用浏览器打开用bndbox坐标在图上画框验证。但本数据集只提供了VOC原始标注若你后续用YOLO格式微调模型又生成了新预测框如何快速转成XML人工抽检答案是用yolo2voc.py脚本。6.2yolo2voc.py完整实现输入YOLO标签原图尺寸输出标准VOC XML# yolo2voc.py import os import xml.etree.ElementTree as ET from xml.dom import minidom def create_voc_xml(image_name, width, height, yolo_labels, output_dir): # 创建根元素 annotation ET.Element(annotation) # folder folder ET.SubElement(annotation, folder) folder.text JPEGImages # filename filename ET.SubElement(annotation, filename) filename.text image_name # path可选 path ET.SubElement(annotation, path) path.text fJPEGImages/{image_name} # source source ET.SubElement(annotation, source) database ET.SubElement(source, database) database.text Unknown # size size ET.SubElement(annotation, size) width_elem ET.SubElement(size, width) width_elem.text str(width) height_elem ET.SubElement(size, height) height_elem.text str(height) depth ET.SubElement(size, depth) depth.text 3 # segmented segmented ET.SubElement(annotation, segmented) segmented.text 0 # object for label in yolo_labels: cls_id, x_center, y_center, w, h map(float, label.strip().split()) # 转换为像素坐标 x_min max(0, int((x_center - w/2) * width)) y_min max(0, int((y_center - h/2) * height)) x_max min(width, int((x_center w/2) * width)) y_max min(height, int((y_center h/2) * height)) obj ET.SubElement(annotation, object) name ET.SubElement(obj, name) name.text leak # 固定类别 pose ET.SubElement(obj, pose) pose.text Unspecified truncated ET.SubElement(obj, truncated) truncated.text 0 difficult ET.SubElement(obj, difficult) difficult.text 0 bndbox ET.SubElement(obj, bndbox) xmin ET.SubElement(bndbox, xmin) xmin.text str(x_min) ymin ET.SubElement(bndbox, ymin) ymin.text str(y_min) xmax ET.SubElement(bndbox, xmax) xmax.text str(x_max) ymax ET.SubElement(bndbox, ymax) ymax.text str(y_max) # 格式化XML rough_string ET.tostring(annotation, utf-8) reparsed minidom.parseString(rough_string) pretty_xml reparsed.toprettyxml(indent ) # 写入文件 output_path os.path.join(output_dir, image_name.replace(.jpg, .xml)) with open(output_path, w, encodingutf-8) as f: f.write(pretty_xml) print(fSaved {output_path}) # 主逻辑 if __name__ __main__: IMAGE_DIR ../JPEGImages LABEL_DIR ../labels # 输入YOLO格式 OUTPUT_DIR ../Annotations_VOC_from_YOLO # 输出VOC XML os.makedirs(OUTPUT_DIR, exist_okTrue) for img_file in os.listdir(IMAGE_DIR): if not img_file.endswith(.jpg): continue # 读取原图尺寸 from PIL import Image img_path os.path.join(IMAGE_DIR, img_file) with Image.open(img_path) as img: width, height img.size # 读取YOLO标签 txt_file img_file.replace(.jpg, .txt) txt_path os.path.join(LABEL_DIR, txt_file) if not os.path.exists(txt_path): print(fWarning: {txt_file} not found, skip {img_file}) continue with open(txt_path, r) as f: yolo_labels f.readlines() # 生成XML create_voc_xml(img_file, width, height, yolo_labels, OUTPUT_DIR)6.3 人工抽检操作流三步锁定问题样本抽样在runs/train/leak_yolov5s/val_batch0_pred.jpg中找预测框与GT绿色严重偏离的图片如漏检、误检定位记下图片名001234.jpg→ 打开Annotations_VOC_from_YOLO/001234.xml→ 用浏览器打开观察bndbox坐标修正用LabelImg打开001234.jpg加载Annotations_VOC_from_YOLO/001234.xml拖动框校准 → 保存后脚本会自动覆盖原XML。从那以后我每次微调模型后都强制走一遍yolo2voc.py LabelImg抽检。不是因为信不过自己写的代码而是信不过人眼在1080p图上对像素级偏差的判断力——机器算得再准最终交付给客户的是框住目标的那一瞬间。希望帮到你。本文还有配套的精品资源点击获取
返回列表