カメラ入力解像度のデフォルトをフルHDに変更
動画圧縮機能の追加
This commit is contained in:
1 parent
ca10876101
commit
6d6b6a0ede
4 files changed
+27
-4
No files matched your search
+3
-2
@@ -14,12 +14,13 @@ input:
|
|||||||
type: camera
|
type: camera
|
||||||
camera_id: 0
|
camera_id: 0
|
||||||
video_path: null
|
video_path: null
|
||||||
width: 1280
|
width: 1920
|
||||||
height: 720
|
height: 1080
|
||||||
fps: 30
|
fps: 30
|
||||||
backend: auto
|
backend: auto
|
||||||
horizontal_flip: false
|
horizontal_flip: false
|
||||||
max_consecutive_read_failures: 5
|
max_consecutive_read_failures: 5
|
||||||
|
fourcc: MJPG # camera pixel format; "" = driver default. MJPG is needed for 1080p@30 on many webcams
|
||||||
detector:
|
detector:
|
||||||
model_path: yolo11n.pt
|
model_path: yolo11n.pt
|
||||||
device: auto
|
device: auto
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ experiment:
|
|||||||
input:
|
input:
|
||||||
type: camera
|
type: camera
|
||||||
camera_id: 0
|
camera_id: 0
|
||||||
width: 1280
|
width: 1920
|
||||||
height: 720
|
height: 1080
|
||||||
fps: 30
|
fps: 30
|
||||||
backend: auto
|
backend: auto
|
||||||
horizontal_flip: false
|
horizontal_flip: false
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"""OpenCV camera and video input abstraction."""
|
"""OpenCV camera and video input abstraction."""
|
||||||
|
|
||||||
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
@@ -8,6 +9,8 @@ import numpy as np
|
|||||||
from .config_loader import InputSettings
|
from .config_loader import InputSettings
|
||||||
from .exceptions import CameraOpenError, FrameReadError
|
from .exceptions import CameraOpenError, FrameReadError
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Camera:
|
class Camera:
|
||||||
"""Read frames from a camera device or video file."""
|
"""Read frames from a camera device or video file."""
|
||||||
@@ -32,9 +35,24 @@ class Camera:
|
|||||||
self.release()
|
self.release()
|
||||||
raise CameraOpenError(f"Could not open {self.config.type} input: {source}")
|
raise CameraOpenError(f"Could not open {self.config.type} input: {source}")
|
||||||
if self.config.type == "camera":
|
if self.config.type == "camera":
|
||||||
|
# The pixel format must be set before the resolution: many webcams only offer
|
||||||
|
# Full HD at a usable frame rate in MJPG, and fall back to a lower mode otherwise.
|
||||||
|
if self.config.fourcc:
|
||||||
|
self._capture.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*self.config.fourcc))
|
||||||
self._capture.set(cv2.CAP_PROP_FRAME_WIDTH, self.config.width)
|
self._capture.set(cv2.CAP_PROP_FRAME_WIDTH, self.config.width)
|
||||||
self._capture.set(cv2.CAP_PROP_FRAME_HEIGHT, self.config.height)
|
self._capture.set(cv2.CAP_PROP_FRAME_HEIGHT, self.config.height)
|
||||||
self._capture.set(cv2.CAP_PROP_FPS, self.config.fps)
|
self._capture.set(cv2.CAP_PROP_FPS, self.config.fps)
|
||||||
|
actual_w, actual_h = self.get_actual_width(), self.get_actual_height()
|
||||||
|
logger.info(
|
||||||
|
"Camera opened: requested %dx%d@%.1f fourcc=%s, actual %dx%d@%.1f",
|
||||||
|
self.config.width, self.config.height, self.config.fps, self.config.fourcc or "default",
|
||||||
|
actual_w, actual_h, self.get_actual_fps(),
|
||||||
|
)
|
||||||
|
if (actual_w, actual_h) != (self.config.width, self.config.height):
|
||||||
|
logger.warning(
|
||||||
|
"Camera resolution differs from the request: requested %dx%d, got %dx%d",
|
||||||
|
self.config.width, self.config.height, actual_w, actual_h,
|
||||||
|
)
|
||||||
|
|
||||||
def read(self) -> np.ndarray | None:
|
def read(self) -> np.ndarray | None:
|
||||||
if self._capture is None or not self._capture.isOpened():
|
if self._capture is None or not self._capture.isOpened():
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ class InputSettings:
|
|||||||
backend: str
|
backend: str
|
||||||
horizontal_flip: bool
|
horizontal_flip: bool
|
||||||
max_consecutive_read_failures: int
|
max_consecutive_read_failures: int
|
||||||
|
# Four-character camera pixel format (e.g. "MJPG"); empty string leaves the driver default.
|
||||||
|
fourcc: str = ""
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True, slots=True)
|
@dataclass(frozen=True, slots=True)
|
||||||
@@ -539,6 +541,8 @@ def _validate(config: AppConfig) -> None:
|
|||||||
raise ConfigurationError("input dimensions, fps, and read failure limit must be positive")
|
raise ConfigurationError("input dimensions, fps, and read failure limit must be positive")
|
||||||
if i.backend not in {"auto", "dshow", "msmf", "v4l2"}:
|
if i.backend not in {"auto", "dshow", "msmf", "v4l2"}:
|
||||||
raise ConfigurationError("input.backend must be auto, dshow, msmf, or v4l2")
|
raise ConfigurationError("input.backend must be auto, dshow, msmf, or v4l2")
|
||||||
|
if not isinstance(i.fourcc, str) or (i.fourcc and len(i.fourcc) != 4):
|
||||||
|
raise ConfigurationError("input.fourcc must be empty or exactly 4 characters (e.g. MJPG)")
|
||||||
if not 0.0 <= d.confidence_threshold <= 1.0 or not 0.0 <= d.iou_threshold <= 1.0:
|
if not 0.0 <= d.confidence_threshold <= 1.0 or not 0.0 <= d.iou_threshold <= 1.0:
|
||||||
raise ConfigurationError("detector confidence and IoU thresholds must be in [0, 1]")
|
raise ConfigurationError("detector confidence and IoU thresholds must be in [0, 1]")
|
||||||
if d.image_size <= 0 or d.max_detections <= 0 or d.person_class_id < 0:
|
if d.image_size <= 0 or d.max_detections <= 0 or d.person_class_id < 0:
|
||||||
|
|||||||
Reference in new issue
Block a user