NVIDIA Omniverse合成数据管道——IMS/DMS训练数据的规模化生成方案

技术背景

DMS/OMS 模型训练面临的核心瓶颈是数据采集成本。Euro NCAP 2026 要求 1200+ 测试场景,真实场景覆盖不到 60%。NVIDIA Omniverse + Cosmos + Replicator 提供了完整的合成数据管道。

NVIDIA 合成数据生态

核心组件

1. Omniverse Replicator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# Omniverse Replicator 合成数据生成示例
# 需要: Omniverse Kit SDK (仅限NVIDIA平台运行)

import omni.replicator.core as rep

class DMSDataGenerator:
"""
DMS合成数据生成器

使用Omniverse Replicator API
运行环境: Omniverse Kit SDK (需要RTX GPU)
"""

def __init__(self, output_dir: str = "/data/dms_synthetic"):
self.output_dir = output_dir
# 标注类型
self.annotators = [
"rgb", # RGB图像
"distance", # 深度图
"bounding_box", # 2D包围盒
"semantic_segmentation", # 语义分割
"instance_segmentation", # 实例分割
"key_points", # 面部关键点
"occlusion", # 遮挡信息
]

def generate_dms_scenarios(
self,
num_scenes: int = 10000,
num_persons: int = 1,
cabin_model: str = "vehicle_cabin.usd"
) -> dict:
"""
生成DMS训练数据

Args:
num_scenes: 场景数量
num_persons: 人数(1=仅驾驶员, 2=驾驶员+乘客)
cabin_model: 座舱USD模型路径

Returns:
stats: 生成统计
"""
# 加载座舱环境
cabin = rep.create.from_usd(cabin_model)

# 生成参数空间
for i in range(num_scenes):
with rep.randomize.instantiate(cabin):
# 驾驶员参数随机化
driver = rep.create.person(
name=f"driver_{i}",
# Metahuman 参数
age=rep.random.uniform(18, 75),
gender=rep.random.choice(["male", "female"]),
height=rep.random.uniform(150, 195), # cm
weight=rep.random.uniform(45, 120), # kg
)

# 姿态随机化
with driver:
rep.modify.pose(
position=rep.random.uniform(
low=(-0.3, -0.5, -0.2),
high=(0.3, 0.5, 0.2)
),
rotation=rep.random.uniform(
low=(-15, -15, -15),
high=(15, 15, 15)
)
)

# 疲劳姿态模拟
if rep.random.choice([True, False], weights=[0.3, 0.7]):
# 30% 概率模拟疲劳
rep.modify.joint(
"neck",
rotation=(rep.random.uniform(10, 30), 0, 0) # 前倾
)
rep.modify.joint(
"eyelid_left",
openness=rep.random.uniform(0.2, 0.6) # 半闭
)

# 光照条件
rep.lighting.set_hdri_environment(
env_map=rep.random.choice([
"daylight.hdr",
"sunset.hdr",
"night.hdr",
"tunnel.hdr"
])
)

# 摄像头参数
camera = rep.create.camera(
focal_length=6.0,
f_stop=2.8,
position=(0.2, -0.8, 0.5), # 方向盘柱位置
look_at=(0, 0, 0.3) # 看向驾驶员
)

# 渲染并保存
rep.orchestrator.run(
num_frames=num_scenes,
output_dir=self.output_dir,
annotators=self.annotators
)

return {
'scenes_generated': num_scenes,
'output_dir': self.output_dir,
'annotations': self.annotators
}

2. Euro NCAP 场景覆盖

NCAP场景 合成生成方案 参数随机化 样本量
D-01 驾驶员看手机 ✅ Metahuman手持手机 位置/角度/光照 2000
D-02 手机至耳边 ✅ 手部动画 手机型号/手位置 1500
D-05 视线偏离>3s ✅ 凝视动画 目标位置/时长 2000
F-01 PERCLOS≥30% ✅ 眼睑半闭 闭眼程度/时长 1500
F-04 微睡眠1.5s ✅ 完全闭眼 时长/恢复速度 1000
CPD-01 婴儿留车 ✅ 婴儿Metahuman 毛毯覆盖/位置 1000
OOP-01 前倾 ✅ 躯干前弯 角度/距离 800
OOP-03 脚搭台 ✅ 腿部姿态 角度/位置 500

3. Anyverse InCabin 对比

维度 NVIDIA Omniverse Anyverse InCabin 真实采集
NCAP场景覆盖 ✅ 全部 ✅ 全部 ⚠️ 部分
物理一致性 ✅ 高 ✅ 高 ✅ 真实
渲染速度 ~100fps (RTX) ~50fps —
人物多样性 Metahuman无限 预设角色 招募成本
光照变化 ✅ HDR环境 ✅ 基于真实 ✅ 自然
传感器模拟 摄像头/雷达/LiDAR 摄像头为主 真实传感器
标注成本 自动 自动 人工$5/张
授权成本 Omniverse免费 商业授权 —

4. 合成数据有效性验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import numpy as np

class SyntheticDataValidator:
"""
合成数据有效性验证器

确保合成数据能提升真实场景的模型性能
"""

def __init__(self, model, test_loader_real):
self.model = model
self.test_real = test_loader_real

def evaluate_domain_gap(
self,
synthetic_loader,
real_loader
) -> dict:
"""
评估合成-真实域差距

Args:
synthetic_loader: 合成数据
real_loader: 真实数据

Returns:
metrics: 域差距分析
"""
# 在真实数据上评估
real_acc = self._evaluate(self.test_real)

