共计 3524 个字符,预计需要花费 9 分钟才能阅读完成。
背景与痛点
自动驾驶技术的快速发展离不开大量高质量的标注数据。然而,真实世界的数据采集面临诸多挑战:

- 成本高昂:需要专业车辆、传感器设备和人力标注,成本动辄数百万。
- 场景覆盖有限:难以收集极端天气、危险场景等长尾数据。
- 标注效率低:人工标注一帧 3D 点云可能需要 30 分钟,而自动驾驶模型训练通常需要数十万帧数据。
CARLA 仿真平台提供了完美的解决方案:
- 场景可控:可自由切换天气、时间、交通状况,甚至模拟传感器故障。
- 标注零成本:所有物体的 3D 位置、语义标签等信息自动生成。
- 无限复用:同一场景可反复采集不同视角、传感器的数据。
CARLA 环境配置
基础环境
- 硬件建议:至少 4 核 CPU、16GB 内存、NVIDIA 显卡(支持 CUDA)
- 下载 CARLA:从官网获取对应版本的预编译包(如 0.9.13)
wget https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/CARLA_0.9.13.tar.gz
tar -xzvf CARLA_0.9.13.tar.gz
传感器配置
CARLA 支持多种传感器组合,典型配置示例:
- 主摄像头:1920×1080 RGB,FOV 90°,安装在前挡风玻璃位置
- 激光雷达:32 线,10Hz,范围 100 米(模拟 Velodyne HDL-32E)
- 语义分割相机:与主摄像头同位置,输出像素级类别标签
通过 Python API 配置传感器的核心参数:
blueprint_library = world.get_blueprint_library()
# 创建 RGB 相机
camera_bp = blueprint_library.find('sensor.camera.rgb')
camera_bp.set_attribute('image_size_x', '1920')
camera_bp.set_attribute('image_size_y', '1080')
camera_bp.set_attribute('fov', '90')
# 创建激光雷达
lidar_bp = blueprint_library.find('sensor.lidar.ray_cast')
lidar_bp.set_attribute('channels', '32')
lidar_bp.set_attribute('range', '100')
lidar_bp.set_attribute('points_per_second', '560000')
数据采集实战
同步采集流程
- 初始化 CARLA 客户端和世界对象
- 设置天气、光照等环境参数
- 生成车辆和传感器
- 注册传感器数据回调函数
- 开始连续采集并保存数据
完整示例代码:
import carla
import random
import os
import numpy as np
# 初始化客户端
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
world = client.get_world()
# 创建保存目录
output_dir = 'carla_data'
os.makedirs(output_dir, exist_ok=True)
# 设置天气
weather = carla.WeatherParameters(cloudiness=random.uniform(0, 50),
precipitation=0,
sun_altitude_angle=70)
world.set_weather(weather)
# 生成车辆
vehicle_bp = random.choice(world.get_blueprint_library().filter('vehicle.*'))
spawn_point = random.choice(world.get_map().get_spawn_points())
vehicle = world.spawn_actor(vehicle_bp, spawn_point)
# 传感器回调函数
def sensor_callback(data, sensor_type):
if sensor_type == 'rgb':
data.save_to_disk(f'{output_dir}/{data.frame}.png')
elif sensor_type == 'lidar':
points = np.frombuffer(data.raw_data, dtype=np.float32)
points = np.reshape(points, (-1, 4))
np.save(f'{output_dir}/{data.frame}_lidar.npy', points)
# 创建并安装传感器
camera = world.spawn_actor(camera_bp, ...)
camera.listen(lambda data: sensor_callback(data, 'rgb'))
lidar = world.spawn_actor(lidar_bp, ...)
lidar.listen(lambda data: sensor_callback(data, 'lidar'))
# 主循环
try:
while True:
world.tick()
finally:
# 清理资源
camera.destroy()
lidar.destroy()
vehicle.destroy()
关键点说明:
world.tick()确保所有传感器数据同步到同一时间戳- 帧号(frame)作为唯一标识,保证多传感器数据对齐
- 原始数据建议保存为无损格式(如 PNG、NPY)
自动化标注
CARLA 原生标注类型
- 语义分割:每个像素包含物体类别(道路、车辆、行人等)
- 深度图:精确的深度信息(单位:米)
- 3D 边界框:物体的精确位置、尺寸和朝向
- 实例分割:区分同类物体的不同实例
格式转换示例(CARLA→KITTI)
KITTI 格式要求每帧包含:
- 图像文件(000001.png)
- 点云文件(000001.bin)
- 标注文件(000001.txt)
转换代码片段:
def convert_to_kitti(carla_bboxes, frame_id):
"""将 CARLA 3D 框转为 KITTI 格式"""
with open(f'{output_dir}/{frame_id:06d}.txt', 'w') as f:
for bbox in carla_bboxes:
# 计算 KITTI 格式的旋转角
rotation_y = -bbox.rotation.yaw * np.pi / 180
# 写入: 类型 截断 遮挡 alpha 2D 框 3D 尺寸 3D 位置 旋转
line = f"Car 0 0 0 0 0 0 0" \
f"{bbox.extent.x*2} {bbox.extent.y*2} {bbox.extent.z*2}" \
f"{bbox.location.x} {bbox.location.y} {bbox.location.z}" \
f"{rotation_y}\n"
f.write(line)
避坑指南
数据同步问题
现象:不同传感器的时间戳不完全对齐
解决方案:
- 使用
world.tick()而非time.sleep()控制帧率 - 检查传感器配置中的
sensor_tick参数(秒 / 帧) - 后处理时根据帧号匹配数据
传感器噪声模拟
CARLA 默认提供理想传感器数据,可通过以下方式增加真实感:
-
摄像头:添加运动模糊、镜头畸变
camera_bp.set_attribute('motion_blur_intensity', '0.5') camera_bp.set_attribute('lens_circle_multiplier', '3.0') -
激光雷达:模拟雨雾衰减
lidar_bp.set_attribute('dropoff_general_rate', '0.45') lidar_bp.set_attribute('atmosphere_attenuation_rate', '0.004')
性能优化
大规模采集技巧
- 并行采集:
- 使用多个 CARLA 服务实例(不同端口)
-
每个实例运行独立的 Python 客户端
-
数据压缩:
- 将点云存储为二进制格式(而非 ASCII)
-
对图像使用 PNG 而非 JPEG(避免压缩伪影)
-
内存管理:
- 定期清理不再需要的 Actor 对象
- 避免在回调函数中进行复杂计算
结语
通过 CARLA 仿真平台,我们能够以极低成本构建高质量的自动驾驶训练数据集。建议读者尝试:
- 设计特定场景(如夜间暴雨)的数据采集方案
- 比较仿真数据训练模型与真实数据模型的性能差异
- 探索域适应技术,缩小仿真与现实的差距
仿真数据不会完全替代真实数据,但两者结合将大幅加速自动驾驶系统的开发迭代。期待看到更多创新性的数据生成方案在 CARLA 上实现!
正文完
