From ec8eb7aebfa4f7c82d03b354891a0cd4cda64d0e Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Apr 2026 16:17:22 +0000 Subject: [PATCH 1/2] 4-seasons: protect night frames from grey filter with brightness floor A stddev-only filter would wrongly drop near-black night frames. Now only skips a frame when BOTH stddev < GREY_MIN AND mean brightness > GREY_DARK_FLOOR (default 30/255). Night frames are dark so they always pass; bad-signal grey frames are mid-bright so they are caught. https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ --- 4-seasons.sh | 11 ++++++++--- sky-cam.conf | 16 ++++++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/4-seasons.sh b/4-seasons.sh index e4c9a6f..484ac2f 100755 --- a/4-seasons.sh +++ b/4-seasons.sh @@ -92,6 +92,7 @@ mapfile -t all_images < <(find "$image_dir" -type f -name "*.jpg" | sort) # SEASONS_GREY_STDDEV_MIN=0 (default) disables the grey filter. # Set to e.g. 5 in sky-cam.conf to drop uniform grey frames (bad-signal captures). GREY_MIN="${SEASONS_GREY_STDDEV_MIN:-0}" +GREY_DARK_FLOOR="${SEASONS_GREY_DARK_FLOOR:-30}" # frames darker than this are never skipped images=(); bad=0; grey=0 for img in "${all_images[@]}"; do # Empty or unreadable @@ -106,10 +107,14 @@ for img in "${all_images[@]}"; do echo "WARNING: skipping corrupt frame: $(basename "$img")" ((bad++)) || true; continue fi - # Optional: skip uniform-grey bad-signal frames (low pixel standard deviation) + # Optional: skip uniform-grey bad-signal frames. + # A frame is bad-signal if it is BOTH uniform (low stddev) AND not dark. + # Night frames are dark so they pass even with low stddev. if [ "$GREY_MIN" != "0" ] && command -v convert &>/dev/null; then - stddev=$(convert "$img" -colorspace Gray -format "%[fx:int(standard_deviation*255)]" info: 2>/dev/null || echo "255") - if [ "${stddev:-255}" -lt "$GREY_MIN" ]; then + read -r stddev mean < <(convert "$img" -colorspace Gray \ + -format "%[fx:int(standard_deviation*255)] %[fx:int(mean*255)]" \ + info: 2>/dev/null || echo "255 128") + if [ "${stddev:-255}" -lt "$GREY_MIN" ] && [ "${mean:-0}" -gt "$GREY_DARK_FLOOR" ]; then ((grey++)) || true; continue fi fi diff --git a/sky-cam.conf b/sky-cam.conf index 04d3b2c..ffe38d6 100644 --- a/sky-cam.conf +++ b/sky-cam.conf @@ -257,13 +257,21 @@ AUDIO_BITRATE=192k # montage-mvt.sh — music track on movement # ── Frame validation (4-seasons.sh) ────────────────────────────────────────── # Corrupt or empty frames (e.g. first frame after a camera reconnect) are always -# skipped automatically via ffprobe. +# skipped automatically via ffprobe. No config needed. # # SEASONS_GREY_STDDEV_MIN: also skip uniform-grey frames caused by a bad RTSP -# signal. These are valid JPEGs but contain a near-solid grey image. -# Value is the minimum pixel standard deviation on a 0–255 scale. -# 0 = disabled (default). Try 5–10 if your camera produces grey frames on reconnect. +# signal (valid JPEGs, but near-solid grey — no real image content). +# A frame is only skipped when BOTH conditions hold: +# 1. pixel standard deviation (0–255) is below SEASONS_GREY_STDDEV_MIN +# 2. mean brightness (0–255) is above SEASONS_GREY_DARK_FLOOR +# This keeps genuine night frames (dark + low stddev) while dropping +# bad-signal grey frames (mid-bright + low stddev). +# +# SEASONS_GREY_STDDEV_MIN=0 disables the filter entirely (default). +# Try 5–10 if your camera produces solid-grey frames on reconnect. +# Requires ImageMagick (convert) to be installed. SEASONS_GREY_STDDEV_MIN=0 +SEASONS_GREY_DARK_FLOOR=30 # frames with mean brightness below this are always kept # ── Montage attribution overlay ─────────────────────────────────────────────── # A translucent bar across the top of each movement montage, naming the From 9d34240ac075790d4c17f9242b0795bf9e4305e4 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Apr 2026 16:22:25 +0000 Subject: [PATCH 2/2] =?UTF-8?q?sky-cam.conf:=20comment=20out=20grey=20filt?= =?UTF-8?q?er=20=E2=80=94=20must=20be=20explicitly=20enabled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SEASONS_GREY_STDDEV_MIN and SEASONS_GREY_DARK_FLOOR settings are now commented out so the filter is fully inert by default and requires a deliberate edit to activate. https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ --- sky-cam.conf | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/sky-cam.conf b/sky-cam.conf index ffe38d6..ed9d92b 100644 --- a/sky-cam.conf +++ b/sky-cam.conf @@ -259,19 +259,15 @@ AUDIO_BITRATE=192k # montage-mvt.sh — music track on movement # Corrupt or empty frames (e.g. first frame after a camera reconnect) are always # skipped automatically via ffprobe. No config needed. # -# SEASONS_GREY_STDDEV_MIN: also skip uniform-grey frames caused by a bad RTSP -# signal (valid JPEGs, but near-solid grey — no real image content). -# A frame is only skipped when BOTH conditions hold: -# 1. pixel standard deviation (0–255) is below SEASONS_GREY_STDDEV_MIN -# 2. mean brightness (0–255) is above SEASONS_GREY_DARK_FLOOR -# This keeps genuine night frames (dark + low stddev) while dropping -# bad-signal grey frames (mid-bright + low stddev). -# -# SEASONS_GREY_STDDEV_MIN=0 disables the filter entirely (default). -# Try 5–10 if your camera produces solid-grey frames on reconnect. -# Requires ImageMagick (convert) to be installed. -SEASONS_GREY_STDDEV_MIN=0 -SEASONS_GREY_DARK_FLOOR=30 # frames with mean brightness below this are always kept +# SEASONS_GREY_STDDEV_MIN / SEASONS_GREY_DARK_FLOOR — optional bad-signal filter. +# Uncomment both lines to enable. A frame is dropped only when BOTH are true: +# 1. pixel standard deviation (0–255) < SEASONS_GREY_STDDEV_MIN (frame is uniform) +# 2. mean brightness (0–255) > SEASONS_GREY_DARK_FLOOR (frame is not dark) +# This keeps genuine night frames (dark + low variation) while dropping +# solid-grey bad-signal frames (mid-bright + no variation). +# Requires ImageMagick (convert). Start with these values and tune from there: +#SEASONS_GREY_STDDEV_MIN=5 # skip if stdev < 5 (very uniform) +#SEASONS_GREY_DARK_FLOOR=30 # …but only if mean brightness > 30 (not a night frame) # ── Montage attribution overlay ─────────────────────────────────────────────── # A translucent bar across the top of each movement montage, naming the