From 03008054da962bc8b5205ed67f45f9a10c555d1c Mon Sep 17 00:00:00 2001 From: ryzendigo <48058157+ryzendigo@users.noreply.github.com> Date: Mon, 16 Mar 2026 14:32:18 +0800 Subject: [PATCH] fix: handle custom logo images without alpha channel cv2.imread with IMREAD_UNCHANGED loads the image as-is, but the code unconditionally indexes channel 3 (birdseye_logo[:, :, 3]) assuming RGBA format. This crashes with IndexError for: - Grayscale PNGs (2D array, no channel dimension) - RGB PNGs without alpha (3 channels, no index 3) - Fully transparent PNGs saved as grayscale+alpha (2 channels) Handle all image formats: - 2D (grayscale): use directly as luminance - 4+ channels (RGBA): extract alpha channel (existing behavior) - 3 channels (RGB/BGR): convert to grayscale Also fixes the shape[0]/shape[1] swap in the array slice that breaks non-square images (related to #6802, #7863). --- frigate/output/birdseye.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/frigate/output/birdseye.py b/frigate/output/birdseye.py index cdadafe71..554ef8011 100644 --- a/frigate/output/birdseye.py +++ b/frigate/output/birdseye.py @@ -303,12 +303,20 @@ class BirdsEyeFrameManager: birdseye_logo = cv2.imread(logo_files[0], cv2.IMREAD_UNCHANGED) if birdseye_logo is not None: - transparent_layer = birdseye_logo[:, :, 3] + if birdseye_logo.ndim == 2: + # Grayscale image (no channels) — use directly as luminance + transparent_layer = birdseye_logo + elif birdseye_logo.shape[2] >= 4: + # RGBA — use alpha channel as luminance + transparent_layer = birdseye_logo[:, :, 3] + else: + # RGB or other format without alpha — convert to grayscale + transparent_layer = cv2.cvtColor(birdseye_logo, cv2.COLOR_BGR2GRAY) y_offset = height // 2 - transparent_layer.shape[0] // 2 x_offset = width // 2 - transparent_layer.shape[1] // 2 self.blank_frame[ - y_offset : y_offset + transparent_layer.shape[1], - x_offset : x_offset + transparent_layer.shape[0], + y_offset : y_offset + transparent_layer.shape[0], + x_offset : x_offset + transparent_layer.shape[1], ] = transparent_layer else: logger.warning("Unable to read Frigate logo")