Isaac Sim知识小解(5):Camera

相机是 Isaac Sim 中的一种 Prim 类型,可以通过详细的 API 可以看到 Isaac Sim 的 API 文档 ↗︎,在这里介绍所需的必要 API。

Camera (omni.isaac.sensor.Camera) ← 上层封装,提供 Python API

│

└── Render Product (Replicator) ← 渲染媒介,负责实际的渲染管线

│

└── GPU 渲染输出 ← 最终图像数据(RGB、Depth、Segmentation 等)

Isaac Sim 的 Camera 类并不是直接渲染的,它依赖 Render Product 来完成实际的 GPU 渲染工作。你可以把 Render Product 理解为一个 渲染任务/渲染目标 ------告诉 PhysX/RTX 渲染器:"请以这个分辨率、这个视角,把画面渲染出来"。

1. 创建相机

在使用 Camera 的接口创建新的 Camera 的时候,一般会直接创建一个新的 render product,并指定给相机

正常流程(有 bug):

创建 Camera → 自动创建 Render Product → 删除 Camera

→ ❌ Render Product 没被清理干净!

→ 再在相同路径创建新 Camera

→ ❌ 新 Camera 绑定到残留的旧 Render Product

→ ❌ 渲染结果异常,很多 step 拿不到数据

workaround 流程(推荐):

手动创建 Render Product → 手动创建 Camera 并绑定已有的 Render Product → 干净可控

复制代码
from omni.isaac.sensor import Camera
import omni.replicator.core as rep

rp = rep.create.render_product(rep.create.camera(), (1280, 720))
camera = Camera(
    prim_path="/World/camera",
    name="camera",
    frequency=1/60,
    resolution=(1280, 720),
    render_product_path=rp.path, # 指定使用上面创建好的 render product
)

时序要求:

world = World()

reset 之前创建相机

camera = Camera(...)

world.reset() # reset 会初始化物理场景、渲染管线等

现在 camera 可以正常使用了

for _ in range(100):

world.step()

rgb_data = camera.get_rgb() # 获取 RGB 图像

depth_data = camera.get_depth() # 获取深度图

... 其他中间表征

2. 渲染 RGB 图片

saac Sim 想要进行更新,主要包括三种不同的形式,即step(), render(), world.step(render=False) ,其中step() 是同时进行物理和渲染引擎的更新,render() 是进行渲染的更新,world.step(render=False) 是进行物理引擎的更新。

方式 物理引擎 渲染引擎 底层实现
world.step() ✅ 更新 ✅ 更新 omni的闭源 update 函数 (有 bug)
world.step(render=False) ✅ 更新 ❌ 不更新 正常的 PhysX stepping
world.render() ❌ 不更新 ✅ 更新 正常的 RTX 渲染

step() 和step(render=False)的差异:

场景:机械臂 Articulation 的 stiffness / damping 参数设置不合理

step() (闭源)

→ 内部可能有额外的"稳定化/阻尼"逻辑

→ 掩盖了参数不合理导致的问题

→ 看起来"正常",但其实是假象 ❌

world.step(render=False)

→ 纯物理,没有任何额外干预

→ 超调 = 真实的物理现象 ✅

→ 反映了 stiffness/damping 设置确实有问题

推荐方式:使用 step(render=False) 来更新物理引擎,并使用 render() 来更新渲染引擎

问题:为什么不使用world.step(render=True)来同时更新物理引擎和渲染引擎

world.step(render=True)可能出现:物理求解器和渲染管线之间的某些隐式同步;step(render=False) + render() 是"自由搭配"。 后者让你能以不同频率运行物理和渲染、能单独调试、能确保物理真实性不被渲染管线间接影响

一个简单的函数可以帮助你获得相机的图像:

复制代码
def get_rgb(camera: Camera) -> np.ndarray | None:
    frame = camera.get_rgba()
    if isinstance(frame, np.ndarray) and frame.size > 0:
        frame = frame[:, :, :3]
        return frame
    else:
        return None

只需要将 Camera 作为参数传入,即可获得 RGB 图片。

同时Camera 支持使用 set_world_pose() 以及 set_local_pose() 来设置相机的世界坐标以及局部坐标,你可以使用这些 API 来设置相机的位置和姿态。

3. 更多参数

相机当然同时支持更多的参数,甚至包括设置鱼眼相机等

