当前位置: 首页 > article >正文

告别手动分割!用Python脚本一键生成VOC数据集所需的train.txt和val.txt

告别手动分割用Python脚本一键生成VOC数据集所需的train.txt和val.txt在计算机视觉项目中数据集的准备往往是耗时最长的环节之一。特别是当我们需要按照VOC格式整理数据集时手动分割训练集、验证集不仅效率低下还容易引入人为错误。想象一下当你花费数小时标注了上千张图片后却因为手动分配数据集时的一个疏忽导致模型训练出现偏差——这种痛苦相信很多开发者都深有体会。本文将介绍一种高效可靠的解决方案通过Python脚本自动完成VOC数据集的分割工作。这种方法特别适合已经熟悉LabelImg标注工具但希望提升工作效率的中高级开发者。我们将从基础实现开始逐步深入到各种实际应用场景的优化技巧包括小样本处理、类别平衡策略以及随机种子控制等高级话题。1. VOC数据集结构解析与自动化分割原理1.1 VOC标准目录结构剖析VOC数据集的标准结构包含几个关键目录每个都有其特定用途VOCdevkit/ └── VOC2007/ ├── Annotations/ # 存放XML标注文件 ├── ImageSets/ # 包含数据集划分信息 │ └── Main/ # 具体划分文件存放位置 ├── JPEGImages/ # 存放原始图像文件 └── SegmentationClass/ # 语义分割专用可选其中Main目录下的txt文件决定了数据如何被划分。传统手动创建这些文件的方式存在三个主要问题一致性风险人工分配容易导致某些样本被重复使用或遗漏效率瓶颈当数据量达到数千甚至数万时手动操作变得不切实际随机性缺失人工分配难以保证数据分布的随机性和代表性1.2 自动化分割的核心算法我们的Python脚本主要解决上述问题其核心逻辑如下import os import random def split_dataset(xml_dir, output_dir, trainval_ratio0.8, train_ratio0.9): xml_files [f for f in os.listdir(xml_dir) if f.endswith(.xml)] total_count len(xml_files) indices list(range(total_count)) # 第一次分割trainval与test trainval_size int(total_count * trainval_ratio) trainval_indices random.sample(indices, trainval_size) # 第二次分割train与val train_size int(trainval_size * train_ratio) train_indices random.sample(trainval_indices, train_size) # 写入各个分割文件 with open(f{output_dir}/trainval.txt, w) as f1, \ open(f{output_dir}/test.txt, w) as f2, \ open(f{output_dir}/train.txt, w) as f3, \ open(f{output_dir}/val.txt, w) as f4: for idx in indices: base_name os.path.splitext(xml_files[idx])[0] \n if idx in trainval_indices: f1.write(base_name) if idx in train_indices: f3.write(base_name) else: f4.write(base_name) else: f2.write(base_name)提示脚本使用两次随机抽样来确保数据分布的层次性先分离出测试集再从剩余数据中划分训练集和验证集。2. 基础脚本实现与关键参数详解2.1 完整脚本代码解析以下是增强版的自动化分割脚本增加了错误处理和路径兼容性#!/usr/bin/env python3 import os import random import argparse from pathlib import Path def parse_args(): parser argparse.ArgumentParser(descriptionVOC数据集自动分割工具) parser.add_argument(--xml-dir, typestr, requiredTrue, helpAnnotations目录路径) parser.add_argument(--output-dir, typestr, requiredTrue, help输出目录路径(通常为ImageSets/Main)) parser.add_argument(--trainval, typefloat, default0.8, help训练验证集占总数据的比例) parser.add_argument(--train, typefloat, default0.9, help训练集占训练验证集的比例) parser.add_argument(--seed, typeint, defaultNone, help随机种子用于可重复实验) return parser.parse_args() def main(): args parse_args() if args.seed is not None: random.seed(args.seed) xml_dir Path(args.xml_dir) output_dir Path(args.output_dir) if not xml_dir.exists(): raise FileNotFoundError(fAnnotations目录不存在: {xml_dir}) output_dir.mkdir(parentsTrue, exist_okTrue) xml_files sorted([f.name for f in xml_dir.glob(*.xml)]) total_count len(xml_files) indices list(range(total_count)) trainval_size int(total_count * args.trainval) trainval_indices random.sample(indices, trainval_size) train_size int(trainval_size * args.train) train_indices random.sample(trainval_indices, train_size) # 写入分割文件 splits { trainval.txt: trainval_indices, test.txt: [i for i in indices if i not in trainval_indices], train.txt: train_indices, val.txt: [i for i in trainval_indices if i not in train_indices] } for filename, idx_list in splits.items(): with open(output_dir / filename, w) as f: for idx in idx_list: f.write(f{Path(xml_files[idx]).stem}\n) print(f数据集分割完成共处理{xml_files}个XML文件) print(f分割比例训练集{len(train_indices)/total_count:.1%} f验证集{(trainval_size-train_size)/total_count:.1%} f测试集{(total_count-trainval_size)/total_count:.1%}) if __name__ __main__: main()2.2 关键参数配置指南脚本包含几个重要参数需要根据实际需求调整参数名类型默认值说明适用场景--trainvalfloat0.8训练验证集占总数据比例常规数据集(1k-10k样本)--trainfloat0.9训练集占训练验证集比例中等规模数据集--seedintNone随机种子需要可重复实验时--xml-dirstr必填Annotations目录路径所有场景--output-dirstr必填输出目录路径所有场景注意对于小样本数据集(少于500个样本)建议调整--trainval为0.7左右以确保测试集有足够样本。3. 高级应用场景与优化策略3.1 处理类别不均衡数据集当数据集中某些类别样本过少时简单随机分割可能导致某些类别在验证集中缺失。以下是改进方案def stratified_split(xml_dir, output_dir, trainval_ratio0.8): from collections import defaultdict import xml.etree.ElementTree as ET # 按类别收集样本 class_samples defaultdict(list) for xml_file in Path(xml_dir).glob(*.xml): tree ET.parse(xml_file) classes {obj.find(name).text for obj in tree.findall(object)} for cls in classes: class_samples[cls].append(xml_file.stem) # 对每个类别独立分割 splits defaultdict(list) for cls, samples in class_samples.items(): random.shuffle(samples) split_point int(len(samples) * trainval_ratio) splits[trainval] samples[:split_point] splits[test] samples[split_point:] # 写入文件 for split_name, samples in splits.items(): with open(f{output_dir}/{split_name}.txt, w) as f: f.write(\n.join(set(samples)) \n)3.2 小样本数据集的特殊处理当样本量较少时(如200)建议使用分层k折交叉验证代替固定分割调整分割比例为60/20/20(训练/验证/测试)实施数据增强策略以下是k折交叉验证的实现示例from sklearn.model_selection import KFold def kfold_split(xml_dir, output_dir, n_splits5): xml_files sorted([f.stem for f in Path(xml_dir).glob(*.xml)]) kf KFold(n_splitsn_splits, shuffleTrue) for fold, (train_idx, test_idx) in enumerate(kf.split(xml_files)): fold_dir Path(output_dir) / ffold_{fold} fold_dir.mkdir(exist_okTrue) with open(fold_dir/train.txt, w) as f: f.write(\n.join([xml_files[i] for i in train_idx]) \n) with open(fold_dir/test.txt, w) as f: f.write(\n.join([xml_files[i] for i in test_idx]) \n)4. 工程实践中的常见问题与解决方案4.1 路径处理最佳实践在跨平台环境中路径处理需要特别注意# 不推荐 - Windows特定路径 xml_path D:\\data\\VOC\\Annotations # 推荐 - 使用Pathlib跨平台方案 from pathlib import Path xml_path Path(/data/VOC/Annotations) # Linux/macOS xml_path Path(D:/data/VOC/Annotations) # Windows也适用4.2 随机种子与可重复性在科研场景中实验可重复性至关重要。设置随机种子时要注意在脚本开始时设置全局种子避免在多线程环境中依赖随机性记录使用的种子值import random import numpy as np import torch def set_seed(seed42): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) if torch.cuda.is_available(): torch.cuda.manual_seed_all(seed)4.3 性能优化技巧处理大规模数据集时(10k样本)可以考虑以下优化使用多进程处理缓存文件列表使用更高效的文件写入方式from multiprocessing import Pool def process_chunk(chunk): # 处理数据块 return processed_chunk with Pool(processes4) as pool: results pool.map(process_chunk, large_file_list)在实际项目中我发现将分割脚本与数据预处理流水线集成可以显著提升效率。例如可以在生成分割文件的同时计算数据集统计信息如类别分布、图像尺寸等为后续模型训练提供参考。

相关文章:

告别手动分割!用Python脚本一键生成VOC数据集所需的train.txt和val.txt

告别手动分割!用Python脚本一键生成VOC数据集所需的train.txt和val.txt 在计算机视觉项目中,数据集的准备往往是耗时最长的环节之一。特别是当我们需要按照VOC格式整理数据集时,手动分割训练集、验证集不仅效率低下,还容易引入人为…...

别再只用默认样式了!手把手教你定制LVGL Bar进度条的3种高级视觉效果

突破视觉边界:LVGL进度条高级定制技法三则 在嵌入式UI开发领域,LVGL以其轻量级和高度可定制性赢得了众多开发者的青睐。但当我们超越基础功能实现,进入视觉表现力的深水区时,这个开源图形库的真正魅力才开始显现。进度条作为人机交…...

安科士(AndXe)SPF-10G-T :10G 电口模块,重塑短距网络升级性价比

数字化转型浪潮下,企业园区、数据中心对10Gbps 高速互联的需求呈爆发式增长。但传统 10G 升级方案深陷困境:光纤布线成本高昂、施工周期长且需专业运维技能,而多数企业机架内、相邻机架间及办公楼层内的链路距离普遍低于 30 米,光…...

5分钟掌握终极音乐解密方案:Unlock Music Electron完整指南

5分钟掌握终极音乐解密方案:Unlock Music Electron完整指南 【免费下载链接】unlock-music-electron Unlock Music Project - Electron Edition 在Electron构建的桌面应用中解锁各种加密的音乐文件 项目地址: https://gitcode.com/gh_mirrors/un/unlock-music-ele…...

Hive 3.1.3部署后,你可能会遇到的3个连接与权限报错及解决实录

Hive 3.1.3部署后三大经典连接与权限问题深度解析 当你终于按照教程完成Hive 3.1.3的安装,却在最后连接阶段遭遇各种"拦路虎"时,那种挫败感我深有体会。本文将带你直击三个最具代表性的连接与权限问题,从报错现象到根因分析&#x…...

TranslucentTB:让Windows任务栏变透明的终极指南

TranslucentTB:让Windows任务栏变透明的终极指南 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB 你是否厌倦了Windows任务栏那…...

告别CubeMX思维定式:用S32DS的Processor Expert玩转S32K144外设配置(含FreeRTOS组件添加)

从CubeMX到Processor Expert:S32K144高效开发实战指南 在嵌入式开发领域,工具链的选择往往决定了开发效率的上限。对于习惯了ST生态的开发者来说,CubeMX的图形化配置已成为肌肉记忆般的操作。但当项目需求将我们推向NXP的S32K系列时&#xff…...

HeyGen免费额度怎么用最值?我用1个积分做了个多语言口播视频(附保姆级教程)

HeyGen免费额度高效使用指南:1积分打造多语言口播视频 第一次接触HeyGen时,我被它逼真的口型同步技术震撼了——直到发现免费账户只有1个积分。这就像得到一颗钻石却只能刮一次玻璃。经过两周的反复测试,我总结出一套**"1积分最大化&quo…...

从手机镜头到AR眼镜:几何光学三大定律如何塑造你身边的成像技术

从手机镜头到AR眼镜:几何光学三大定律如何塑造你身边的成像技术 当你用手机拍下一张照片,或是戴上AR眼镜看到虚拟与现实融合的世界时,背后其实隐藏着几个世纪前就被发现的物理定律。这些看似高深的光学原理,正以最直接的方式影响…...

用GoC画图搞定2018年5月那道‘场记板’编程题,附完整代码和思路拆解

用GoC画图还原2018年场记板编程题的完整解题思路 第一次看到这道场记板题目时,许多同学会被"n条竖线"的要求难住。其实只要拆解图形结构,用GoC的基础命令就能轻松实现。本文将从零开始,带你用分治法拆解这个经典考题,不…...

别再死记硬背了!图解ASCII码表,轻松掌握C语言字符处理的底层逻辑

从ASCII到C语言:用图形化思维解锁字符处理的本质 在初学C语言时,很多人都会对char类型和int类型之间的暧昧关系感到困惑。为什么一个字符可以像整数一样进行加减运算?为什么大小写字母转换只需要简单地加减32?这些看似神奇的操作背…...

保姆级教程:在Ubuntu 22.04上用Netplan搞定Bond+VLAN+Bridge混合网络(附H3C交换机配置)

企业级网络架构实战:Ubuntu 22.04下BondVLANBridge混合部署指南 在虚拟化环境和云计算基础设施中,网络架构的可靠性和灵活性至关重要。本文将深入探讨如何在Ubuntu 22.04系统上,通过Netplan配置工具实现Bond(链路聚合)…...

2026年PCB行业研究报告

随着全球算力需求爆发式增长,印制电路板(PCB)已从传统的电子连接载体,演进为决定AI集群信号完整性的核心物理瓶颈。PCB不仅是电子工业的母板,更是支撑人工智能与大数据等新质生产力落地的底层基石。当前,行…...

从QPLL与CPLL选型到线速计算:一份给Xilinx GTY新手的时钟配置速查手册

从QPLL与CPLL选型到线速计算:一份给Xilinx GTY新手的时钟配置速查手册 第一次接触Xilinx UltraScale系列FPGA的GTY收发器时,最让人头疼的莫过于时钟配置。面对QPLL0、QPLL1和CPLL三种时钟源,以及N1、N2、M、D等分频参数,新手工程师…...

CAN总线电压测试避坑指南:用示波器实测显性/隐性电平,别再被CAN_H和CAN_L的命名误导了

CAN总线电压测试实战手册:从示波器设置到波形解读的完整指南 实验室里,工程师小王盯着示波器屏幕上跳动的波形皱起了眉头——按照教科书上的说法,CAN_H电压应该始终高于CAN_L,但眼前的波形却显示在总线空闲时CAN_L电压反而更高。这…...

QMCDecode:3步解锁QQ音乐加密音频,让音乐真正属于你!

QMCDecode:3步解锁QQ音乐加密音频,让音乐真正属于你! 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac,qmc0,qmc3转mp3, mflac,mflac0等转flac),仅支持macOS,可自动识别到QQ音乐下载…...

别再让你的App‘抢麦’了!Android AudioFocus避坑指南与实战(附8.0+新API详解)

Android音频焦点管理实战:从冲突解决到优雅兼容 音乐播放器突然被通知音打断后无法恢复?语音助手播报时被来电强行中断?这些看似简单的音频冲突背后,是Android音频焦点机制的复杂运作。作为开发者,我们常常低估了正确处…...

RDP Wrapper实用指南:三步解决[not supported]错误的高效方法

RDP Wrapper实用指南:三步解决[not supported]错误的高效方法 【免费下载链接】rdpwrap RDP Wrapper Library 项目地址: https://gitcode.com/gh_mirrors/rd/rdpwrap RDP Wrapper是一款让Windows家庭版支持多用户远程桌面连接的开源工具,但许多用…...

STM32以太网实战:手把手教你配置SMI接口,搞定PHY寄存器读写

STM32以太网实战:手把手教你配置SMI接口,搞定PHY寄存器读写 在嵌入式以太网开发中,PHY芯片的配置往往是项目成败的关键。很多开发者能够轻松完成MAC层的初始化,却在PHY寄存器读写这个环节卡壳——明明硬件连接正确,却无…...

高工独家报告|谁在收割2026智驾市场红利?440万辆背后的芯片大洗牌

