The V3 detector's fixed 512x512 stretch-resize and the V4 detector's
naive closest-profile matching both miss images whose delivered
resolution is a clean upscale of one of the codebook's captured
profiles in the transposed orientation (e.g. a portrait 1792x2390
download that is exactly 2x a landscape 896x1195 reference profile).
Confirmed on a real Gemini download: was scoring 0.20-0.36 confidence
(false negative), now correctly detected at 0.50.
detect_watermark() now checks for a profile the image is a clean
scaled/rotated version of (aspect ratio within 0.3%) and runs V4
detection against it when found, keeping the max confidence against
the V3 baseline. An earlier version of this that tried every
orientation against every profile introduced false positives on clean
images by taking the max over too many independent noisy checks; the
strict tolerance requirement (empirically: genuine matches land at
~0.00% deviation, coincidental ones at 1.5%+) avoids that while still
catching the real case. Re-verified against the full validation set
(4 clean images, still 0.03-0.08 confidence) plus two known-watermarked
references (both still correctly flagged).
Blindly subtracting the codebook's carrier pattern from an image that
never had the watermark would imprint one instead of removing it. Now
each image is run through RobustSynthIDExtractor first, and the V3
bypass only runs when a watermark is actually detected; otherwise the
image passes through untouched (still eligible for metadata stripping).
Small Tkinter app: drop images in, get SynthID-cleaned copies out,
with an option to strip EXIF/XMP/IPTC metadata from the output.
Runs offline on the existing V3 codebook, no PyTorch required.