相机

LeRobot 提供了多种视频采集选项:

支持的相机
OpenCVCamera手机、笔记本电脑内置摄像头、USB 网络摄像头
ZMQCamera联网相机
RealSenseCameraIntel RealSense(带深度)
Reachy2CameraReachy 2 机器人相机

有关 OpenCVCamera 的兼容性详细信息,请参阅 Video I/O with OpenCV Overview

找到你的相机

每台相机在被实例化时都需要一个唯一标识符,使你可以区分多个连接的设备。

OpenCVCameraRealSenseCamera 支持自动发现。运行下面的命令来列出可用的设备及其标识符。请注意,根据你的操作系统,这些标识符在重启计算机或重新插拔相机后可能会改变。

lerobot-find-cameras opencv # or realsense for Intel Realsense cameras

如果你连接了两台相机,输出看起来会像这样:

--- Detected Cameras ---
Camera #0:
  Name: OpenCV Camera @ 0
  Type: OpenCV
  Id: 0
  Backend api: AVFOUNDATION
  Default stream profile:
    Format: 16.0
    Width: 1920
    Height: 1080
    Fps: 15.0
--------------------
(more cameras ...)

macOS 中使用 Intel RealSense 相机时,你可能会遇到这个 错误Error finding RealSense cameras: failed to set power state,可以通过使用 sudo 权限运行同一命令来解决。请注意,在 macOS 中使用 RealSense 相机不稳定。

ZMQCameraReachy2Camera 不支持自动发现。必须通过提供它们的网络地址和端口或机器人 SDK 设置来手动配置。

使用相机

帧访问模式

所有相机类都实现了三种用于采集帧的访问模式:

方法行为会阻塞?最适合
read()等待相机硬件返回一帧。根据相机和 SDK 的不同,可能会长时间阻塞。简单脚本、顺序采集
async_read(timeout_ms)从后台线程返回最新的未消费帧。只有在缓冲区为空时才会阻塞,最多 timeout_ms。如果没有帧到达,则抛出 TimeoutError带超时与相机 FPS 同步的控制循环
read_latest(max_age_ms)窥视缓冲区中最近的帧(可能是过期的)。如果帧早于 max_age_ms,则抛出 TimeoutErrorUI 可视化、日志、监控

用法示例

以下示例展示了如何使用相机 API 配置不同相机类型并采集帧。

  • 阻塞和非阻塞帧采集:使用基于 OpenCV 的相机
  • 彩色和深度采集:使用 Intel RealSense 相机

未能干净地断开相机可能会造成资源泄漏。请使用上下文管理器协议来确保自动清理:

with OpenCVCamera(config) as camera:
    ...

你也可以手动调用 connect()disconnect(),但对于后者,请始终使用 finally 块。

Open CV Camera
Intel Realsense Camera
from lerobot.cameras.opencv import OpenCVCamera, OpenCVCameraConfig
from lerobot.cameras import ColorMode, Cv2Rotation

# Construct an `OpenCVCameraConfig` with your desired FPS, resolution, color mode, and rotation.
config = OpenCVCameraConfig(
    index_or_path=0,
    fps=15,
    width=1920,
    height=1080,
    color_mode=ColorMode.RGB,
    rotation=Cv2Rotation.NO_ROTATION
)

# Instantiate and connect an `OpenCVCamera`, performing a warm-up read (default).
with OpenCVCamera(config) as camera:

    # Read a frame synchronously — blocks until hardware delivers a new frame
    frame = camera.read()
    print(f"read() call returned frame with shape:", frame.shape)

    # Read a frame asynchronously with a timeout — returns the latest unconsumed frame or waits up to timeout_ms for a new one
    try:
        for i in range(10):
            frame = camera.async_read(timeout_ms=200)
            print(f"async_read call returned frame {i} with shape:", frame.shape)
    except TimeoutError as e:
        print(f"No frame received within timeout: {e}")

    # Instantly return a frame - returns the most recent frame captured by the camera
    try:
        initial_frame = camera.read_latest(max_age_ms=1000)
        for i in range(10):
            frame = camera.read_latest(max_age_ms=1000)
            print(f"read_latest call returned frame {i} with shape:", frame.shape)
            print(f"Was a new frame received by the camera? {not (initial_frame == frame).any()}")
    except TimeoutError as e:
        print(f"Frame too old: {e}")

使用深度

Intel RealSense 和 Reachy 2 相机可以在同步 state 下同时采集彩色和深度。调用 read() 返回 彩色 帧,即 (H, W, 3) uint8。调用 read_depth() 返回 深度图,即 (H, W, 1) uint16,其中每个像素值是以 毫米 表示的到传感器的距离。像素值为 0 通常表示“无可用测量”(超出范围、被遮挡或置信度低)。

录制期间,控制循环通过 read_latest()(彩色)和 read_latest_depth()(深度)以非阻塞方式窥视最新的缓冲帧,并将深度图添加为并列特征(例如 front_depth 紧挨着 front)。

关于录制 dataset 时深度流的存储和编码方式,请参阅视频编码指南中的 Depth streams 一节。

使用手机的相机

iPhone & macOS
OBS virtual camera

要在 macOS 上将 iPhone 用作相机,请启用连续互通相机(Continuity Camera)功能:

  • 确保你的 Mac 运行 macOS 13 或更高版本,iPhone 使用 iOS 16 或更高版本。
  • 使用同一个 Apple ID 登录两台设备。
  • 使用 USB 线连接你的设备,或者打开 Wi-Fi 和蓝牙进行无线连接。

更多详细信息,请访问 Apple 支持

如果一切设置正确,你的手机会以标准 OpenCV 相机的形式出现,并可与 OpenCVCamera 一起使用。

在 GitHub 上更新