NuScenes 数据集合并工具 NuScenes 数据集合并工具一、背景介绍在自动驾驶感知算法的研发过程中数据集的规模和多样性直接影响模型的泛化能力。NuScenes作为自动驾驶领域最具影响力的公开数据集之一提供了丰富的多传感器数据和精细的标注信息。然而实际项目中常常需要整合多个来源的数据集以构建更大规模的训练数据。问题挑战合并 NuScenes 格式数据集并非简单的文件复制主要面临以下技术难题Token 冲突每个数据对象scene、sample、annotation 等都有唯一的 token 标识直接合并会导致重复跨数据集引用数据对象之间存在复杂的引用关系如 sample 引用 scene、annotation 引用 instance跨数据集时引用会失效类别映射不同数据集可能使用不同的 category token 标识同一类别文件冲突同名的数据文件需要重命名避免覆盖场景结构维护打乱样本后需要重新维护 scene-sample 的层级关系和样本间的 prev/next 链接。二、设计思路2.1 整体架构┌─────────────────┐ ┌─────────────────┐ │ Dataset 1 │ │ Dataset 2 │ └────────┬────────┘ └────────┬────────┘ │ │ ▼ ▼ ┌───────────────────────────────────────────┐ │ NuScenesMerger │ │ ┌─────────────────────────────────────┐ │ │ │ 1. Static Files Copy │ │ │ │ (attribute, category, sensor...) │ │ │ ├─────────────────────────────────────┤ │ │ │ 2. Token Mapping │ │ │ │ (category_token, calib_token) │ │ │ ├─────────────────────────────────────┤ │ │ │ 3. Dynamic Data Processing │ │ │ │ (scene, sample, annotation...) │ │ │ ├─────────────────────────────────────┤ │ │ │ 4. Sample Shuffling (Optional) │ │ │ ├─────────────────────────────────────┤ │ │ │ 5. File Copy Rename │ │ │ └─────────────────────────────────────┘ │ └──────────────────────┬───────────────────┘ │ ▼ ┌─────────────────┐ │ Merged Dataset │ └─────────────────┘2.2 核心设计原则原则说明Token 全局重映射使用 UUID 生成新 token建立 old_token → new_token 的映射表静态文件优先保留 dataset1 的静态元数据category、sensor 等确保类别体系一致动态数据合并对 scene、sample、annotation 等动态数据进行逐对象处理跨数据集引用修复建立 category_token 和 calibrated_sensor_token 的跨数据集映射文件唯一性保证通过在文件名后追加 UUID 后缀避免冲突三、功能介绍3.1 核心功能1.数据集合并支持两个 NuScenes 格式数据集的完整合并自动处理所有 JSON 元数据文件智能复制并重命名数据文件2.Token 管理自动生成新 token 避免冲突维护完整的 token 映射关系修复跨数据集的 token 引用3.样本打乱Shuffle跨场景打乱所有样本重新建立 scene-sample 层级关系修复样本间的 prev/next 链接支持随机种子保证可复现性4.完整性验证检查并修复无效的 token 引用自动处理孤立的 prev/next 链接3.2 命令行接口# 基础用法python merge_nuscenes_datasets.py dataset1/nuscenes dataset2/nuscenes# 启用样本打乱python merge_nuscenes_datasets.py dataset1/nuscenes dataset2/nuscenes--shuffle# 启用打乱并指定随机种子python merge_nuscenes_datasets.py dataset1/nuscenes dataset2/nuscenes--shuffle12345四、核心代码讲解4.1 Token 映射机制def_remap_token(self,old_token:str)-str:Remap a token to a new unique tokenifold_tokennotinself.token_map:self.token_map[old_token]self._generate_new_token()returnself.token_map[old_token]设计要点使用字典self.token_map维护 old_token → new_token 的映射相同的 old_token 始终映射到相同的 new_token保证引用一致性使用 UUID4 生成新 token确保全局唯一性4.2 类别跨数据集映射def_build_category_mapping(self):Build mapping from dataset2 category tokens to dataset1 category tokenscat1self._load_json(os.path.join(self.dataset1_path,v1.0-mini,category.json))cat2self._load_json(os.path.join(self.dataset2_path,v1.0-mini,category.json))name_to_token1{cat[name]:cat[token]forcatincat1}forname,token2inname_to_token2.items():ifnameinname_to_token1:self.category_token_map[token2]name_to_token1[name]解决的问题不同数据集可能为同一类别如car分配不同的 token通过类别名称建立映射关系确保合并后类别引用一致。4.3 递归 Token 重映射def_remap_tokens_in_data(self,data:Any,is_dataset2:boolFalse)-Any:Recursively remap all tokens in data structureifisinstance(data,dict):new_data{}forkey,valueindata.items():ifkeytoken:new_data[key]self._remap_token(value)elifkeycategory_tokenandis_dataset2:ifvalueinself.category_token_map:new_data[key]self.category_token_map[value]elifkeyin[scene_token,sample_token,ego_pose_token,...]:ifisinstance(value,str)andvalue:new_data[key]self._remap_token(value)......核心逻辑递归遍历嵌套数据结构根据字段名识别需要重映射的 token对 dataset2 的 category_token 进行特殊处理映射到 dataset1 的对应 token4.4 样本打乱算法def_shuffle_samples(self):Shuffle all samples across scenesrandom.seed(self.shuffle_seed)# Shuffle all samplesall_samplesself.all_samples random.shuffle(all_samples)# Distribute samples evenly across scenessamples_per_scenelen(all_samples)//len(self.all_scenes)remainderlen(all_samples)%len(self.all_scenes)# Reset and rebuild scene-sample relationshipsforsceneinself.all_scenes:scene[first_sample_token]scene[last_sample_token]sample_idx0forscene_idx,sceneinenumerate(self.all_scenes):scene_samplesall_samples[sample_idx:sample_idxsamples_per_scene(1ifscene_idxremainderelse0)]sample_idxlen(scene_samples)# Update scene referencesscene[first_sample_token]scene_samples[0][token]scene[last_sample_token]scene_samples[-1][token]# Update prev/next linksfori,sampleinenumerate(scene_samples):sample[scene_token]scene[token]sample[prev]scene_samples[i-1][token]ifi0elsesample[next]scene_samples[i1][token]ifilen(scene_samples)-1else算法流程打乱样本使用 Fisher-Yates 算法随机打乱所有样本均匀分配按场景数量均分样本余数均匀分配到前 N 个场景重建链接更新每个场景的 first/last_sample_token修复样本间的双向链表。4.5 无效引用修复# Check and fix prev referenceifsample[prev]:ifsample[prev]insample_tokens:sample[prev]self._remap_token(sample[prev])else:sample[prev]# Invalid reference, set to empty设计考虑dataset2 中的样本可能引用了 dataset1 中不存在的 token如 prev 指向 dataset1 的样本通过预收集当前数据集的所有 token过滤无效引用。五、典型应用场景5.1 数据集扩充场景将两个采集批次的数据合并为一个更大的训练集。python merge_nuscenes_datasets.py batch1/nuscenes batch2/nuscenes价值扩大训练数据规模提升模型泛化能力。5.2 数据增强场景通过打乱样本顺序破坏原有场景的时间连续性增强模型对随机时序数据的鲁棒性。python merge_nuscenes_datasets.py train_set1/nuscenes train_set2/nuscenes--shuffle42价值防止模型学习到数据集的时序偏差提升实际部署效果。5.3 跨域数据融合场景合并不同城市、不同天气条件下采集的数据。python merge_nuscenes_datasets.py beijing/nuscenes shanghai/nuscenes--shuffle价值构建多样化数据集增强模型对不同环境的适应性。5.4 数据集版本管理场景合并同一项目的不同版本数据集保持数据格式一致性。python merge_nuscenes_datasets.py v1.0/nuscenes v2.0/nuscenes价值简化数据版本管理确保实验可复现性。六、技术亮点6.1 安全性设计特性实现方式文件覆盖保护复制前检查目标文件是否存在输出警告信息原始数据保护使用.copy()创建副本避免修改原始数据异常处理对缺失文件进行容错处理输出警告而非中断6.2 可扩展性模块化设计每个功能独立为方法便于后续扩展配置化传感器传感器列表通过配置定义支持自定义传感器类型可复现性支持设置随机种子确保打乱结果可重复。6.3 性能优化单次遍历对每个数据集仅进行一次完整遍历内存效率按需加载 JSON 文件避免一次性加载全部数据批量操作使用列表扩展extend而非逐元素添加。七、总结merge_nuscenes_datasets.py是一个专业的 NuScenes 数据集合并工具解决了多数据集合并中的核心技术难题Token 冲突问题通过全局重映射机制保证唯一性跨数据集引用建立 category 和 calibrated_sensor 的映射关系样本打乱实现跨场景打乱并维护数据结构一致性数据完整性自动检测和修复无效引用。该工具已通过visualize_nuscenes.py验证生成的合并数据集完全符合 NuScenes 规范可直接用于模型训练和评估。