Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions dimos/hardware/test_webcam.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,17 @@ def test_basic():
def test_module():
dimos = start(1)
# Deploy ColorCameraModule, not Webcam directly
camera_module = dimos.deploy(ColorCameraModule)
camera_module = dimos.deploy(
ColorCameraModule,
hardware=lambda: Webcam(camera_index=4, frequency=30, stereo_slice="left"),
)
camera_module.image.transport = LCMTransport("/image", Image)
camera_module.start()

test_transport = LCMTransport("/image", Image)
test_transport.subscribe(print)

time.sleep(2)
time.sleep(60)

print("shutting down")
camera_module.stop()
Expand Down
12 changes: 11 additions & 1 deletion dimos/hardware/webcam.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from abc import ABC, abstractmethod, abstractproperty
from dataclasses import dataclass, field
from functools import cache
from typing import Any, Callable, Generic, Optional, Protocol, TypeVar
from typing import Any, Callable, Generic, Optional, Protocol, TypeVar, Literal

import cv2
import numpy as np
Expand Down Expand Up @@ -62,6 +62,7 @@ class WebcamConfig(CameraConfig):
frequency: int = 10
camera_info: CameraInfo = field(default_factory=CameraInfo)
frame_id_prefix: Optional[str] = None
stereo_slice: Optional[Literal["left", "right"]] = None # For stereo cameras


class Webcam(ColorCameraHardware[WebcamConfig]):
Expand Down Expand Up @@ -155,6 +156,15 @@ def capture_frame(self) -> Image:
frame_id=self._frame("camera"), # Standard frame ID for camera images
ts=time.time(), # Current timestamp
)

if self.config.stereo_slice in ("left", "right"):
image.frame_id = self._frame(f"camera_stereo_{self.config.stereo_slice}")
half_width = image.width // 2
if self.config.stereo_slice == "left":
image = image.crop(0, 0, half_width, image.height)
else:
image = image.crop(half_width, 0, half_width, image.height)

return image

def _capture_loop(self):
Expand Down
Loading