From 1e8a535195d5d3ae01a9e319f8b5af81b05347ef Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 24 Oct 2022 16:14:19 -0400 Subject: [PATCH] Detect gray frames from OBS-Camera --- src/AutoSplit.py | 1 + .../VideoCaptureDeviceCaptureMethod.py | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/AutoSplit.py b/src/AutoSplit.py index 74baef30..ef8ffa52 100644 --- a/src/AutoSplit.py +++ b/src/AutoSplit.py @@ -408,6 +408,7 @@ def __check_fps(self): while count < CHECK_FPS_ITERATIONS: capture, is_old_image = self.__get_capture_for_comparison() _ = image.compare_with_capture(self, capture) + # TODO: If is_old_image=true is always returned, this becomes an infinite loop if not is_old_image: count += 1 diff --git a/src/capture_method/VideoCaptureDeviceCaptureMethod.py b/src/capture_method/VideoCaptureDeviceCaptureMethod.py index 2fd68e16..f15fe082 100644 --- a/src/capture_method/VideoCaptureDeviceCaptureMethod.py +++ b/src/capture_method/VideoCaptureDeviceCaptureMethod.py @@ -13,6 +13,19 @@ if TYPE_CHECKING: from AutoSplit import AutoSplit +OBS_CAMERA_BLANK = [127, 129, 128] + + +def is_blank(image: cv2.Mat): + # Running np.all on the entire array is extremely slow. + # Because it always converts the entire array to boolean first + # So instead we loop manually to stop early. + for row in image: + for pixel in row: + if all(pixel != OBS_CAMERA_BLANK): + return False + return True + class VideoCaptureDeviceCaptureMethod(CaptureMethodBase): capture_device: cv2.VideoCapture @@ -36,7 +49,14 @@ def __read_loop(self, autosplit: AutoSplit): # STS_ERROR most likely means the camera is occupied result = False image = None - self.last_captured_frame = image if result else None + if not result: + image = None + + # Blank frame. Reuse the previous one. + if image is not None and is_blank(image): + continue + + self.last_captured_frame = image self.is_old_image = False except Exception as exception: # pylint: disable=broad-except # We really want to catch everything here error = exception