LeRobot documentation
카메라
카메라
LeRobot은 비디오 캡처를 위한 여러 옵션을 제공합니다:
| 클래스 | 지원되는 카메라 |
|---|---|
OpenCVCamera | 휴대전화, 내장형 노트북, USB 웹캠 |
ZMQCamera | 네트워크 연결 카메라 |
RealSenseCamera | Intel RealSense (깊이 포함) |
Reachy2Camera | Reachy 2 로봇 카메라 |
OpenCVCamera호환성 세부 사항은 OpenCV를 사용한 비디오 I/O 개요를 참조하세요.
카메라 찾기
각 카메라는 인스턴스화될 때 고유한 식별자를 필요로 하며, 이를 통해 여러 연결된 장치를 구별할 수 있습니다.
OpenCVCamera와 RealSenseCamera는 자동 감지를 지원합니다. 아래 명령을 실행하면 사용 가능한 장치와 해당 식별자를 나열합니다. 운영체제에 따라 컴퓨터 재부팅 또는 카메라 재연결 후 식별자가 변경될 수 있습니다.
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 카메라를 사용하는 것은 불안정할 수 있습니다.
ZMQCamera와 Reachy2Camera는 자동 감지를 지원하지 않습니다. 네트워크 주소와 포트 또는 로봇 SDK 설정을 제공하여 수동으로 구성해야 합니다.
카메라 배치 및 조명
카메라 이미지는 정책이 학습하는 대상이므로, 높은 해상도보다 좋은 카메라 세팅이 더 중요합니다:
- 장면을 고르게 조명합니다. 확산되고 일관된 조명을 사용하고 직사광선, 강한 반사, 움직이는 그림자는 피합니다. 녹화 시점과 배포 시점의 조명이 다르면 정책이 실패할 수 있습니다.
- 카메라를 고정합니다. 단단하게 설치하고, 녹화 세션 사이 또는 녹화와 배포 사이에 위치를 변경하지 마세요.
- 작업을 정의합니다. 대상, 그립퍼, 목표 지점은 최소 하나의 카메라에 보여야 합니다. 좋은 테스트 방법: 카메라 이미지만 보고 본인이 해당 작업을 수행할 수 있는가?
- 해상도를 적절하게 유지하세요. 대부분의 작업에는 640×480, 30 fps면 충분하며, 이를 통해 녹화와 학습 속도를 빠르게 유지할 수 있습니다.
카메라 사용
프레임 액세스 모드
모든 카메라 클래스는 프레임 캡처를 위한 세 가지 액세스 모드를 구현합니다:
| 메서드 | 동작 | 블록? | 가장 적합한 용도 |
|---|---|---|---|
read() | 카메라 하드웨어가 프레임을 반환할 때까지 대기합니다. 카메라 및 SDK에 따라 장시간 블로킹될 수 있습니다. | 예 | 간단한 스크립트, 순차 캡처 |
async_read(timeout_ms) | 배경 스레드에서 아직 소비되지 않은 최신 프레임을 반환합니다. 버퍼가 비어 있는 경우에만 timeout_ms까지 블로킹됩니다. 프레임이 도착하지 않으면 TimeoutError를 발생시킵니다. | 타임아웃과 함께 | 카메라 FPS에 동기화된 제어 루프 |
read_latest(max_age_ms) | 버퍼의 가장 최근 프레임을 확인합니다(오래된 값일 수 있음). 프레임의 나이가 max_age_ms보다 크면 TimeoutError를 발생시킵니다. | 아니요 | UI 시각화, 로깅, 모니터링 |
사용 예시
다음 예제는 카메라 API를 사용하여 다양한 유형의 카메라를 구성하고 프레임을 캡처하는 방법을 보여줍니다.
- OpenCV 기반 카메라를 사용한 블로킹 및 논블로킹 프레임 캡처
- Intel RealSense 카메라를 사용한 색상 및 깊이 캡처
카메라를 깔끔하게 연결 해제하지 않으면 리소스 누수가 발생할 수 있습니다. 자동 클리업을 보장하기 위해 컨텍스트 매니저 프로토콜을 사용하세요:
with OpenCVCamera(config) as camera: ...
connect()와disconnect()를 수동으로 호출할 수도 있지만, 후자는 항상finally블록을 사용해야 합니다.
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}")
from lerobot.cameras.realsense import RealSenseCamera, RealSenseCameraConfig
from lerobot.cameras import ColorMode, Cv2Rotation
# Create a `RealSenseCameraConfig` specifying your camera’s serial number and enabling depth.
config = RealSenseCameraConfig(
serial_number_or_name="233522074606",
fps=15,
width=640,
height=480,
color_mode=ColorMode.RGB,
use_depth=True,
# Optional fixed color controls. Omit them to leave the current sensor settings unchanged.
exposure=120,
gain=64,
white_balance=4600,
rotation=Cv2Rotation.NO_ROTATION
)
# Instantiate and connect a `RealSenseCamera` with warm-up read (default).
camera = RealSenseCamera(config)
camera.connect()
# Capture a color frame via `read()` and a depth map via `read_depth()`.
try:
color_frame = camera.read()
depth_map = camera.read_depth()
print("Color frame shape:", color_frame.shape)
print("Depth map shape:", depth_map.shape)
finally:
camera.disconnect()수동 색상 제어는 해당 자동 노출 또는 화이트 밸런스 모드를 비활성화합니다. 지원 범위는 카메라 모델에 따라 다르며, 잘못된 값을 사용하면 센서가 보고한 범위가 포함된 오류가 연결 시점에 발생합니다. 지원되지 않는 제어를 요청하는 경우에도 오류가 발생합니다. 생략된 제어는 센서의 기존 자동 또는 수동 설정을 변경하지 않습니다. 이 옵션들은 use_rgb=True가 필요합니다.
수동 색상 제어에는 전용 RGB 모듈이 필요합니다. RealSense D405와 같이 해당 모듈이 없는 카메라는 이를 지원하지 않으며, 연결 시 오류가 발생합니다.
깊이(depth) 작업
Intel RealSense 및 Reachy 2 카메라는 색도와 심도를 동기화하여 캡처할 수 있습니다. read()를 호출하면 색도 프레임을 (H, W, 3) uint8 형식으로 반환합니다. read_depth()를 호출하면 심도 맵을 (H, W, 1) uint16 형식으로 반환하며, 각 픽셀 값은 센서로부터의 거리를 밀리미터 단위로 나타냅니다. 픽셀 값이 0인 경우 일반적으로 “측정 값 없음”(범위 초과, 가림, 또는 낮은 신뢰도)을 의미합니다.
녹화 중 제어 루프는 read_latest()(색상)과 read_latest_depth()(깊이)를 통해 최신 버퍼 프레임에 비차단 방식으로 접근하며, 깊이 맵을 형제 기능으로 추가합니다(예: front 옆에 front_depth).
데이터셋을 기록할 때 깊이 스트림이 저장되고 인코딩되는 방식에 대해서는 비디오 인코딩 가이드의 Depth streams 섹션을 참조하세요.
Use your phone’s camera
macOS에서 iPhone을 카메라로 사용하려면 Continuity Camera 기능을 활성화하세요:
- Mac이 macOS 13 이상, iPhone이 iOS 16 이상을 실행 중인지 확인하세요.
- 같은 Apple ID로 두 기기에 모두 로그인하세요.
- USB 케이블로 장치를 연결하거나, 무선 연결을 위해 Wi-Fi와 Bluetooth를 켜세요.
자세한 내용은 Apple support를 방문하세요.
OBS를 사용하여 휴대폰을 카메라로 사용하려면 다음 단계를 따라 가상 카메라를 설정하세요.
- (Linux 전용)
v4l2loopback-dkms와v4l-utils를 설치합니다. 이 패키지들은 가상 카메라 장치를 생성하고 설정을 확인합니다. 다음 명령으로 설치합니다:
sudo apt install v4l2loopback-dkms v4l-utils휴대폰에 DroidCam 앱을 설치합니다. 이 앱은 iOS와 Android 모두에서 사용할 수 있습니다.
OBS Studio를 다운로드하여 설치합니다.
DroidCam OBS 플러그인을 다운로드하여 설치하세요.
OBS Studio를 시작합니다.
전화를 소스로 추가합니다. 여기의 지침을 따르세요. 워터마크를 피하려면 해상도를
640x480으로 설정해야 합니다.해상도 설정 조정. OBS Studio에서
File > Settings > Video또는OBS > Preferences... > Video로 이동합니다.Base(Canvas) Resolution과Output(Scaled) Resolution을640x480으로 수동 입력하여 변경합니다.가상 카메라 시작. OBS Studio에서 여기의 지침을 따르세요.
가상 카메라 설정과 해상도를 확인합니다.
- Linux: 사용
v4l2-ctl하여 장치를 나열하고 해상도를 확인합니다:다음과 같이v4l2-ctl --list-devices # find VirtualCam and note its /dev/videoX path v4l2-ctl -d /dev/videoX --get-fmt-video # replace with your VirtualCam pathVirtualCam이 나열되고 해상도가640x480. - macOS: Photo Booth 또는 FaceTime를 열고 입력으로 “OBS Virtual Camera”를 선택합니다.
- Windows: 네이티브 Camera 앱은 가상 카메라를 지원하지 않습니다. 화상회의 앱(Zoom, Teams)을 사용하거나
lerobot-find-cameras opencv를 직접 실행하여 확인하세요.
- Linux: 사용
Troubleshooting
가상 카메라 해상도가 올바르지 않습니다.
가상 카메라 소스를 삭제한 후 다시 생성합니다. 생성 후에는 해상도를 변경할 수 없습니다.
Error reading frame in background thread for OpenCVCamera(X): OpenCVCamera(X) frame width=640 or height=480 do not match configured width=1920 or height=1080.
이 오류는 리스케일링에도 불구하고 OBS Virtual Camera가 1920x1080 해상도를 보고하기 때문에 발생합니다. 현재 유일한 해결 방법은 _postprocess_image()의 너비와 높이 검사를 주석 처리하는 것입니다.
모든 설정이 올바르게 완료되면 휴대폰이 표준 OpenCV 카메라로 표시되며 OpenCVCamera와 함께 사용할 수 있습니다.