Add smoke-test script for cloud-veil composite

test_moon_composite.py uses the existing repo sample frames
(21-07-00.jpg east frame with thin cloud cover + full_moon_closeup.jpg
as NASA render stand-in) to produce test_composite_out.jpg without
needing a live NASA API call or moon detection run.

Run: python3 test_moon_composite.py

https://claude.ai/code/session_01HkTxpNSTWtViZzxbrbKytR
This commit is contained in:
Claude
2026-05-01 17:16:50 +00:00
parent 3ededd68b8
commit 09fda8d8af
+111
View File
@@ -0,0 +1,111 @@
#!/usr/bin/env python3
"""test_moon_composite.py — smoke-test the cloud-veil composite using local files.
Uses the sample east frame (21-07-00.jpg) and the reference moon photo
(full_moon_closeup.jpg) already in the repo to produce a composite without
needing a live NASA API call or actual moon detection.
Run from the sky-cam directory:
python3 test_moon_composite.py
Output: test_composite_out.jpg in the same directory.
The east frame (2026-04-29 21:06:45) shows the moon with visible thin cloud
cover across the sky, so the cloud-veil layer should be clearly active.
"""
import pathlib
import sys
from datetime import datetime, timezone
HERE = pathlib.Path(__file__).resolve().parent
sys.path.insert(0, str(HERE))
EAST_FRAME = HERE / "21-07-00.jpg"
NASA_RENDER = HERE / "full_moon_closeup.jpg"
OUT_PATH = HERE / "test_composite_out.jpg"
# Approximate moon centroid in the east frame, estimated visually.
# The moon appears at roughly 68% from left, 31% from top of the 1920×1080 frame.
# moon_detect.py would compute these exactly at runtime.
MOON_CX_FRAC = 0.68
MOON_CY_FRAC = 0.31
# Apparent diameter in source pixels — roughly 38 px for a typical wide-field
# IP camera at full-moon. Adjust if your camera gives a larger blob.
MOON_DIAM_PX = 38
def _make_fake_detection(frame_path):
"""Return a detection-like object with centroid_xy and diameter_px."""
from PIL import Image
im = Image.open(frame_path)
w, h = im.size
cx = w * MOON_CX_FRAC
cy = h * MOON_CY_FRAC
print(f" frame size : {w}×{h}")
print(f" moon centroid: ({cx:.0f}, {cy:.0f})")
print(f" moon diameter: {MOON_DIAM_PX} px")
class _Det:
centroid_xy = (cx, cy)
diameter_px = MOON_DIAM_PX
quality = 0.82 # plausible for a hazy but visible moon
return _Det()
def main():
for p in (EAST_FRAME, NASA_RENDER):
if not p.exists():
print(f"ERROR: missing {p}", file=sys.stderr)
sys.exit(1)
print("=== moon composite smoke-test ===")
print(f"east frame : {EAST_FRAME.name}")
print(f"NASA render : {NASA_RENDER.name}")
print(f"output : {OUT_PATH.name}")
print()
det = _make_fake_detection(EAST_FRAME)
# Timestamp matching the east frame filename
when_utc = datetime(2026, 4, 29, 21, 7, 0, tzinfo=timezone.utc)
from moon_composite import render_phase_closeup
caption = (
"Full Moon — April 2026 — "
"sky-cam east witnessed at 2026-04-29 21:07:00 UTC "
"(+7 min from exact full) — render: NASA SVS Dial-a-Moon [SIMULATED]"
)
print("rendering composite …")
render_phase_closeup(
nasa_render_path=str(NASA_RENDER),
out_path=str(OUT_PATH),
output_size=(1920, 1080),
moon_height_pct=0.92,
caption=caption,
east_frame_path=str(EAST_FRAME),
east_detection=det,
cloud_overlay_enabled=True,
cloud_overlay_max_opacity=0.40,
cloud_overlay_blur=0, # auto
)
print(f"\ndone → {OUT_PATH}")
print()
print("What you should see:")
print(" • Full moon disk filling ~92% of the 1920×1080 frame")
print(" • Thin grey-blue cloud veil over the composite — sourced from")
print(" the sky ring around the moon in 21-07-00.jpg, blurred to haze")
print(" • Moon disk re-pasted sharp on top of the veil layer")
print(" • Caption at bottom-left with phase / date / witness text")
print()
print("Sky brightness in the annular ring drives veil opacity.")
print("The hazy sky visible in 21-07-00.jpg should produce a visible but")
print("partial veil (estimated ~2030% opacity for that frame).")
if __name__ == "__main__":
main()