复制代码
def setup_camera(
    camera: Camera,
    focal_length: float = 4.5,
    clipping_range_min: float = 0.01,
    clipping_range_max: float = 10000.0,
    vertical_aperture: float = 5.625,
    horizontal_aperture: float = 10.0,
    with_distance: bool = True,
    with_semantic: bool = False,
    with_bbox2d: bool = False,
    with_bbox3d: bool = False,
    with_motion_vector: bool = False,
) -> None:
    camera.initialize()
    camera.set_focal_length(focal_length)
    camera.set_clipping_range(clipping_range_min, clipping_range_max)
    camera.set_vertical_aperture(vertical_aperture)
    camera.set_horizontal_aperture(horizontal_aperture)
    if with_distance:
        camera.add_distance_to_image_plane_to_frame()
    if with_semantic:
        camera.add_semantic_segmentation_to_frame()
    if with_bbox2d:
        camera.add_bounding_box_2d_tight_to_frame()
        camera.add_bounding_box_2d_loose_to_frame()
    if with_bbox3d:
        camera.add_bounding_box_3d_to_frame()
    if with_motion_vector:
        camera.add_motion_vectors_to_frame()

可以设置相机的焦距,剪裁范围,光圈,以及是否添加额外的表征,比如说深度图,语义,2D 和 3D 框,以及运动向量。

其中裁剪范围也就是如 RGB 图,当裁剪范围过小,相机会在物体距离较近的时候看到物体的切面图,基本上此参数调整到大的很大,小的约 0.001 即可。

4. 与现实相机对齐

Isaac Sim 的相机自然也可以和现实中的相机进行对齐,此时外参通过 set_world_pose() 来设置,内参则通过下述代码来设置:

复制代码
def set_camera_rational_polynomial(
    camera: Camera,
    fx: float,
    fy: float,
    cx: float,
    cy: float,
    width: int,
    height: int,
    pixel_size: float = 3,
    f_stop: float = 2.0,
    focus_distance: float = 0.3,
    D: np.ndarray | None = None,
) -> Camera:
    if D is None:
        D = np.zeros(8)
    camera.initialize()
    camera.set_resolution([width, height])
    camera.set_clipping_range(0.02, 5)
    horizontal_aperture = pixel_size * 1e-3 * width
    vertical_aperture = pixel_size * 1e-3 * height
    focal_length_x = fx * pixel_size * 1e-3
    focal_length_y = fy * pixel_size * 1e-3
    focal_length = (focal_length_x + focal_length_y) / 2
    camera.set_focal_length(focal_length / 10.0)
    camera.set_focus_distance(focus_distance)
    camera.set_lens_aperture(f_stop * 100.0)
    camera.set_horizontal_aperture(horizontal_aperture / 10.0)
    camera.set_vertical_aperture(vertical_aperture / 10.0)
    camera.set_clipping_range(0.05, 1.0e5)
    diagonal = 2 * math.sqrt(max(cx, width - cx) ** 2 + max(cy, height - cy) ** 2)
    diagonal_fov = 2 * math.atan2(diagonal, fx + fy) * 180 / math.pi
    camera.set_projection_type("fisheyePolynomial")
    camera.set_rational_polynomial_properties(width, height, cx, cy, diagonal_fov, D)
    return camera
相关推荐
QYR-分析2 小时前
20.58 亿→41.41 亿美元,CAGR 10.5%|机器人机器视觉:柔性自动化的感知核心正在迭代
机器人·自动化·智能电视
RockChinQ3 小时前
没有服务器,也能在 QQ 群里养一只大肥鱼
人工智能·机器人·开源
硅谷秋水4 小时前
Agentic World Action Models(AW-0)贡献与不足分析
人工智能·机器学习·计算机视觉·语言模型·机器人
搞科研的小刘选手5 小时前
【IEEE出版,快至会后3-4个月检索 | 北方民族大学主办 | 中国·银川(线上+线下)】2026年机器人、智能计算与自动化学术会议(RAIC 2026)
机器人·自动化·学术会议·智能计算·会议推荐·北方民族大学·银川
集萃智造机器人5 小时前
协作机器人选型要看哪些参数?负载、臂展与重复定位精度的取舍逻辑
机器人
xwz小王子6 小时前
一根光纤上的“触觉触手“:Nature Communications 光纤触觉 微操作 机器人
人工智能·机器人
2601_952047796 小时前
金蝶云星空销售订单附件查询接口权威教程(BOS_Attachment)
python·机器人·钉钉
由你创机器人7 小时前
具身智能全栈机器人定制:从需求甄别到落地避坑全指南
机器人
龍德明宇7 小时前
机器人的礼貌是标注出来的-龍德明宇
人工智能·机器人·大语言模型llm·负主体性·ai存在论
飞猫的边缘AI8 小时前
机器人基础模型的两种赌注:VLA与VFA
人工智能·机器人·vla·ai模型·边缘ai·视觉语言动作模型·vfa