高工智能汽车研究院发布《2026年中国市场智能汽车SoC芯片行业分析报告》。报告立足中国乘用车市场,基于乘用车前装量产数据库,全面解析智能驾驶SoC(含前视一体机、域控制器及高阶自动驾驶辅助芯片)与智能座舱SoC(含端侧…...

CAXA 表格样式

位置属性和 CAD 类似默认【标准】自带,删不掉。预览常规-表格方向向上;向下;单元样式标题;表头;数据;【切换】对应下方 常规、文字的属性设置。常规【对齐】创建行时合并单元:文字命令位置先设置…...

别再怪PoE不稳定了!手把手教你排查网线、供电、配置三大坑(附真实监控项目踩坑实录)

PoE稳定性实战指南:从网线到供电的深度排查手册 凌晨三点,监控室突然响起警报——某重要区域的摄像头集体离线。值班工程师的第一反应往往是"设备又坏了",但真实情况可能藏在那些容易被忽略的细节里:一根劣质网线在低温…...

深入Linux内核:图解PTP硬件时间戳(HW Timestamp)从网卡到用户空间的完整路径

深入Linux内核:图解PTP硬件时间戳从网卡到用户空间的完整路径 1. 高精度时间同步的技术演进与PTP核心价值 在分布式系统与工业自动化领域,微秒级甚至纳秒级的时间同步已成为刚需。传统NTP协议受限于软件实现和网络抖动,精度通常只能达到毫秒级…...

使用C#代码在 PowerPoint 中组合或取消组合形状

在 PowerPoint 中,对形状进行组合和取消组合是两个非常实用的功能。通过组合,您可以将多个形状整合为一个整体,从而像操作单个对象一样同时移动、设置格式、调整大小或旋转这些形状。而取消组合则可以解除这些形状之间的关联,使您…...

2026 AI 标书工具深度测评:技术原理、功能对比与选型指南

一、行业背景与测评说明1.1 招投标行业数字化痛点传统标书制作存在三大核心痛点:效率低下:一份 100 页的标准标书,纯人工制作需 3-5 天,其中 80% 时间用于解析招标文件、整理框架和填充通用内容废标风险高:据行业统计&…...

Blender3mfFormat终极指南:开启3D打印无缝工作流的新时代

Blender3mfFormat终极指南:开启3D打印无缝工作流的新时代 【免费下载链接】Blender3mfFormat Blender add-on to import/export 3MF files 项目地址: https://gitcode.com/gh_mirrors/bl/Blender3mfFormat 你是否曾为Blender与3D打印软件之间的格式转换而烦恼…...

2023年天梯赛真题解析L2-2(优先级队列)

L2-046 天梯赛的赛场安排 题目链接: https://pintia.cn/problem-sets/994805046380707840/exam/problems/type/7?problemSetProblemId1649748772841508873&page1 题目分析: 本题的考点是结构体优先级队列,因为每个学校包含的信息较多&am…...

工业内窥镜哪家好用?

经常有不同行业的朋友问我,工业内窥镜品牌这么多,到底该怎么选?其实对于大多数企业来说,选择一款适用性广、能满足多种检测场景的设备,才是最划算的。我用了这么多年韦林工业内窥镜,最大的感受就是它几乎能…...

微信小程序 健身服务与轻食间平台系统健身减肥系统

目录同行可拿货,招校园代理 ,本人源头供货商项目概述核心功能模块技术实现亮点商业模式差异化优势项目技术支持源码获取详细视频演示 :同行可合作点击我获取源码->获取博主联系方式->进我个人主页-->同行可拿货,招校园代理 ,本人源头供货商 项目概述 微信…...

昇腾环境300v pro 搭建qwen3 vl

1.启动dockerdocker run -itd \--name qwen-vl-serve \--nethost \--device/dev/davinci0 \--device/dev/davinci_manager \--device/dev/devmm_svm \--device/dev/hisi_hdc \-v /home/zhouty/Qwen3-VL-8B-Instruct:/workspace/models \-v /usr/local/Ascend/driver:/usr/local…...