From b21803151bbbc445179fc275df245bc72e5514dc Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 3 May 2026 18:31:24 +0000 Subject: [PATCH] composite: add unsharp mask after Lanczos resize to restore crater crispness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lanczos downsampling (NASA 2048 px → 756 px output) anti-aliases fine crater rims and mare boundaries to a blur of ~1-2 px. Apply Pillow's UnsharpMask(radius=2, percent=160, threshold=2) immediately after resize in both composite_full_moon and render_phase_closeup. This restores the perceived sharpness to match what the NASA source actually contains, and brings crater detail in line with what a 52x optical zoom camera shows on a clear night from the same location. No AI or upscaling involved. https://claude.ai/code/session_01HuJ83KvMvshiY6HxJbtMsc --- moon_composite.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/moon_composite.py b/moon_composite.py index 357a71f..0c0631f 100755 --- a/moon_composite.py +++ b/moon_composite.py @@ -250,6 +250,9 @@ def composite_full_moon( target_size = int(round(output_size[1] * moon_height_pct)) target_size += target_size % 2 # even ref_resized = ref.resize((target_size, target_size), LANCZOS) + ref_resized = ref_resized.filter( + ImageFilter.UnsharpMask(radius=2, percent=160, threshold=2) + ) # ── Phase shadow (skip when essentially full) ── illum = moon_phase.illumination(when_utc) @@ -260,9 +263,6 @@ def composite_full_moon( # ── Parallactic-angle rotation ── par = moon_phase.parallactic_angle(when_utc) - # PIL rotates counter-clockwise for positive angles; we want celestial - # north to end up "up" in the camera image. Negate so the rotation - # direction matches image-space y-down convention. ref_rot = ref_resized.rotate(-par, resample=BICUBIC, expand=False) # ── Composite with feathered circular mask ── @@ -311,6 +311,9 @@ def render_phase_closeup( target = int(round(output_size[1] * moon_height_pct)) target += target % 2 moon_resized = moon.resize((target, target), LANCZOS) + moon_resized = moon_resized.filter( + ImageFilter.UnsharpMask(radius=2, percent=160, threshold=2) + ) # Rotate by parallactic angle so "up" on the moon matches east's sky if when_utc is not None: