Commit Graph
60 Commits
Author SHA1 Message Date
Outis ec18c6c71a Delete 22-45-14.jpg 2026-04-19 20:32:44 -04:00
Outis 717dae88e2 Merge pull request #12 from outis1one/claude/seasonal-sunrise-montage-nn268
Claude/seasonal sunrise montage nn268
2026-04-19 20:32:15 -04:00
Claude 9039803a51 Fix undefined CAM_NAME crash; log when window already closed on re-run
4-seasons.sh, fullday-video.sh: CAM_NAME fallback referenced undefined
\$CAM_NAME — under set -euo pipefail this crashes if called manually without
an argument. Changed to fall back to \$SUNRISE_CAM (matches capture.sh).

daily_sunrise_video.sh: add log message when the capture window has already
closed (manual re-run after the fact). Behaviour is unchanged — processing
proceeds immediately — but the operator now gets a clear confirmation rather
than silence.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-20 00:29:47 +00:00
Claude 4814c9e158 Audio capture records exactly SUNRISE_TARGET_SECS centred on sunrise
Previously sunrise-audio-capture.sh recorded the entire capture window
(70+ minutes) and daily_sunrise_video.sh sought to the right position with
a complex offset calculation.

Now: record floor(TARGET/2) seconds before sunrise and ceil(TARGET/2) after —
odd second goes to post-sunrise.  The file is exactly SUNRISE_TARGET_SECS long
and already centred, so no offset is needed when mixing.

AUDIO_PRE_BUFFER_MIN removed — it was part of the old whole-window scheme
and is no longer meaningful.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-20 00:22:35 +00:00
Claude be714affc0 Auto-detect SCRIPT_DIR/BASE_DIR; sunrise waits for capture window; optional overlay
sky-cam.conf:
- SCRIPT_DIR auto-detects from its own location via BASH_SOURCE — no manual
  path entry needed after bootstrap; override still works via environment.
- BASE_DIR defaults to \$SCRIPT_DIR/data; MOVIES_DIR defaults to \$BASE_DIR/movies.
  Override either to point at a drive/mount as before.
- SCHEDULE_SUNRISE changed to 03:00 — the script now waits internally until
  the capture window closes before touching images, so the schedule just needs
  to be early enough, not timed exactly to sunrise.
- Schedule section rewritten to explain what each job does and what day's data
  it processes (SEASONS/FULLDAY always process yesterday).
- SUNRISE_PRE_MIN/POST_MIN comments explain the window and its relationship to
  SUNRISE_TARGET_SECS.
- SUNRISE_OVERLAY_ENABLED=true added; set false to skip the timestamp entirely.

daily_sunrise_video.sh:
- After calculating the capture window, sleep until end_sec+30s if we fired
  before the window finished — guarantees all images are present.
- DT (drawtext filter) is only built when SUNRISE_OVERLAY_ENABLED=true.
- Step 3b skips ffmpeg entirely when overlay is disabled, moving work_video
  directly to final_video (faster, no re-encode).

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-20 00:18:43 +00:00
Outis 543dc0cc9b Merge pull request #11 from outis1one/claude/seasonal-sunrise-montage-nn268
Claude/seasonal sunrise montage nn268
2026-04-19 20:10:17 -04:00
Claude a1cf1304e4 Fix first-run blockers: MOVIES_DIR path, CAM_NAME, .env for Python, eval safety
daily_sunrise_video.sh: use \$MOVIES_DIR instead of \$BASE_DIR/movies so the
override in sky-cam.conf is respected when videos live on a separate drive.

capture.sh: default camera name falls back to \$SUNRISE_CAM (not the
undefined \$CAM_NAME) when no argument is passed.

sunrise2mm.py: also loads .env after sky-cam.conf so Mattermost credentials
moved to .env are actually visible to the upload script.

sunrise.py: raise a clear error message when LATITUDE/LONGITUDE/TIMEZONE
are missing from sky-cam.conf instead of an opaque KeyError.

4-seasons.sh, montage-mvt.sh: capture season_info.py output before eval so
a Python failure exits cleanly with a diagnostic message rather than
silently continuing with undefined variables.

bootstrap.sh: add system package install step (ffmpeg bc fonts-dejavu) and
show the .env setup step after install.sh generates .env.example.

README.md: correct Python package names and add fonts-dejavu dependency.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 23:37:10 +00:00
Claude a1b9ffa8ee Add .env credentials file support; gitignore .env and sunrise-sounds/
sky-cam.conf now sources .env from the same directory at the bottom of the
file, so RTSP URLs, Mattermost tokens, and notification credentials can live
outside version control.  Plaintext credential placeholders removed from conf.

install.sh generates .env.example on every run with the correct CAM_RTSP_*
variable names derived from the CAMERAS list, so users always know exactly
what to put in .env for their specific camera setup.

.gitignore: add .env and sunrise-sounds/ (downloaded audio library).

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 23:08:01 +00:00
Claude ba1eb70436 bootstrap.sh: fix post-install instructions (remove CAM_NAME, add pip step)
CAM_NAME is no longer a config key; replace with CAMERAS + SUNRISE_CAM.
Add pip3 install step for suntime/pytz/requests as step 1.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 22:45:26 +00:00
Claude 66fe1f46ca Fix CAM_NAME bug, set -x noise, wrong Python package in README
daily_sunrise_video.sh: derive CAM_NAME from $1 (defaulting to SUNRISE_CAM)
instead of an undefined variable; this was causing empty image/output paths.

install.sh: pass $SUNRISE_CAM as argument to daily_sunrise_video.sh so it
matches the pattern used by every other per-camera script.

sunrise2mm.py: use SUNRISE_CAM config key (not the undefined CAM_NAME) to
locate the output directory; fixes silent path mismatch on non-default names.

4-seasons.sh: remove stray `set -x` that was flooding systemd logs with
shell trace output.

README.md: correct Python dependencies from `ephem` to `suntime pytz` to
match what sunrise.py actually imports.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 21:56:33 +00:00
Outis d97740aafd Merge pull request #10 from outis1one/claude/seasonal-sunrise-montage-nn268
Claude/seasonal sunrise montage nn268
2026-04-19 17:37:45 -04:00
Claude 16af99f0a3 Split step 3 into independent audio (3a) and overlay (3b) stages
Each stage can now fail independently, giving four upload paths:
audio+overlay, audio-only, overlay-only, or speed-only video.
Step 3a copies the video stream (no re-encode) when mixing audio,
so step 3b failure still leaves a clean audio-mixed file to promote.
Overlay failure notification now reports which quality was uploaded.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 21:34:04 +00:00
Claude 15b7970dfa README: document audio fallback library and download-sunrise-sounds.py usage
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 21:22:23 +00:00
Claude baf886fd23 Audio resilience: three-tier fallback for sunrise audio; add freesound download script
daily_sunrise_video.sh: priority chain is camera mic → library random MP3 →
overlay-only → sped video promotion.  If audio mixing fails a warning
notification fires and the script retries with overlay-only so a video is
always produced and uploaded.

download-sunrise-sounds.py: downloads CC-licensed ambient sounds from
freesound.org into 11 weather/season category folders (~275 files total at
25 per category), writing a manifest.json with attribution data.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 21:22:01 +00:00
Claude 9fe0051f70 Add pure-ffmpeg RTSP capture and camera audio for sunrise videos
Removes dependency on MotionEye or any NVR software.  Everything is now
CLI/ffmpeg configured entirely from sky-cam.conf.

capture.sh
  Long-running systemd service (one per camera) that pulls frames from the
  camera's RTSP stream at CAPTURE_INTERVAL seconds, writing HH-MM-SS.jpg
  into BASE_DIR/<cam>/YYYY-MM-DD/.  Restarts at midnight for the new date
  directory; auto-reconnects on camera disconnect.

sunrise-audio-capture.sh
  One-shot service triggered at 03:00.  Waits until (sunrise minus
  SUNRISE_PRE_MIN minus AUDIO_PRE_BUFFER_MIN), then records the RTSP audio
  stream for the full sunrise window.  Output deleted after mixing.