# 在合成数据上训练后在真实数据上评估
# (模拟实验,实际需要完整训练)
synthetic_trained_acc = real_acc + 0.05 # 示例提升

# 域差距指标
synthetic_acc = self._evaluate(synthetic_loader)
domain_gap = real_acc - synthetic_acc

return {
'real_only_accuracy': real_acc,
'synthetic_accuracy': synthetic_acc,
'domain_gap': domain_gap,
'synthetic_boost': synthetic_trained_acc - real_acc,
'recommendation': 'use_mix' if domain_gap < 0.15 else 'needs_adaptation'
}

def _evaluate(self, loader):
"""评估模型精度"""
# 简化
return 0.92

DMS合成数据管道代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import numpy as np
import json
from pathlib import Path

class DMSSyntheticPipeline:
"""
DMS合成数据生成与验证完整管道

Pipeline:
1. 场景定义 (NCAP场景模板)
2. 参数随机化 (Domain Randomization)
3. 渲染生成 (Omniverse Replicator)
4. 自动标注 (语义/关键点/包围盒)
5. 数据增强 (混合真实数据)
6. 模型训练与验证
"""

# NCAP场景模板
SCENE_TEMPLATES = {
'D-01_phone_use': {
'description': '驾驶员手持手机',
'fatigue': False,
'distraction': True,
'required_objects': ['phone'],
'gaze_target': 'phone_screen',
'ncap_category': 'distraction'
},
'F-01_perclos': {
'description': 'PERCLOS ≥ 30%',
'fatigue': True,
'distraction': False,
'eye_openness': (0.0, 0.3), # 闭眼30-100%
'duration_sec': 5,
'ncap_category': 'fatigue'
},
'CPD-01_child_alone': {
'description': '婴儿独自留在车内',
'fatigue': False,
'person_type': 'infant',
'covered': True, # 毛毯覆盖
'ncap_category': 'cpd'
},
'OOP-01_forward_lean': {
'description': '驾驶员前倾(捡东西)',
'posture': 'forward_lean',
'lean_angle': (20, 45), # 度
'ncap_category': 'oop'
}
}

def generate_dataset(
self,
output_path: str,
total_samples: int = 50000,
scene_distribution: dict = None
) -> dict:
"""
生成完整合成数据集

Args:
output_path: 输出路径
total_samples: 总样本数
scene_distribution: 场景分布(比例)

Returns:
manifest: 数据集清单
"""
if scene_distribution is None:
scene_distribution = {
'D-01_phone_use': 0.15,
'D-05_gaze_away': 0.15,
'F-01_perclos': 0.10,
'F-04_microsleep': 0.10,
'CPD-01_child_alone': 0.15,
'OOP-01_forward_lean': 0.10,
'normal_driving': 0.25,
}

manifest = {
'total_samples': total_samples,
'scenes': {},
'statistics': {}
}

for scene_name, ratio in scene_distribution.items():
n_samples = int(total_samples * ratio)
manifest['scenes'][scene_name] = {
'count': n_samples,
'template': self.SCENE_TEMPLATES.get(scene_name, {}),
'output_dir': f"{output_path}/{scene_name}/"
}

# 生成标注统计
manifest['statistics'] = {
'annotators': [
'rgb', 'depth', 'semantic_seg', 'bbox_2d',
'bbox_3d', 'keypoints_2d', 'keypoints_3d',
'occlusion_mask', 'gaze_direction'
],
'image_resolution': '1920x1080',
'frame_rate': 30,
'diversity': {
'persons': 500, # Metahuman variations
'lighting': 20, # HDR environments
'vehicles': 10, # Cabin models
'cameras': 5, # Camera positions
}
}

# 保存清单
Path(output_path).mkdir(parents=True, exist_ok=True)
with open(f"{output_path}/manifest.json", 'w') as f:
json.dump(manifest, f, indent=2)

return manifest


# 生成数据集清单
if __name__ == "__main__":
pipeline = DMSSyntheticPipeline()
manifest = pipeline.generate_dataset(
output_path="/data/dms_synthetic_v2",
total_samples=50000
)

print(f"总样本: {manifest['total_samples']}")
print("场景分布:")
for scene, info in manifest['scenes'].items():
print(f" {scene}: {info['count']} 张")

与Anyverse的竞争分析

维度 NVIDIA方案 Anyverse方案
技术路线 物理仿真渲染 混合渲染+真实
场景覆盖 需自建 NCAP全场景预置
人物多样性 Metahuman无限 精选角色库
部署门槛 需Omniverse+RTX SaaS订阅
成本 GPU硬件~$5K 年订阅~$50K
适用团队 有3D能力团队 快速验证

IMS开发启示

  1. 合成数据可覆盖NCAP 100%场景,解决真实数据采集难题
  2. 建议混合策略: 70%合成 + 30%真实,兼顾多样性和真实性
  3. Omniverse适合有3D能力的团队,Anyverse适合快速验证
  4. Metahuman是关键优势,可生成无限多样性的虚拟人
  5. 自动标注降低90%标注成本,从$5/张降到$0.5/张

来源:NVIDIA Omniverse docs, Anyverse, arXiv 2601.03290 | 关键词:synthetic data, Omniverse, Replicator, Metahuman, DMS, Euro NCAP