公司动态

利用UnrealCV与虚幻引擎批量生成高质量合成视觉数据集实战指南

📅 2026/7/22 7:45:21
利用UnrealCV与虚幻引擎批量生成高质量合成视觉数据集实战指南
1. 项目概述为什么选择UnrealCV来生成图像数据集如果你正在做计算机视觉项目无论是目标检测、语义分割还是深度估计最头疼的问题之一可能就是数据。公开数据集虽然多但场景、光照、物体种类往往受限自己用相机采集成本高、流程繁琐标注更是耗时耗力。更关键的是真实世界的数据很难做到“可控”——你想研究雨雪天气对算法的影响难道要等下雨下雪你想生成一个物体在360度不同光照下的精确图像在现实中几乎不可能。这就是为什么我们需要合成数据。而UnrealCV正是连接虚幻引擎Unreal Engine这个顶级3D渲染平台与Python编程世界的桥梁。它不是一个独立的软件而是一个运行在虚幻引擎内部的插件和一套通信协议。简单来说你可以用Python脚本像远程控制一个超级逼真的3D游戏一样指挥虚幻引擎里的相机移动、改变光照、抓取屏幕并同时获取每个像素对应的深度、法线、物体ID等“真值”信息。整个过程完全自动化生成的数据天生就是带精确标注的。我最初接触UnrealCV是为了一个室内场景理解的项目。当时我们需要大量带实例分割标注的家具图像手动标注了几百张就快崩溃了。转向UnrealCV后我在一个周末就用一个现成的3D室内场景生成了上万张不同视角、不同布局、不同光照条件下的图像每一张都自动带有像素级的物体类别和实例ID标签。效率的提升是数量级的而且数据的多样性远超想象。所以这个项目的核心价值在于用程序化、可复现的方式批量生成高质量、高保真、带丰富真值Ground Truth的合成图像数据集。它特别适合这几类人计算机视觉算法研究员需要特定、稀缺或难以采集的数据机器人仿真开发者需要真实的视觉输入来训练感知模型以及任何对高质量合成数据有需求的工程师。接下来我会带你从零开始拆解整个流程。2. 环境搭建与核心工具链解析工欲善其事必先利其器。用UnrealCV生成数据集你需要搭建一个由虚幻引擎、UnrealCV插件和Python客户端组成的“铁三角”。每一步的选择都直接影响后续开发的顺畅度。2.1 虚幻引擎版本选择与安装这是整个体系的基石。强烈建议使用Unreal Engine 4UE4的某个稳定版本而不是最新的UE5。原因很简单UnrealCV插件对UE4的支持最成熟、社区资源最多、踩坑的解决方案也最全。我亲身经历在UE5早期版本上配置UnrealCV会遇到各种插件兼容性和编译问题对于以生成为目的的项目来说稳定性远高于追求新特性。我的推荐是Unreal Engine 4.27.2。这是一个长期支持LTS版本非常稳定。你可以通过Epic Games启动器进行安装。安装时注意勾选你目标平台的支持如Windows但最重要的是确保安装目录不要有中文或空格这是很多C相关工具链的硬性要求。安装完成后建议先运行一次引擎创建一个空项目比如选择“第一人称”或“空白”模板确保引擎能正常启动。这一步是为了验证基础环境没问题。2.2 UnrealCV插件安装与项目配置UnrealCV本身是一个插件。官方推荐的方式是从GitHub下载发布版Release解压后放到你项目的Plugins文件夹下。但这里有个更稳妥的实操技巧不要直接下载master分支的代码而是下载针对特定UE4版本的发布包或者使用git克隆后切换到对应的tag。假设你的项目路径是D:\MyUnrealCVProject那么操作步骤如下在项目根目录下创建Plugins文件夹如果不存在。将下载的UnrealCV插件文件夹整个放入Plugins中。最终路径应该是D:\MyUnrealCVProject\Plugins\UnrealCV。用文本编辑器打开项目根目录下的MyUnrealCVProject.uproject文件这是一个JSON文件。在Modules部分之后添加一个Plugins部分确保包含以下内容Plugins: [ { Name: UnrealCV, Enabled: true } ]保存并关闭。然后双击这个.uproject文件启动项目。第一次启动时引擎会编译插件可能需要几分钟。如果编译成功在编辑器界面的“设置”-“插件”里你应该能看到“UnrealCV”插件已被启用。注意如果编译失败最常见的原因是Visual Studio的C开发工具包没有安装完整或者UE4的源码版本与插件不匹配。务必确保你的系统已安装“使用C的桌面开发”工作负载的Visual Studio 2019或2022。2.3 Python环境配置与客户端库安装Python端是我们的控制中心。你需要一个Python环境3.7均可然后安装UnrealCV的Python客户端库。这里强烈建议使用虚拟环境以避免包冲突。# 创建并激活虚拟环境以conda为例 conda create -n unrealcv python3.8 conda activate unrealcv # 安装unrealcv客户端库 pip install unrealcv这个unrealcvPython包非常轻量它只包含了与UE4编辑器通信的客户端协议。安装完成后你可以写一个最简单的测试脚本test_connection.pyimport unrealcv # 连接到默认的UE4编辑器运行在localhost:9000 client unrealcv.Client((localhost, 9000)) client.connect() if client.isconnected(): print(成功连接到UnrealCV服务器) # 尝试获取当前视图的屏幕分辨率 res client.request(vget /camera/0/location) print(f相机位置: {res}) else: print(连接失败请确保UE4编辑器已运行且UnrealCV插件已启用。)运行这个脚本前必须确保你的UE4项目已经打开并处于“运行”Play模式。因为UnrealCV的服务器只有在游戏运行时才启动。这是新手最容易忽略的一点不是打开编辑器就行必须要点击工具栏上的“运行”按钮。3. 核心工作流与场景准备环境搭好只是万里长征第一步。接下来我们要理解并设计整个数据生成的工作流。核心流程可以概括为准备3D场景 - 设置捕获参数 - 编写Python控制脚本 - 批量运行与数据保存。3.1 获取与准备3D资产场景你的数据质量很大程度上取决于3D场景的质量。你有几个选择虚幻商城Unreal Marketplace这是最丰富的资源库有大量免费和付费的高质量场景如“Archviz Explorer”、“Infinity Blade: Grasslands”等。这些场景通常材质、光照都非常出色开箱即用。自己用建模软件Blender, 3ds Max, Maya创建自由度最高但成本也最高需要专业的3D美术知识。使用开源数据集转换例如将ScanNet、Matterport3D等真实扫描数据集转换成UE4可用的格式。这个过程比较复杂涉及模型修复、材质赋予等。对于大多数研究和快速原型开发我推荐从虚幻商城找一个免费的室内或室外场景开始。下载后在Epic启动器的“库”-“保管库”中找到它并添加到你的项目中。导入场景后在UE4编辑器中你需要做几件关键事检查并修复材质有时商城的资源在新版本引擎中会有材质警告按照提示重新编译或连接缺失的纹理节点即可。设置物体IDObject Mask这是自动标注的关键。UnrealCV可以通过命令获取每个像素对应的物体ID。你需要确保场景中的每个需要独立标注的物体比如不同的椅子、桌子都有唯一的ID。这通常通过在物体的材质上设置“Custom Stencil Value”来实现。更高效的方法是使用UnrealCV提供的蓝图工具批量为场景中的静态网格体Static Mesh分配ID。优化性能如果你的场景非常庞大在批量生成时可能会遇到性能瓶颈。可以考虑在生成前关闭实时全局光照使用烘焙光照、降低阴影质量等以提升帧率加快捕获速度。3.2 理解UnrealCV的核心通信命令UnrealCV客户端与UE4的交互是通过发送一系列文本命令实现的。掌握这些命令是编写控制脚本的基础。主要命令分为几类1. 相机控制vset /camera/0/location {x} {y} {z}设置相机位置。vset /camera/0/rotation {pitch} {yaw} {roll}设置相机旋转单位度。vget /camera/0/location和vget /camera/0/rotation获取当前相机位姿。2. 图像捕获vget /camera/0/lit {format}捕获RGB彩色图像lit表示带光照的渲染结果。{format}可以是png或jpg。vget /camera/0/depth {format}捕获深度图。深度值默认是相机空间的Z值即距离可以指定为png16位或exr32位浮点更精确。vget /camera/0/object_mask {format}捕获物体ID图即实例分割标签。每个物体被渲染成其ID对应的纯色。3. 场景与物体查询vget /objects获取场景中所有对象的名称列表。vget /object/{obj_name}/location获取特定对象的位置。一个典型的交互例子是先用Python脚本随机生成一个相机位姿位置和角度通过vset命令发送给UE4然后依次请求lit、depth和object_mask将返回的图像数据保存到本地并记录下此时的相机位姿作为标注。这就构成了一条完整的数据样本。4. Python控制脚本的深度实现现在进入核心环节编写Python脚本将上述流程自动化、批量化。一个好的生成脚本应该是健壮、可配置且高效的。4.1 构建稳健的客户端连接与命令执行直接使用unrealcv.Client的基础请求有时不够稳定尤其是在长时间批量生成时。我们需要封装一个更健壮的辅助类。import unrealcv import time import numpy as np from PIL import Image import io class UnrealCVClient: def __init__(self, host127.0.0.1, port9000): self.client unrealcv.Client((host, port)) self._connect() def _connect(self, max_retries5): 带重试机制的连接 for i in range(max_retries): try: self.client.connect() if self.client.isconnected(): print(f第{i1}次尝试连接成功。) # 连接后建议等待一帧让场景稳定 time.sleep(2.0) return True except Exception as e: print(f第{i1}次连接尝试失败: {e}) time.sleep(3.0) # 等待更长时间再重试 raise ConnectionError(f无法连接到UnrealCV服务器 {self.client.host}:{self.client.port}) def safe_request(self, cmd, delay0.1): 安全发送命令并处理潜在错误 try: if not self.client.isconnected(): self._connect() time.sleep(delay) # 命令间的小延迟避免服务器过载 res self.client.request(cmd) # 检查返回是否包含错误信息 if isinstance(res, str) and res.startswith(Error): raise RuntimeError(fUnrealCV命令错误: {cmd} - {res}) return res except Exception as e: print(f命令执行失败 {cmd}: {e}) # 这里可以加入更复杂的重连和重试逻辑 raise def capture_frame(self, save_dir, frame_id, capture_maskTrue): 捕获一帧数据RGB、深度、可选物体掩码 base_filename f{save_dir}/frame_{frame_id:06d} # 1. 捕获RGB图像 res_lit self.safe_request(vget /camera/0/lit png) with open(f{base_filename}_rgb.png, wb) as f: f.write(res_lit) # 2. 捕获深度图使用EXR格式保留浮点精度 res_depth self.safe_request(vget /camera/0/depth exr) with open(f{base_filename}_depth.exr, wb) as f: f.write(res_depth) # 注意EXR文件需要专门的库如OpenEXR来读取也可以选择png但会量化 # 3. 捕获物体ID掩码 if capture_mask: res_mask self.safe_request(vget /camera/0/object_mask png) with open(f{base_filename}_mask.png, wb) as f: f.write(res_mask) # 4. 同时记录当前相机位姿 loc self.safe_request(vget /camera/0/location) rot self.safe_request(vget /camera/0/rotation) with open(f{base_filename}_pose.txt, w) as f: f.write(fLocation: {loc}\n) f.write(fRotation: {rot}\n) print(f已保存帧: {base_filename}) return True这个类做了几件关键事实现了带重试的连接逻辑封装了命令请求并加入了错误检查提供了延迟以避免请求风暴并将一帧数据的捕获过程函数化。4.2 设计相机轨迹与采样策略如何让生成的图像数据集“有用”关键在于相机位姿的采样策略。你不能让相机乱飞生成一堆无意义的图像。1. 随机采样最简单的方法是在场景的可行走区域Bounding Box内随机生成位置并随机生成朝向。适用于需要大量、多样背景的数据。def random_pose(scene_bounds): # scene_bounds: {min: [x,y,z], max: [x,y,z]} x np.random.uniform(scene_bounds[min][0], scene_bounds[max][0]) y np.random.uniform(scene_bounds[min][1], scene_bounds[max][1]) z np.random.uniform(scene_bounds[min][2], scene_bounds[max][2]) # 通常高度固定 yaw np.random.uniform(0, 360) pitch np.random.uniform(-30, 30) # 避免极端俯仰角 return (x, y, z), (pitch, yaw, 0)2. 环绕采样Orbit Sampling非常适合物体-centric的数据集。固定一个目标点比如一个物体的中心让相机在球面上移动始终看向目标。def orbit_pose(center, radius, azimuth, elevation): # 将球坐标转换为笛卡尔坐标 x center[0] radius * np.cos(np.radians(elevation)) * np.sin(np.radians(azimuth)) y center[1] radius * np.cos(np.radians(elevation)) * np.cos(np.radians(azimuth)) z center[2] radius * np.sin(np.radians(elevation)) # 计算相机朝向目标点的旋转这里需要一些向量计算略复杂 # 可以使用 lookat 函数计算所需的yaw和pitch return (x, y, z), calculated_rotation3. 路径采样Path Sampling模拟机器人或自动驾驶汽车的行驶路径。你可以先在UE4编辑器中手动放置一些“路点”Spline然后在Python脚本中读取这些路点并在它们之间进行插值生成平滑的相机轨迹。4. 光照与天气变化除了相机还可以通过命令动态改变光照强度、颜色、方向甚至启用雨、雪等天气特效如果场景支持从而在相同视角下生成不同光照条件的数据极大地增强数据集的多样性。# 示例改变定向光源太阳的旋转和强度 self.safe_request(vset /sun/rotation {pitch} {yaw} {roll}) self.safe_request(vset /sun/intensity {value})4.3 实现批量生成与数据管理将采样策略和捕获函数结合起来就构成了主循环。此外一个完整的数据生成管道还需要考虑数据管理。import os import json import argparse def main(): parser argparse.ArgumentParser(descriptionUnrealCV 数据集批量生成) parser.add_argument(--output_dir, typestr, default./dataset, help输出目录) parser.add_argument(--num_frames, typeint, default1000, help生成帧数) parser.add_argument(--scene_bounds, typefloat, nargs6, default[-500,-500,100,500,500,300], help场景边界[min_x, min_y, min_z, max_x, max_y, max_z]) args parser.parse_args() # 创建输出目录结构 os.makedirs(args.output_dir, exist_okTrue) rgb_dir os.path.join(args.output_dir, rgb) depth_dir os.path.join(args.output_dir, depth) mask_dir os.path.join(args.output_dir, mask) pose_dir os.path.join(args.output_dir, pose) for d in [rgb_dir, depth_dir, mask_dir, pose_dir]: os.makedirs(d, exist_okTrue) # 初始化客户端 client UnrealCVClient() # 保存数据集元信息 meta_info { num_frames: args.num_frames, scene_bounds: args.scene_bounds, capture_time: time.strftime(%Y-%m-%d %H:%M:%S), unrealcv_version: 1.0 # 可以实际获取 } with open(os.path.join(args.output_dir, meta.json), w) as f: json.dump(meta_info, f, indent4) # 主生成循环 for i in range(args.num_frames): print(f生成第 {i1}/{args.num_frames} 帧...) try: # 1. 生成随机相机位姿 bounds_dict {min: args.scene_bounds[:3], max: args.scene_bounds[3:]} loc, rot random_pose(bounds_dict) # 2. 设置相机 loc_cmd fvset /camera/0/location {loc[0]} {loc[1]} {loc[2]} rot_cmd fvset /camera/0/rotation {rot[0]} {rot[1]} {rot[2]} client.safe_request(loc_cmd, delay0.2) client.safe_request(rot_cmd, delay0.2) # 3. 可选随机调整光照每10帧调一次增加多样性 if i % 10 0: sun_yaw np.random.uniform(0, 360) sun_pitch np.random.uniform(20, 80) # 模拟白天不同时段 client.safe_request(fvset /sun/rotation {sun_pitch} {sun_yaw} 0) client.safe_request(fvset /sun/intensity {np.random.uniform(0.8, 1.2)}) # 4. 捕获并保存数据 # 这里简化实际应将路径传给capture_frame frame_data client.capture_frame(args.output_dir, i) # 可以在这里将位姿信息写入一个总的poses.txt文件 # 5. 进度保存与容错 if i % 100 0: print(f已保存 {i} 帧当前位姿: {loc}, {rot}) # 可以保存一个检查点文件防止程序意外中断后从头开始 except KeyboardInterrupt: print(用户中断生成。) break except Exception as e: print(f生成第{i}帧时发生错误: {e}) # 记录错误帧号跳过继续 with open(os.path.join(args.output_dir, error_log.txt), a) as f: f.write(fFrame {i}: {e}\n) time.sleep(5.0) # 出错后等待更长时间 continue print(数据集生成完成) if __name__ __main__: main()这个脚本展示了完整的流程参数解析、目录创建、元数据保存、带错误处理的主循环以及可扩展的光照变化。你可以根据需要修改采样策略、增加更多的场景交互如随机开关门、移动物体等。5. 高级技巧与性能优化实战当数据量需求上升到数万甚至数十万时基础流程会遇到性能瓶颈。以下是我在实践中总结的几个关键优化点。5.1 渲染与捕获的性能调优1. 分辨率与图像格式vget /camera/0/lit png默认捕获的是编辑器视口的分辨率。你可以在请求前用vset /camera/0/screen_resolution {width} {height}来设置。更高的分辨率意味着更长的渲染和传输时间。对于训练数据640x480或1024x768通常是平衡质量和速度的甜点。深度图格式选择exr格式保留32位浮点精度但文件大读写慢。如果不需要毫米级的深度精度使用png16位可以大幅减少磁盘I/O压力。你需要了解深度值的映射关系通常是线性或反向Z并在后续处理时进行转换。2. 关闭不必要的渲染特性在UE4编辑器的“运行”模式下你可以通过命令或修改项目设置来临时关闭昂贵的特效提升帧率。# 在生成循环开始前发送命令关闭一些后期处理效果 client.safe_request(vset /postprocess/0/antialiasing 0) # 关闭抗锯齿 client.safe_request(vset /postprocess/0/ambientocclusion 0) # 关闭环境光遮蔽 client.safe_request(vset /postprocess/0/motionblur 0) # 关闭运动模糊 # 生成结束后再恢复更彻底的方法是为数据生成专门创建一个“开发”质量等级在项目设置中将其所有特效调到最低。3. 多进程并行生成单进程单次捕获是串行的。一个强大的优化是同时运行多个UE4编辑器实例每个实例加载相同的场景但监听不同的端口如9000, 9001, 9002...然后用Python的多进程multiprocessing库让每个进程控制一个客户端并行生成数据。 这需要你的机器有足够的内存每个UE4实例可能占用2-4GB和强大的CPU/GPU。但可以将生成速度提升近线性取决于核心数。5.2 数据标注的后处理与格式转换UnrealCV直接生成的是“原始”数据要用于训练通常需要后处理。1. 物体掩码Object Mask到语义/实例标签object_mask图像是每个物体渲染成其ID对应的颜色通常是RGB值。你需要一个映射文件将每个颜色对应到具体的物体类别和实例ID。在生成前通过vget /objects命令获取所有物体名称和其ID的映射并保存为JSON。后处理时读取mask.png将每个像素的RGB值与映射表对比生成两张图语义分割图Semantic Segmentation每个像素值为类别ID。实例分割图Instance Segmentation每个像素值为实例ID。 这步可以用OpenCV和NumPy高效完成。2. 深度图转换从UE4捕获的深度值通常是相机空间的Z值需要转换到真实的物理距离米。转换公式取决于项目的投影设置。一个常见的公式是depth_meters depth_scale * raw_depth depth_offset。depth_scale和depth_offset需要通过一个已知距离的标定来获取或者查阅UnrealCV的相关文档。处理后的深度图可以保存为16位的PNG以毫米为单位以节省空间。3. 生成标准数据集格式为了便于使用最好将数据组织成主流框架如COCO、Cityscapes的格式。例如为COCO格式生成instances_train.json文件其中包含images,annotations,categories字段。这需要你编写脚本将每张图片的实例掩码转换成多边形RLE编码并填入JSON结构。5.3 场景动态化与程序化内容生成PCG要让数据集无限接近真实世界的复杂性静态场景是不够的。我们需要引入变化。1. 物体随机化位置/旋转/缩放随机化在生成每帧前随机移动、旋转或缩放场景中的某些物体如椅子、杯子。可以通过vset /object/{name}/location等命令实现。外观随机化通过命令或材质参数集合Material Parameter Collection随机改变物体的颜色、纹理粗糙度、金属度等材质属性。这能极大地增加数据在外观层面的多样性。2. 程序化布局生成对于室内场景你可以编写脚本根据规则如沿着墙壁放置家具程序化地生成不同的房间布局。这需要更深入地与UE4的Actor生成和放置API交互超出了基础UnrealCV命令的范围可能需要用到UE4的Python脚本unrealPython模块或蓝图与UnrealCV的结合。3. 光照与天气循环模拟一天中不同时间清晨、正午、黄昏、夜晚的光照以及不同的天气条件晴天、阴天、雨天。这可以通过控制天空球Sky Sphere、定向光源、指数高度雾Exponential Height Fog以及后期处理体积Post Process Volume的参数来实现。将这些参数的变化编入你的采样策略就能生成具有强大光照鲁棒性的数据集。6. 避坑指南与常见问题排查即使按照教程操作你也一定会遇到各种问题。以下是我和同事们踩过的主要的“坑”及其解决方案。6.1 连接与通信故障问题1Python脚本无法连接提示Connection refused。检查1UE4编辑器是否处于“运行”Play模式UnrealCV服务器只在游戏运行时启动。必须点击编辑器工具栏上的“运行”按钮或按F8看到视口左下角有“UnrealCV Server started”的日志输出才算成功。检查2端口是否正确默认端口是9000。确保没有其他程序占用该端口。你可以在UE4的“输出日志”Output Log窗口中搜索“UnrealCV”来确认服务器启动和监听的端口。检查3防火墙是否阻止临时关闭Windows防火墙或添加入站规则允许UE4编辑器通过端口9000。问题2连接成功但发送命令后无响应或返回错误。可能1命令格式错误。UnrealCV命令对大小写和空格敏感。确保命令与文档完全一致。使用vget /help可以查看命令列表。可能2对象名称不存在。使用vget /objects确认场景中物体的确切名称。名称可能包含空格或特殊字符在命令中需要用引号包裹。可能3插件未正确编译或启用。检查项目插件目录并确保在.uproject文件中已启用。尝试重启UE4编辑器。6.2 渲染与数据质量问题问题3捕获的图像是全黑或全白的。对于RGB图全黑很可能场景没有有效光照。检查场景中的光源Directional Light, Point Light是否被启用强度是否大于0。在捕获前可以先用vget /camera/0/lit命令测试一下。对于深度图全白深度值可能超出了PNG格式的表示范围。尝试使用exr格式捕获深度或者调整相机的近/远裁剪平面Near/Far Clip Plane。深度值通常被归一化到[0, 1]区间全白可能意味着所有深度都是1即远裁剪平面。问题4物体掩码Object Mask图中某些物体没有颜色或颜色不对。根本原因物体的材质没有设置“Custom Depth”或“Stencil Value”。在UE4中要渲染到Custom Depth/Stencil缓冲区必须在材质的“材质域”Material Domain中选择“表面”Surface并勾选“在自定义深度中渲染”Render in Custom Depth或设置“自定义深度模板值”Custom Stencil Value。解决方案打开物体的材质实例。找到“常规材质设置”General Material Settings。确保“材质域”为“表面”。勾选“在自定义深度中渲染”或在“高级”Advanced下找到相关设置。如果需要不同的ID设置“自定义深度模板值”。 更高效的方法是使用UnrealCV提供的“Object Painter”工具或蓝图批量分配ID。问题5生成速度太慢帧率很低。优化1降低渲染分辨率。这是最直接有效的方法。优化2在UE4中设置低画质预设。创建或切换到一个将所有后期处理、阴影、纹理质量都调低的“可扩展性”Scalability等级。优化3关闭实时全局光照。如果场景使用动态光照将其改为烘焙Baked光照可以极大提升静态场景的渲染速度。优化4避免在循环中频繁获取不必要的信息。比如如果不是每帧都需要物体列表就不要每帧都调用vget /objects。6.3 流程与自动化问题问题6长时间运行后UE4编辑器崩溃或无响应。内存泄漏UE4编辑器长时间运行大型场景可能存在内存累积。定期如每生成5000帧保存项目并重启编辑器是一个笨拙但有效的办法。显卡驱动问题确保使用为创作或游戏优化的最新稳定版显卡驱动。脚本死循环确保你的Python脚本有良好的异常处理和超时机制避免因某个命令卡死而导致脚本无限等待。问题7生成的数据集与后续训练框架不兼容。提前规划格式在开始生成前就确定好目标训练框架PyTorch, TensorFlow, MMDetection等需要的数据格式如COCO, VOC, Cityscapes。在数据后处理脚本中一次性转换到位避免重复劳动。统一文件命名采用清晰、一致的命名规则如{scene}_{seq:04d}_{frame:06d}_{type}.{ext}便于管理和索引。保存完整的元数据除了图像和标注务必保存生成时所用的所有参数相机参数、光照参数、物体随机化种子等。这在复现实验或调试模型时至关重要。最后一个最重要的心得从小规模测试开始。不要一开始就设定生成10万张图。先用一个简单的场景生成50-100张检查RGB、深度、掩码图像是否正确标注是否对齐数据格式是否无误。确认整个管道畅通后再逐步增加数据量、引入更复杂的场景和随机化策略。这个“试点”阶段能帮你提前发现并解决90%的基础问题避免在长时间批量运行后才发现数据不可用那将是灾难性的时间浪费。