平铺相机渲染#
备注
此功能仅在Isaac Sim 4.2.0及以上版本可用。
平铺渲染结合图像处理网络需要大量内存资源,尤其是在更大的分辨率下。我们建议在RTX 4090 GPUs或类似设备上在场景中运行512台摄像机。
平铺渲染API提供了一个矢量化接口,用于从摄像头传感器收集数据。这对需要视觉环节的强化学习环境非常有用。平铺渲染通过连接多个摄像头的相机输出并呈现为单个大图像,而不是由每个单独摄像头生成的多个较小图像。这减少了呈现所需的时间,并为处理视觉数据提供了更高效的API。
Isaac Lab 提供了用于 RGB、深度以及其他注释器的分块渲染 API,通过 TiledCamera
类。分块渲染 API 的配置可以通过 TiledCameraCfg
类来定义,指定诸如所有相机路径的正则表达式、相机的变换、所需的数据类型、要添加到场景中的相机类型以及相机分辨率等参数。
tiled_camera: TiledCameraCfg = TiledCameraCfg(
prim_path="/World/envs/env_.*/Camera",
offset=TiledCameraCfg.OffsetCfg(pos=(-7.0, 0.0, 3.0), rot=(0.9945, 0.0, 0.1045, 0.0), convention="world"),
data_types=["rgb"],
spawn=sim_utils.PinholeCameraCfg(
focal_length=24.0, focus_distance=400.0, horizontal_aperture=20.955, clipping_range=(0.1, 20.0)
),
width=80,
height=80,
)
要访问平铺渲染接口,可以创建一个 TiledCamera
对象,并用于从摄像头获取数据。
tiled_camera = TiledCamera(cfg.tiled_camera)
data_type = "rgb"
data = tiled_camera.data.output[data_type]
返回的数据将转换为形状(num_cameras,height,width,num_channels),可以直接用作强化学习的观察数据。
在处理渲染时,请确保在启动环境时添加 --enable_cameras
参数。例如:
python source/standalone/workflows/rl_games/train.py --task=Isaac-Cartpole-RGB-Camera-Direct-v0 --headless --enable_cameras
注释器和数据类型#
TiledCamera
和 Camera
类提供了从复制器中检索各种类型注释器数据的 API:
"rgb"
: 一个由 3 通道渲染的彩色图像。"rgba"
: 一个由4个通道渲染的带有 Alpha 通道的彩色图像。"distance_to_camera"
: 包含到相机光学中心的距离的图像。"distance_to_image_plane"
: 包含 3D 点从相机平面沿相机Z轴的距离的图像。"depth"
: 和"distance_to_image_plane"
相同。"normals"
: 包含每个像素处的局部表面法线向量的图像。"motion_vectors"
: 包含每个像素的运动矢量数据的图像。"semantic_segmentation"
: 语义分割数据。"instance_segmentation_fast"
: 实例分割数据。"instance_id_segmentation_fast"
: 实例 ID 分割数据。
RGB 和 RGBA#
rgb
数据类型返回一个类型为 torch.uint8
的3通道RGB彩色图像,尺寸为(B,H,W,3)。
rgba
数据类型返回一个类型为 torch.uint8
的4通道RGBA彩色图像,尺寸为(B,H,W,4)。
要将 torch.uint8
数据转换为 torch.float32
,请将缓冲区除以255.0,以获得包含数据0到1的 torch.float32
缓冲区。
深度和距离#
distance_to_camera
返回一个单通道深度图像,显示到相机光学中心的距离。这个注释器的尺寸为(B,H,W,1),类型为 torch.float32
。
distance_to_image_plane
返回一个单通道深度图像,显示3D点从相机平面沿着相机的Z轴的距离。这个注释器的尺寸为(B,H,W,1),类型为 torch.float32
。
depth
提供了 distance_to_image_plane
的别名,并且会返回与 distance_to_image_plane
注释器相同的数据,尺寸为(B,H,W,1),类型为 torch.float32
。
法线#
normals
返回一个包含每个像素处的局部表面法线向量的图像。缓冲区的尺寸为(B,H,W,3),包含每个矢量的(x,y,z)信息,类型为 torch.float32
。
运动矢量#
motion_vectors
返回图像空间中每个像素的像素运动矢量,用包含相对于帧之间相机视口中像素的相对运动的运动矢量的二维数组表示。缓冲区的尺寸为(B,H,W,2),表示x-水平轴(图像宽度)上的运动距离,左侧图像的移动为正,右侧移动为负,y-垂直轴(图像高度)上的运动距离,图像顶部移动为正,向底部移动为负。数据类型为 torch.float32
。
语义分割#
semantic_segmentation
输出相机视口中具有语义标签的每个实体的语义分割。除了图像缓冲区外,还可以使用 tiled_camera.data.info['semantic_segmentation']
检索到包含ID到标签信息的 info
字典。
如果相机配置中
colorize_semantic_segmentation=True
,则会返回一个4通道RGBA图像,尺寸为(B,H,W,4),类型为torch.uint8
。信息idToLabels
字典将表示从颜色到语义标签的映射。如果
colorize_semantic_segmentation=False
,则会返回一个尺寸为(B,H,W,1)的类型为torch.int32
的缓冲区,其中包含每个像素的语义ID。信息idToLabels
字典将表示从语义ID到语义标签的映射。
实例ID分割#
instance_id_segmentation_fast
输出相机视口中每个实体的实例ID分割。每个prim在场景中具有不同路径的实例ID是唯一的。除了图像缓冲区外,还可以使用 tiled_camera.data.info['instance_id_segmentation_fast']
检索到包含ID到标签信息的 info
字典。
instance_id_segmentation_fast
和 instance_segmentation_fast
之间的主要区别在于实例分割注释器会向下移动到具有语义标签的最低级别prim,而实例ID分割总会向下移动到叶prim。
如果相机配置中
colorize_instance_id_segmentation=True
,则会返回一个4通道RGBA图像,尺寸为(B,H,W,4),类型为torch.uint8
。信息idToLabels
字典将表示从颜色到该实体的USD prim路径的映射。如果
colorize_instance_id_segmentation=False
,则会返回一个尺寸为(B,H,W,1)的类型为torch.int32
的缓冲区,其中包含每个像素的实例ID。信息idToLabels
字典将表示从实例ID到该实体的USD prim路径的映射。
实例分割#
instance_segmentation_fast
输出相机视口中每个实体的实例分割。与图像缓冲区一起,还可以检索到包含ID到标签和ID到语义信息的 info
字典。
如果相机配置中
colorize_instance_segmentation=True
,则会返回一个4通道RGBA图像,尺寸为(B,H,W,4),类型为torch.uint8
。信息idToLabels
字典表示从颜色到该语义实体的USD prim路径的映射。信息idToSemantics
字典表示从颜色到该语义实体的语义标签的映射。如果
colorize_instance_segmentation=False
,则会返回一个尺寸为(B,H,W,1)的类型为torch.int32
的缓冲区,其中包含每个像素的实例ID。信息idToLabels
字典表示从实例ID到该语义实体的USD prim路径的映射。信息idToSemantics
字典表示从实例ID到该语义实体的语义标签的映射。
当前限制#
由于当前渲染器的限制,我们在场景中只能有 一个 TiledCamera
实例。对于需要多个相机的用例,我们可以通过在渲染调用之间移动相机的位置来模仿多相机行为。
例如,在立体视觉设置中,可以实现以下代码片段:
# render image from "first" camera
camera_data_1 = self._tiled_camera.data.output["rgb"].clone() / 255.0
# update camera transform to the "second" camera location
self._tiled_camera.set_world_poses(
positions=pos,
orientations=rot,
convention="world"
)
# step the renderer
self.sim.render()
self._tiled_camera.update(0, force_recompute=True)
# render image from "second" camera
camera_data_2 = self._tiled_camera.data.output["rgb"].clone() / 255.0
请注意,这种方法仍然限制了所有相机的渲染分辨率必须相同。目前,使用 TiledCamera
实现不同分辨率图像没有解决方法。最佳方法是使用所有期望分辨率中最大的分辨率,并在渲染输出中添加额外的缩放或裁剪操作作为后处理步骤。
此外,在比较不同数量环境的渲染输出时,可能会有明显的质量差异。目前,任何组合分辨率的宽度小于 265 像素或高度小于 265 像素的情况下,将自动切换到 DLAA 抗锯齿模式,该模式在抗锯齿过程中不会进行上采样。对于宽度和高度均大于 265 像素的分辨率,我们默认使用 “性能” DLSS 模式进行抗锯齿,以获得性能上的好处。抗锯齿模式和其他渲染参数可以在 RenderCfg
中指定。