mirror of
https://github.com/wiltodelta/remove-ai-watermarks.git
synced 2026-09-02 02:30:48 +02:00
Harden scale-registered SynthID detection
This commit is contained in:
+8
-2
@@ -64,13 +64,19 @@ TrustMark. Metadata inspection still runs.
|
||||
```bash
|
||||
remove-ai-watermarks detect-synthid image.png
|
||||
remove-ai-watermarks detect-synthid image.png --json
|
||||
remove-ai-watermarks detect-synthid resized.png --register-scale
|
||||
```
|
||||
|
||||
The command returns one of `detected`, `not_detected`, or `unsupported`. The
|
||||
runtime detector covers one frozen periodic carrier family in the
|
||||
[calibrated image-size range](synthid.md#32-how-our-tool-detects-the-supported-carrier)
|
||||
and needs the `pixels` extra. It never resizes the input and does not register
|
||||
a carrier whose sampling period changed through arbitrary spatial resampling.
|
||||
and needs the `pixels` extra. The default never resizes the input and does not
|
||||
register a carrier whose sampling period changed through spatial resampling.
|
||||
`--register-scale` enables a substantially slower bounded search over measured
|
||||
carrier periods for images from 250,000 through 10,000,000 decoded pixels, with
|
||||
both sides at least 64 pixels. It is opt-in and is not used by `identify`.
|
||||
The measured positive scale range is approximately 0.65 through 1.5; 0.5x
|
||||
resizes are not reliably detected.
|
||||
It is positive-only: `not_detected` means the score stayed below this detector's
|
||||
threshold, while `unsupported` means the image geometry is outside its scope.
|
||||
Neither result proves that another SynthID epoch or payload is absent.
|
||||
|
||||
@@ -70,13 +70,17 @@ Google does not publish the proprietary SynthID payload decoder. The project
|
||||
ships a positive-only detector for one measured periodic image carrier in a
|
||||
calibrated image-size range, plus provenance-based recognition
|
||||
from Google AI C2PA or current OpenAI C2PA with an explicit watermark action.
|
||||
It does not cover images outside that size range, crop, strong JPEG compression,
|
||||
video, or future carrier epochs. Arbitrary dimensions inside the range are
|
||||
supported only while the recovered carrier retains its measured 16-pixel
|
||||
sampling lattice. A spatial resize changes that period; the runtime does not
|
||||
yet search fractional periods or infer the pre-resize geometry. A `not_detected`
|
||||
or `unsupported` result is not a negative universal verdict, and removal still
|
||||
requires the matching provider oracle for confirmation.
|
||||
It does not cover images outside the selected mode's size range, crop, strong
|
||||
JPEG compression, video, or future carrier epochs. Arbitrary dimensions inside
|
||||
the default range are supported only while the recovered carrier retains its
|
||||
measured 16-pixel sampling lattice. A spatial resize changes that period. The
|
||||
opt-in `detect-synthid --register-scale` mode searches a bounded
|
||||
fractional-period range for images from 250,000 through 10,000,000 pixels, but
|
||||
requires both sides to be at least 64 pixels. Its measured positive range is
|
||||
approximately scale 0.65 through 1.5; a 0.5 resize aliases the carrier with
|
||||
ordinary resize lattices and is not reliably detected. It is also slower. A
|
||||
`not_detected` or `unsupported` result is not a negative universal verdict, and
|
||||
removal still requires the matching provider oracle for confirmation.
|
||||
|
||||
For important outputs:
|
||||
|
||||
|
||||
@@ -500,7 +500,32 @@ the native threshold, compared with an upper bound of 48 when the true source
|
||||
geometry was supplied. The complete search still failed its small frozen
|
||||
control split: a threshold above 250 development controls accepted two of 150
|
||||
final controls. Multiplying the canonical score by spectral-period confidence
|
||||
also accepted two. This branch is not a calibrated runtime fallback.
|
||||
also accepted two. That baseline was rejected rather than shipped at its
|
||||
discovery threshold.
|
||||
|
||||
The opt-in `register_scale=True` path is the later calibrated successor. It
|
||||
keeps the harmonic search, adds three-level scale-space consistency and quadrant
|
||||
agreement. Its calibrated decision requires the canonical winner to be the
|
||||
strongest spectral-period candidate, its three-way amplitude to cross the
|
||||
threshold for that period bin, and both independent high-frequency template
|
||||
bands to correlate by at least `0.075`. The public registered score is the
|
||||
minimum normalized margin across those gates, so its decision threshold is
|
||||
`1.0`.
|
||||
|
||||
The earlier single-threshold version produced 68 false positives among 11,273
|
||||
symmetrically downscaled Spaces controls. A top-candidate plus period-bin version
|
||||
removed those but still produced 6 false positives among 1,000 source-independent
|
||||
Open Images controls. The high-band gate removed them and then accepted none of
|
||||
499 previously untouched Open Images reserve controls. The resulting rule
|
||||
retained 229 of 355 source-disjoint transformed positives: 0/65 at scale 0.5 and
|
||||
229/290 from scale 0.65 through 1.5. The explicit period-8 rescue is rejected
|
||||
because resize lattices fully overlap its positive distribution.
|
||||
|
||||
The separately measured geometry range remains 250,000 through 10,000,000
|
||||
decoded pixels with both sides at least 64 pixels. The default path and
|
||||
`identify` remain the native fold. A 20-image real-corpus drift check was
|
||||
byte-identical after integration. The calibration history and caveats are in the
|
||||
linked detector research plan.
|
||||
|
||||
### Portable metadata record
|
||||
|
||||
|
||||
+13
-5
@@ -23,15 +23,23 @@ result = raiw.detect_synthid("input.png")
|
||||
print(result.status) # "detected" | "not_detected" | "unsupported"
|
||||
print(result.score) # float for a supported image size, otherwise None
|
||||
print(result.threshold) # frozen operating point
|
||||
|
||||
# Opt in when the image may have been spatially resized.
|
||||
registered = raiw.detect_synthid("resized.png", register_scale=True)
|
||||
```
|
||||
|
||||
The detector is positive-only and covers one measured periodic carrier family
|
||||
in the [calibrated image-size range](synthid.md#32-how-our-tool-detects-the-supported-carrier).
|
||||
Arbitrary dimensions are accepted inside that range, but arbitrary spatial
|
||||
resampling can change the carrier period and is not registered. `not_detected`
|
||||
means only that this model did not find its carrier; `unsupported` is kept
|
||||
separate from a negative result. Neither is proof that the image contains no
|
||||
SynthID watermark.
|
||||
Arbitrary dimensions are accepted inside the default range, but spatial
|
||||
resampling can change the carrier period. `register_scale=True` enables the
|
||||
slower scale-registered operating point over 250,000 through 10,000,000 decoded
|
||||
pixels, with both sides at least 64 pixels; the default remains the native-period
|
||||
detector used by `identify`. Its score is a normalized multi-gate statistic with
|
||||
a threshold of `1.0`, not the native detector's raw template correlation. Scale
|
||||
0.5 is outside its reliable positive range.
|
||||
`not_detected` means only that the selected model did not find its carrier;
|
||||
`unsupported` is kept separate from a negative result. Neither is proof that
|
||||
the image contains no SynthID watermark.
|
||||
|
||||
## Remove visible marks
|
||||
|
||||
|
||||
@@ -132,9 +132,14 @@ calibrated image-size range, available through `detect-synthid`
|
||||
and the default pixel pass in `identify` when the `pixels` extra is installed.
|
||||
The unchanged fixed threshold accepted none of the public COCO views in both
|
||||
an observed-geometry challenge and a generated-geometry challenge covering all
|
||||
modulo-16 edge cases. Arbitrary dimensions in the calibrated range are accepted,
|
||||
but the input must retain the measured 16-pixel carrier scale: arbitrary spatial
|
||||
resampling is not registered. The detector does not attribute a provider locally.
|
||||
modulo-16 edge cases. Arbitrary dimensions in the default calibrated range are
|
||||
accepted, but the input must retain the measured 16-pixel carrier scale. The
|
||||
opt-in `detect-synthid --register-scale` mode performs a slower bounded scale
|
||||
search over its separately measured 250,000-through-10,000,000-pixel range and
|
||||
requires both sides to be at least 64 pixels. Its measured positive scale range
|
||||
is approximately 0.65 through 1.5; 0.5x resizes are not reliably detected.
|
||||
`identify` does not enable that search. Neither detector attributes a provider
|
||||
locally.
|
||||
|
||||
The tool also recognizes presence from supported provenance: Google AI C2PA
|
||||
under Google's all-media watermark policy, and current OpenAI C2PA carrying an
|
||||
|
||||
@@ -1331,6 +1331,99 @@ acceptance from 49 to 52 of 60 at its development threshold but accepted the
|
||||
same two final controls. This fractional FFT baseline is rejected for runtime
|
||||
use; better period estimation alone does not solve multiple-search specificity.
|
||||
|
||||
### 2026-08-11: multiscale calibration and opt-in registered detector
|
||||
|
||||
The fractional search was revisited as a multiple-search calibration problem,
|
||||
not as period estimation alone. A source-disjoint challenge used 200 confirmed
|
||||
fixed-carrier positives, 40 independent sources at each scale 0.8, 0.9, 1.1,
|
||||
1.2, and 1.333. Controls were 4,900 unique COCO images resized into the positive
|
||||
pixel-count domain, split into 2,900 development and 2,000 final items. The ten
|
||||
frozen candidates combined exact fractional canonical correlation, quadrant
|
||||
agreement, and a three-level scale-space score through mean or minimum rules.
|
||||
Pure box-counting dimensions, multifractal width, lacunarity, roughness,
|
||||
wavelet-energy slope, and a generic log-Mellin response had already failed the
|
||||
smaller pilot and were not promoted to the large challenge.
|
||||
|
||||
At the development-only threshold, the three-way mean accepted 177 of 200
|
||||
positives versus 163 for canonical correlation alone, with 16 positives rescued
|
||||
and two lost in the paired decision. Each produced one final false positive, on
|
||||
different source images, so the development threshold was rejected. Recalibrating
|
||||
above all 4,900 COCO controls left 176 of 200 three-way positives and 160 of 200
|
||||
canonical-only positives. This recalibration is exploratory rather than a new
|
||||
validation because the final controls had then been inspected.
|
||||
|
||||
A second source-disjoint corpus froze those thresholds before scoring 105 new
|
||||
positives across scales 0.5, 0.65, 0.8, 1.0, 1.2, 1.333, and 1.5, plus all 879
|
||||
content-deduplicated Kodak and Picsum controls available locally. Natural
|
||||
2816x1536 controls had a heavier null tail than upscaled COCO: the three-way
|
||||
mean accepted 82 of 105 positives and six controls at the COCO threshold,
|
||||
whereas canonical-only accepted 79 positives and ten controls. A threshold
|
||||
above all 5,779 controls retained 253 of the first 305 positives for the
|
||||
three-way mean. Four coarse pixel-count bins recovered only six more positives,
|
||||
so size normalization did not explain the main 0.5x miss.
|
||||
|
||||
At 0.5x, a fixed period-8 branch raised canonical correlation for seven of the
|
||||
15 discovery positives but also won the unconstrained search on 629 of 879
|
||||
controls. Searching it unconditionally merely raised the null threshold. The
|
||||
frozen remedy requires period-8 native correlation of at least 0.35 and takes
|
||||
the maximum of the old and period-8 three-way scores. It added four positives
|
||||
without an accepted control in the discovery corpus. On the earlier 4,900
|
||||
controls, the frozen gate never opened and none crossed the final three-way
|
||||
threshold `0.2460603834083705`.
|
||||
|
||||
The improvement itself was then tested on 50 additional source-disjoint 0.5x
|
||||
positives that influenced neither gate nor threshold. The ungated three-way
|
||||
score accepted 6; the frozen gate accepted 17, rescuing 11 and losing none. The
|
||||
exact paired sign test was `p = 0.0009765625`. These results support an opt-in
|
||||
scale-registered detector over 250,000 through 10,000,000 decoded pixels. The
|
||||
runtime also requires both sides to be at least 64 pixels so each canonical
|
||||
quadrant can retain a full 16-by-16 tile. These results do not establish a
|
||||
universal SynthID decoder: the control maximum helped set the operating point,
|
||||
33 of 50 new 0.5x positives still missed, and crop, strong codec changes, other
|
||||
carrier epochs, and provider attribution remain outside the claim. The fast
|
||||
native fold remains the default and the `identify` path.
|
||||
|
||||
That period-8 conclusion was overturned by a later symmetric negative test.
|
||||
Every one of the 11,506 known non-Google Spaces controls was downscaled by 0.5,
|
||||
matching the positive transformation; 11,273 outputs remained in the registered
|
||||
geometry range. The direct analytic 8-by-8 template was dominated by shared
|
||||
resize structure: 80.8% of its energy projected onto a 2-by-2 lattice and 94.0%
|
||||
onto a 4-by-4 lattice. The production period-8 gate opened on 73 controls, and
|
||||
all 73 crossed the registered threshold. They spanned hosted jobs, Firefly,
|
||||
China AIGC-labeled generators, Meta-tagged images, OpenAI, and local tools. No
|
||||
tested secondary condition separated the 11 rescued positives from those 73
|
||||
controls. The explicit period-8 rescue is therefore rejected and not part of
|
||||
the runtime detector. The 0.5x rescue result is retained here as an incident
|
||||
record against asymmetric transformed-positive evaluation.
|
||||
|
||||
The same symmetric corpus also invalidated the main single-threshold registered
|
||||
rule: 68 of 11,273 supported controls crossed `0.2460603834083705`. Fixed
|
||||
thresholds for nine recovered-period bins eliminated those errors while
|
||||
retaining 238 of 355 transformed positives, but one of 4,900 COCO controls then
|
||||
crossed through the third spectral candidate. Requiring the canonical winner to
|
||||
match the strongest spectral candidate removed that case and all 68 Spaces
|
||||
errors, with 239 of 355 positives retained. This version was not shipped: a
|
||||
fresh, content-deduplicated 1,000-image Open Images validation corpus produced
|
||||
six false positives.
|
||||
|
||||
All six Open Images errors concentrated their apparent match in one
|
||||
middle-frequency ring. Their correlations disappeared or changed sign in the
|
||||
two higher-frequency rings of the 16-by-16 carrier, unlike the accepted Gemini
|
||||
positives. Adding a frozen minimum correlation of `0.075` across those two rings
|
||||
removed the six development errors and retained 229 of 355 positives. A
|
||||
previously untouched reserve of 499 supported Open Images controls then produced
|
||||
five amplitude-gate candidates and zero final positives; their maximum
|
||||
high-band score was `0.004682175209264222`.
|
||||
|
||||
The retained positives by scale were 0/65 at 0.5, 8/15 at 0.65, 53/55 at 0.8,
|
||||
33/40 at 0.9, 13/15 at 1.0, 30/40 at 1.1, 38/55 at 1.2, 40/55 at 1.333, and
|
||||
14/15 at 1.5. A physically transformed template recovered strong correlations
|
||||
for some period-8 positives, but 975 top-candidate Spaces controls fully
|
||||
overlapped every tested amplitude, spectral-band, and joint feature. No
|
||||
zero-control operating point retained a period-8 positive. The calibrated
|
||||
runtime therefore uses the top-candidate, period-bin, and high-band gates and
|
||||
makes no 0.5x detection claim.
|
||||
|
||||
### 2026-08-10: OpenAI periodic-carrier challenge
|
||||
|
||||
The OpenAI track repeated the Google carrier method without runtime provenance
|
||||
|
||||
@@ -483,6 +483,30 @@ less conservative per-period thresholds accepted five final controls. The
|
||||
runtime therefore detects arbitrary decoded dimensions only when the carrier
|
||||
retains its measured 16-pixel scale.
|
||||
|
||||
`remove-ai-watermarks detect-synthid image.png --register-scale` opts into the
|
||||
separately calibrated scale-registered detector. It samples the 30 strongest
|
||||
template harmonics over fractional periods, reconstructs the three strongest
|
||||
canonical candidates, and combines full-frame correlation with quadrant and
|
||||
three-level scale-space consistency. A positive result additionally requires
|
||||
the canonical winner to be the strongest spectral candidate, a calibrated
|
||||
threshold for its recovered period, and agreement in two independent
|
||||
high-frequency template bands. The reported score is the minimum normalized
|
||||
margin across these requirements; its threshold is `1.0`.
|
||||
|
||||
The final rule retained 229 of 355 source-disjoint transformed positives and
|
||||
accepted none of 499 previously untouched Open Images controls. It retained
|
||||
229 of 290 positives from scale 0.65 through 1.5, but none of 65 at scale 0.5.
|
||||
A separate period-8 rescue was rejected because symmetric 0.5x control resizing
|
||||
reproduced the same lattice and fully overlapped the positive feature range.
|
||||
The measured input range is 250,000 through 10,000,000 decoded pixels.
|
||||
Both dimensions must also be at least 64 pixels so every canonical quadrant can
|
||||
retain one 16-by-16 carrier tile.
|
||||
|
||||
This mode is not the default because the bounded search is materially slower;
|
||||
scale registration is explicit and `identify` keeps the native detector. The
|
||||
registered mode does not reliably detect 0.5x carriers and does not make the
|
||||
detector universal across crop, codecs, carrier epochs, or providers.
|
||||
|
||||
A positive result identifies the carrier but does not attribute a provider.
|
||||
Provider identity still comes from provenance.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user