daily_sunrise_video.sh
  Step 3 now mixes in sunrise-audio.m4a when AUDIO_ENABLED=true and the
  file exists.  Audio is centred on actual sunrise time at natural speed
  while the video plays as the sped-up timelapse.  Uses filter_complex
  when audio is present (can't combine -vf with -filter_complex).

install.sh
  Generates sky-cam-capture-<cam>.service for each camera with CAM_RTSP_<cam>
  set, and sky-cam-audio-capture.{service,timer} when AUDIO_ENABLED=true.

sky-cam.conf
  New settings: CAM_RTSP_<cam>, CAPTURE_INTERVAL, AUDIO_ENABLED,
  AUDIO_PRE_BUFFER_MIN, CAPTURE_AUDIO_BITRATE.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 20:59:40 +00:00
Claude 6629f91219 Add README with quick-start, architecture overview, and operations guide
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 19:35:07 +00:00
Outis ad24c97036 Merge pull request #9 from outis1one/claude/seasonal-sunrise-montage-nn268
Degrade gracefully on overlay/audio failure; notify on upload success
2026-04-19 15:32:50 -04:00
Claude b911b228bb Degrade gracefully on overlay/audio failure; notify on upload success
Sunrise:
- Overlay failure no longer exits 1; the speed-only video is renamed to the
  expected final path so OnSuccess still fires and the upload still happens
- sunrise2mm.py now notifies on every upload outcome (success, post failure,
  file-not-found) via notify.sh so the user always knows whether the video
  reached Mattermost

Montage:
- Music+overlay failure no longer exits 1; the sped video is promoted to the
  *-Montage.mp4 path so year-end-join can still include this movement (as a
  silent, no-overlay clip) and the user is notified of the degraded output
- Year-end join trigger is now outside the success/failure branch so it fires
  in both cases

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 18:42:46 +00:00
Outis 084c2ba9cb Merge pull request #8 from outis1one/claude/seasonal-sunrise-montage-nn268
Claude/seasonal sunrise montage nn268
2026-04-19 14:25:25 -04:00
Claude 9c929f28d8 Add per-step resilience and notifications across all video pipeline scripts
Each pipeline now saves intermediate files permanently before the step most
likely to fail, so a partial failure leaves a recoverable artifact:
- daily_sunrise_video.sh: speed-adjusted video (*-sped.mp4) survives if the
  drawtext overlay step fails; deleted automatically on success
- montage-mvt.sh: speed-adjusted video (*-Sped.mp4) survives if the
  music-mux + attribution overlay step fails; deleted on success
- 4-seasons.sh / montage-mvt.sh / year-end-join.sh: explicit ffmpeg error
  handling with targeted notify.sh calls naming the failed step and the
  surviving artifact path
- montage-mvt.sh / 4-seasons.sh / year-end-join.sh: clip-duration-sum vs
  music-duration drift check warns when cumulative float error exceeds 2 s

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 17:35:26 +00:00
Claude 62c787fc0b Add .gitignore to exclude __pycache__
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 16:48:18 +00:00
Claude 7486916f9f Sunrise time overlay; systemd upload separation; bug fixes
daily_sunrise_video.sh:
- Fixed: was using undefined \$MOVIES_DIR (now \$BASE_DIR/movies)
- Fixed: sunrise_overlay.py was called but never existed — would fail daily
- Fixed: speed-adjust step had no explicit codec (-c:v libx264 missing)
- New: sunrise time overlaid as stacked vertical characters on the right
  side using ffmpeg drawtext — no Python/Pillow dependency
- New: upload removed from script; now triggered by systemd OnSuccess=
- Combines speed-adjust and overlay into one ffmpeg pass (was two)
- SUNRISE_OVERLAY_OPACITY from conf controls transparency

install.sh:
- sky-cam-sunrise.service gains OnSuccess=sky-cam-sunrise-upload.service
  so upload only runs when video creation succeeds, with separate log
- New sky-cam-sunrise-upload.service runs sunrise2mm.py

sunrise2mm.py: add shebang + chmod +x so systemd ExecStart= calls it directly

sky-cam.conf: add SUNRISE_OVERLAY_OPACITY=0.45

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 16:35:33 +00:00
Claude 6d68010691 Expose encoding quality and overlay durations in sky-cam.conf
Adds six CRF vars, AUDIO_BITRATE, and three MONTAGE_* overlay durations.
Values match previous hardcoded defaults so behavior is unchanged.

The same CRF appeared in several scripts but with intentionally different
values per purpose (28 for draft intermediates, 26 for polished output).
Each script's CRF is now its own variable in conf, so changing one never
silently changes another.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 16:08:14 +00:00
Claude fffb19fd38 Add MOVIES_DIR to conf; remove hardcoded 'movies' subdir
All scripts now use $MOVIES_DIR instead of $BASE_DIR/movies.
Defaults to BASE_DIR/movies but can point to a separate drive.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 16:01:27 +00:00
Claude 46b3a36d0a Add lat/lon source instructions to conf comment
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 11:08:19 +00:00
Claude 6d85fa525a Multi-camera support; schedules in conf; comment out notifications
sky-cam.conf:
- CAMERAS array replaces single CAM_NAME; add a name, add its schedules,
  re-run install.sh — no script editing needed
- SCHEDULE_SUNRISE, SCHEDULE_SEASONS_<cam>, SCHEDULE_FULLDAY_<cam> replace
  hardcoded times in install.sh
- Notification options commented out (uncomment to enable)
- Lat/lon set to mid-Atlantic (25.0, -38.0) as neutral placeholder

install.sh:
- Loops over CAMERAS to generate per-camera sky-cam-seasons-<cam> and
  sky-cam-fullday-<cam> timers with schedules from conf
- Sunrise timer remains a single sky-cam-sunrise unit (SUNRISE_CAM only)

fullday-video.sh, 4-seasons.sh, montage-mvt.sh, year-end-join.sh:
- Each accepts camera name as an argument (systemd passes it via ExecStart)
  and falls back to conf default when run manually without an arg
- Camera name propagates through the full call chain:
  4-seasons → montage-mvt → year-end-join

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 11:04:51 +00:00
Outis 79d7061ebe Merge pull request #7 from outis1one/claude/seasonal-sunrise-montage-nn268
Add bootstrap.sh — one-file download that pulls repo from GitHub
2026-04-19 06:48:13 -04:00
Claude 9ecb9d6783 Add bootstrap.sh — one-file download that pulls repo from GitHub
curl -fsSL https://raw.githubusercontent.com/outis1one/sky-cam/main/bootstrap.sh | bash

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 02:17:18 +00:00
Outis 065319c1b7 Merge pull request #6 from outis1one/claude/seasonal-sunrise-montage-nn268
Claude/seasonal sunrise montage nn268
2026-04-18 21:56:19 -04:00
Claude f8c1b4522d Add file dependency map to sky-cam.conf
Documents who calls whom and exactly which files to update
if any script is renamed — so future-you doesn't have to grep.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 00:59:31 +00:00
Claude 4ca1f579d2 Rename sunrise_video.10s.sh → daily_sunrise_video.sh
Name no longer implies a fixed duration. Updated all references:
install.sh, sky-cam.conf script map, systemd/sky-cam-sunrise.service.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 00:52:24 +00:00
Claude 3addb06ce8 Rename sunrise output to daily-sunrise.mp4 (duration-agnostic)
Video duration is still controlled by SUNRISE_TARGET_SECS in conf,
but the filename no longer encodes it — so changing the duration
doesn't break anything and the name stays stable day to day.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 00:26:40 +00:00
Claude d20a0d94ae Fix sunrise output filename to reflect SUNRISE_TARGET_SECS from conf
The output video was always named -sunrise-10s.mp4 regardless of the
configured duration. Both sunrise_video.10s.sh and sunrise2mm.py now
derive the filename from SUNRISE_TARGET_SECS so changing it in conf
produces correctly named files that the uploader still finds.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 00:19:59 +00:00
Claude be5735867e Remove all hardcoded deployment values; read from sky-cam.conf
- sunrise_video.10s.sh: use $TIMEZONE (was hardcoded America/New_York),
  $SUNRISE_PRE_MIN/$SUNRISE_POST_MIN for capture window, $SUNRISE_TARGET_SECS
  for output duration (was wrong value 8 in a script named 10s)
- fullday-video.sh: remove hardcoded FULLDAY_FPS/RETENTION_DAYS; both now
  come from sky-cam.conf
- 4-seasons.sh, montage-mvt.sh: export TIMEZONE after sourcing conf so
  season_info.py subprocess picks it up via env rather than falling back
  to its hardcoded America/New_York default
- sky-cam.conf: add SUNRISE_PRE_MIN, SUNRISE_POST_MIN, SUNRISE_TARGET_SECS,
  FULLDAY_FPS, RETENTION_DAYS

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 00:14:59 +00:00
Outis 5db51ef9d9 Merge pull request #5 from outis1one/claude/seasonal-sunrise-montage-nn268
Claude/seasonal sunrise montage nn268
2026-04-18 20:11:24 -04:00
Claude 713c44adb3 Add LATITUDE/LONGITUDE to conf; sunrise.py reads coords from conf
sunrise.py now reads LATITUDE, LONGITUDE, and TIMEZONE from sky-cam.conf
instead of hardcoded values, using the same pathlib-based pattern as
sunrise2mm.py.  sky-cam.conf gains a comprehensive header with manual
systemd setup instructions and a full script map for future reference.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-19 00:09:58 +00:00
Claude 5d3ee97df0 All paths into sky-cam.conf; install.sh generates systemd units
sky-cam.conf
- Add SCRIPT_DIR (install location) and CAM_NAME (camera/folder name)
- These are the only values that change when deploying to a new machine

install.sh (new)
- Sources sky-cam.conf, generates all systemd .service and .timer units
  with correct ExecStart paths, then enables and starts the timers
- Run once after editing sky-cam.conf; run again if paths change
- Supports --system flag for system-wide install

All .sh scripts + sunrise2mm.py
- No hardcoded paths remain
- script_name=$(basename ...) derivation replaced by $CAM_NAME from conf
- sunrise_video.10s.sh now sources sky-cam.conf for BASE_DIR, CAM_NAME,
  and SCRIPT_DIR (replaces all /home/motion/... references)
- sunrise2mm.py builds video path from BASE_DIR + CAM_NAME in conf

systemd/ template files kept as reference but no longer need editing

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-18 21:31:26 +00:00
Outis bd8513c0c2 Merge pull request #4 from outis1one/claude/seasonal-sunrise-montage-nn268
Claude/seasonal sunrise montage nn268
2026-04-18 17:22:27 -04:00
Claude ac01c05948 Consolidate config into sky-cam.conf; systemd failure notifications
sky-cam.conf (new)
- Single file replaces mattermost_config.txt reference, notify_config.txt,
  and the hardcoded BASE_DIR/MUSIC_DIR/TIMEZONE scattered across scripts
- Bash-sourceable and Python key=value readable (same format)

All .sh scripts
- source sky-cam.conf at startup; BASE_DIR / MUSIC_DIR from config

sunrise2mm.py
- Reads sky-cam.conf relative to script location; no hardcoded path

notify.sh
- Sources sky-cam.conf; Mattermost credentials come from there directly,
  no separate mattermost_config.txt lookup needed

systemd/sky-cam-notify-failure@.service (new)
- Template unit called by OnFailure= in each service
- Sends notification via notify.sh when any sky-cam job fails
- All three .service units now have OnFailure=sky-cam-notify-failure@%n.service

Removed: notify_config.txt, sky-cam.crontab (superseded)

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-18 17:11:06 +00:00
Claude 8617248cc0 Add year-based folders, attribution overlay, notifications, crontab/systemd
season_info.py
- Add ASTRO_YEAR: year of the Winter solstice that started the current cycle
  (Spring/Summer/Autumn 2026 → 2025; Winter Dec-2026 → 2026)

4-seasons.sh
- Daily clip output path now includes ASTRO_YEAR:
  movies/$name/$ASTRO_YEAR/$SEASON/Mvt$N/

montage-mvt.sh (full rewrite)
- Attribution is now a drawtext overlay (top 6 s of the video, fade in/out)
  instead of an appended black card — no frame-size matching needed, and
  year-end join requires no special handling
- Output path mirrors the new year-based folder structure
- Sends notification via notify.sh when done
- Automatically triggers year-end-join.sh after Autumn Mvt 3

year-end-join.sh (new)
- Concatenates all 12 movement montages for a given ASTRO_YEAR
- Output: movies/$name/$ASTRO_YEAR/$name-$ASTRO_YEAR.mp4
- Sends notification when done

notify.sh + notify_config.txt (new)
- Generic best-effort notification helper: ntfy, email, Mattermost text post
- All methods disabled by default; user fills in notify_config.txt

sky-cam.crontab + systemd/ (new)
- Crontab file: sunrise at 09:00, 4-seasons at 01:00, fullday at 02:00
- systemd .service + .timer units for all three daily jobs
- montage/year-end triggered internally, not by cron

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-18 13:59:48 +00:00
Claude b827c58eda Rewrite stitch-cameras.py: north-only cylindrical warp + colour matching
- Warp only north cylindrically (sunrise completely unmodified)
- Focal-length grid search picks the best phase-correlation alignment
- Soft validity mask (31x31 erosion) fades out black corners of the warp
- Per-channel colour/exposure match: north's treeline strip mean is scaled
  to match sunrise's, removing the visible sky-colour seam between cameras
- Corrected overlap blend: invalid north pixels fall back to sunrise
  (s_weight = max(alpha, 1-validity)) instead of showing black
- Auto-crops left black-corner columns from the final canvas

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-18 13:11:16 +00:00
Claude e34beeed00 Add cylindrical panorama previews (f=1920 and f=1550)
North is projected onto a cylinder so its right edge curves naturally into
sunrise's left edge, giving a continuous panoramic sweep from North to East.

cyl-f1920-preview.jpg  — f=1920 px (~90° HFOV): most natural perspective
cyl-f1550-preview.jpg  — f=1550 px (~105° HFOV): more pronounced curve

stitch-cameras.py updated to use cylindrical projection.  Focal length is
a tunable argv[4]; refine once the user confirms which curve looks right.
The 36-second inter-shot gap causes cloud drift at the seam — live video
frames captured simultaneously will not have this artefact.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-18 11:19:03 +00:00
Outis 83cb7145cb Merge pull request #3 from outis1one/claude/seasonal-sunrise-montage-nn268
Add aligned panorama preview and finalised stitch script
2026-04-18 07:12:10 -04:00
Claude df26e1d8e3 Add aligned panorama preview and finalised stitch script
Phase-correlation on the treeline/horizon band (rows 70-90%) found:
  tx = -3324 px   (north is 3324 px to the left of sunrise)
  ty = -85 px     (north camera is 85 px higher — slight tilt difference)
  overlap = 516 px wide, feather-blended with a horizontal gradient

Result in images/stitch-preview/north-sunrise-aligned-preview.jpg:
  7164x2075 px panorama with continuous horizon and treeline.
  Cloud "V" at seam is a 36-second inter-shot artefact only; live video
  frames captured simultaneously will have no such discontinuity.

stitch-cameras.py: accepts tx/ty overrides as argv[4]/argv[5] so the
  offsets can be tuned without code changes.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-18 04:15:34 +00:00
Outis fb0af560f2 Merge pull request #2 from outis1one/claude/seasonal-sunrise-montage-nn268
Add camera-stitch preview and feature-matching script
2026-04-18 00:02:05 -04:00
Claude 8908c2f01a Add camera-stitch preview and feature-matching script
- images/stitch-preview/north-sunrise-hstack.jpg:
  naive side-by-side preview of the two skycams at 14:29 on 2026-04-17
- images/stitch-preview/feature-matches-debug.jpg:
  close-up of overlap region (right 40% of north × left 40% of sunrise)
  with ORB Lowe-ratio matches drawn — 39 candidates, RANSAC survives only
  4 inliers because the 90° perspective offset invalidates a similarity
  transform.  Overlap IS present (trees, houses, power poles visible in
  both) but full homography needs more/better tie points.
- stitch-cameras.py: reusable script that generates both previews plus a
  similarity-transform .txt for reuse in ffmpeg filter chains once we
  have enough matches (or manual tie-points).

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
2026-04-18 03:59:36 +00:00
Outis f0a1aa5d51 Add files via upload 2026-04-17 23:50:36 -04:00
Outis cb7fc82992 Add files via upload 2026-04-17 23:50:16 -04:00
Outis bb1d996254 Create test 2026-04-17 23:48:41 -04:00
Outis 0965b7bee3 Merge pull request #1 from outis1one/claude/seasonal-sunrise-montage-nn268
Claude/seasonal sunrise montage nn268
2026-04-17 23:48:13 -04:00