improve 480p support and opencv print log

This commit is contained in:
ykcheungab
2026-03-11 10:40:04 +08:00
parent 9d6753f186
commit aa781a7a2a
2 changed files with 54 additions and 33 deletions
+1 -1
View File
@@ -11,7 +11,7 @@
}, },
"stitcher": { "stitcher": {
"min_area_frac": 0.01, "min_area_frac": 0.01,
"max_area_frac": 0.04, "max_area_frac": 0.06,
"max_aspect_ratio": 100, "max_aspect_ratio": 100,
"index": [1,2,3,6,7,8,11,12,13], "index": [1,2,3,6,7,8,11,12,13],
"margin": 4, "margin": 4,
+53 -32
View File
@@ -472,54 +472,75 @@ class Sensor:
def _open_video_source(self, override, box): def _open_video_source(self, override, box):
"""Initialize video capture and calibration.""" """Initialize video capture and calibration."""
_is_camera_index = isinstance(self.vid_src, int) # _is_camera_index = isinstance(self.vid_src, int)
_is_v4l2_path = isinstance(self.vid_src, str) and self.vid_src.startswith("/dev/video") # _is_v4l2_path = isinstance(self.vid_src, str) and self.vid_src.startswith("/dev/video")
use_linux_camera_pyav = ( # use_linux_camera_pyav = (
platform.system() == "Linux" # platform.system() == "Linux"
and (_is_camera_index or _is_v4l2_path) # and (_is_camera_index or _is_v4l2_path)
and av is not None # and av is not None
) # )
if use_linux_camera_pyav: # if use_linux_camera_pyav:
device = self.vid_src if _is_v4l2_path else f"/dev/video{self.vid_src}" # device = self.vid_src if _is_v4l2_path else f"/dev/video{self.vid_src}"
if self.verbose: # if self.verbose:
print(f"Using PyAV Linux camera backend: {device}") # print(f"Using PyAV Linux camera backend: {device}")
try: # try:
self._av_container = av.open( # self._av_container = av.open(
device, # device,
format="v4l2", # format="v4l2",
options={ # options={
"input_format": "mjpeg", # "input_format": "mjpeg",
"video_size": f"{self._config_resolution_raw[0]}x{self._config_resolution_raw[1]}", # "video_size": f"{self._config_resolution_raw[0]}x{self._config_resolution_raw[1]}",
"framerate": str(self._config_fps), # "framerate": str(self._config_fps),
}, # },
) # )
self._av_stream = self._av_container.streams.video[0] # self._av_stream = self._av_container.streams.video[0]
self._av_decoder = self._av_container.decode(self._av_stream) # self._av_decoder = self._av_container.decode(self._av_stream)
self._use_pyav = True # self._use_pyav = True
except Exception as exc: # except Exception as exc:
if self.verbose: # if self.verbose:
print(f"PyAV camera open failed ({exc}), fallback to OpenCV backend.") # print(f"PyAV camera open failed ({exc}), fallback to OpenCV backend.")
self._use_pyav = False # self._use_pyav = False
self.use_pyav = False
if not self._use_pyav: if not self._use_pyav:
self.cap = cv2.VideoCapture(self.vid_src) self.cap = cv2.VideoCapture(self.vid_src)
# Set buffer size to 1 to reduce latency and avoid frame accumulation # Set buffer size to 1 to reduce latency and avoid frame accumulation
# Note: Not all backends support this, but it helps when available # Note: Not all backends support this, but it helps when available
try: # try:
self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
except Exception: # except Exception:
pass # Some backends don't support this property # pass # Some backends don't support this property
self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('M', 'J', 'P', 'G')) self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('M', 'J', 'P', 'G'))
self.cap.set(cv2.CAP_PROP_FPS, self._config_fps) self.cap.set(cv2.CAP_PROP_FPS, self._config_fps)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, self._config_resolution_raw[0]) self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, self._config_resolution_raw[0])
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self._config_resolution_raw[1]) self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self._config_resolution_raw[1])
if self.verbose: if self.verbose:
print("Connecting to video source...") print("Connecting to video source...")
if not self._is_source_open(): if not self._is_source_open():
raise Exception("Failed to open video source.") raise Exception("Failed to open video source.")
if self.verbose and not self._use_pyav and self.cap is not None:
fourcc_int = int(self.cap.get(cv2.CAP_PROP_FOURCC))
fourcc_bytes = [(fourcc_int >> (8 * i)) & 0xFF for i in range(4)]
# Show printable FOURCC only; some backends return 0 or non-printable bytes.
if fourcc_int <= 0:
fourcc = "N/A"
else:
fourcc = "".join(chr(b) if 32 <= b <= 126 else "." for b in fourcc_bytes)
width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = self.cap.get(cv2.CAP_PROP_FPS)
backend_id = int(self.cap.get(cv2.CAP_PROP_BACKEND))
print(
f"OpenCV negotiated stream: FOURCC='{fourcc}' "
f"(int={fourcc_int}, hex=0x{fourcc_int:08X}), "
f"size={width}x{height}, fps={fps:.2f}, backend_id={backend_id}"
)
# Wait for first valid frame # Wait for first valid frame
frame = None frame = None