refactor(cameras): add warm-up, fix defaul args, remove width and height from find_cameras utils

This commit is contained in:
Steven Palma
2025-05-12 18:04:26 +02:00
parent c9cc544f7e
commit 7224807171
5 changed files with 14 additions and 14 deletions

View File

@@ -33,7 +33,7 @@ class Cv2Rotation(Enum):
ROTATE_270 = -90
@dataclass
@dataclass(kw_only=True)
class CameraConfig(draccus.ChoiceRegistry, abc.ABC):
fps: int | None = None
width: int | None = None

View File

@@ -336,6 +336,10 @@ class RealSenseCamera(Camera):
logger.debug(f"Validating stream configuration for {self.serial_number}...")
self._validate_capture_settings()
logger.debug(f"Reading a warm-up frame for {self.serial_number}...")
self.read() # NOTE(Steven): For now we just read one frame, we could also loop for X secs
logger.info(f"Camera {self.serial_number} connected and configured successfully.")
def _validate_fps(self, stream) -> None:
@@ -396,7 +400,7 @@ class RealSenseCamera(Camera):
def read(
self, color_mode: ColorMode | None = None, timeout_ms: int = 5000
) -> Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]:
) -> np.ndarray | Tuple[np.ndarray, np.ndarray]:
"""
Reads a single frame (color and optionally depth) synchronously from the camera.

View File

@@ -205,6 +205,10 @@ class OpenCVCamera(Camera):
logger.debug(f"Successfully opened camera {self.index_or_path}. Applying configuration...")
self._configure_capture_settings()
logger.debug(f"Reading a warm-up frame for {self.serial_number}...")
self.read() # NOTE(Steven): For now we just read one frame, we could also loop for X secs\
logger.debug(f"Camera {self.index_or_path} connected and configured successfully.")
def _validate_fps(self) -> None:

View File

@@ -1,4 +1,4 @@
from dataclasses import dataclass, field
from dataclasses import dataclass
from pathlib import Path
from ..configs import CameraConfig, ColorMode, Cv2Rotation
@@ -18,9 +18,7 @@ class OpenCVCameraConfig(CameraConfig):
```
"""
index_or_path: int | Path = field(
default=...,
)
index_or_path: int | Path
color_mode: ColorMode = ColorMode.RGB
channels: int = 3 # NOTE(Steven): Why is this a config?
rotation: Cv2Rotation = Cv2Rotation.NO_ROTATION

View File

@@ -157,28 +157,21 @@ def create_camera_instance(cam_meta: Dict[str, Any]) -> Optional[Dict[str, Any]]
"""Create and connect to a camera instance based on metadata."""
cam_type = cam_meta.get("type")
cam_id = cam_meta.get("id")
default_profile = cam_meta.get("default_stream_profile")
width = default_profile.get("width")
height = default_profile.get("height")
instance = None
logger.info(f"Preparing {cam_type} ID {cam_id} with profile: Width={width}, Height={height}")
logger.info(f"Preparing {cam_type} ID {cam_id} with default profile")
try:
if cam_type == "OpenCV":
cv_config = OpenCVCameraConfig(
index_or_path=cam_id,
color_mode=ColorMode.RGB,
width=width,
height=height,
)
instance = OpenCVCamera(cv_config)
elif cam_type == "RealSense":
rs_config = RealSenseCameraConfig(
serial_number=str(cam_id),
color_mode=ColorMode.RGB,
width=width,
height=height,
)
instance = RealSenseCamera(rs_config)
else:
@@ -270,6 +263,7 @@ def save_images_from_all_cameras(
logger.info(f"Starting image capture for {record_time_s} seconds from {len(cameras_to_use)} cameras.")
start_time = time.perf_counter()
# NOTE(Steven): This seems like an overkill to me
with concurrent.futures.ThreadPoolExecutor(max_workers=len(cameras_to_use) * 2) as executor:
try:
while time.perf_counter() - start_time < record_time_s: