mirror of
https://github.com/wiltodelta/remove-ai-watermarks.git
synced 2026-08-31 09:40:38 +02:00
Record pipeline-lattice reframing and registered-v3 phase lock
Document that the pixel route detects an origin-anchored lattice rather than the watermark, and record the registered-v3 two-pixel phase-lock measurement: a 2px diagonal crop killed all 36 tested detections (28 foreign-generator, 8 Google) with recovery only at offsets that are multiples of four. Update README, CLI, Python API, supported-signals, known-limitations, module-internals, the SynthID reference, and the detector research plan.
This commit is contained in:
+40
-17
@@ -12,7 +12,7 @@ path that still runs on CPU and combines `video` and `diffusion`. Add `heif`
|
||||
independently when path-based pixel APIs must decode HEIC, HEIF, or AVIF. See
|
||||
the complete [feature-extra matrix](installation.md#feature-extras).
|
||||
|
||||
## Detect the supported SynthID carrier
|
||||
## Detect the generation-pipeline lattice (experimental)
|
||||
|
||||
Install `remove-ai-watermarks[pixels]`, then call the lazy top-level API:
|
||||
|
||||
@@ -20,26 +20,48 @@ Install `remove-ai-watermarks[pixels]`, then call the lazy top-level API:
|
||||
import remove_ai_watermarks as raiw
|
||||
|
||||
result = raiw.detect_synthid("input.png")
|
||||
print(result.status) # "detected" | "not_detected" | "unsupported"
|
||||
print(result.status) # "detected" | "indeterminate" | "unsupported"
|
||||
print(result.score) # float for a supported image size, otherwise None
|
||||
print(result.threshold) # frozen operating point
|
||||
print(result.reason) # support or non-detection reason, otherwise None
|
||||
|
||||
# Opt in when the image may have been spatially resized.
|
||||
registered = raiw.detect_synthid("resized.png", register_scale=True)
|
||||
# Force the legacy native-period diagnostic only when auditing that expert.
|
||||
fixed_diagnostic = raiw.detect_synthid("native-period.png", register_scale=False)
|
||||
```
|
||||
|
||||
The detector is positive-only and covers one measured periodic carrier family
|
||||
This is experimental and is not a watermark detector. Signed provenance through
|
||||
`identify` is the supported SynthID route. Its statistic is destroyed by a seven-pixel
|
||||
crop while the published SynthID evaluation survives aggressive crop and
|
||||
resize, so a positive identifies the generation pipeline. The result exposes
|
||||
`identifies_watermark` and `tile_aligned_crop_required` so a caller cannot
|
||||
reach the wrong conclusion from `status` alone. It is positive-only and covers
|
||||
one measured periodic lattice family
|
||||
in the [calibrated image-size range](synthid.md#32-how-our-tool-detects-the-supported-carrier).
|
||||
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.
|
||||
The default and `identify` use registered-v3 over 250,000 through 10,000,000
|
||||
decoded pixels, with both sides at least 256 pixels. An opponent-registered-v1
|
||||
fallback covers 1 through 10 megapixels, sides of at least 768 pixels, and
|
||||
periods 7.9 through 12.0; period-8 candidates also require the opponent-color
|
||||
block-edge codec veto. Large-v1 covers 10 through 18 megapixels. Each score
|
||||
uses a threshold of `1.0`; registered-v3 also requires independent split-patch
|
||||
confirmation. The fallback is qualified for measured lossless 0.5x-0.75x
|
||||
views, not lossy retranscodes.
|
||||
`register_scale=True` forces the registered-v3 cascade, including its bounded
|
||||
opponent fallback, while `False` explicitly selects the legacy native-period
|
||||
fixed-v2 diagnostic below the large-image boundary.
|
||||
`indeterminate` means only that the selected local model did not find its
|
||||
carrier; `unsupported` means no local expert covers the input geometry. Neither
|
||||
is proof that the image contains no SynthID watermark.
|
||||
Both local and official OpenAI JSON results expose `signal_family`,
|
||||
`provider_scope`, `backend`, `metadata_used_for_verdict`, and
|
||||
`pixels_preserved`; the local result adds `identifies_watermark` and
|
||||
`tile_aligned_crop_required`, so callers do not need to infer the evidence boundary from
|
||||
the detector name.
|
||||
|
||||
Remote transport and response failures raise `OpenAIProvenanceError`. Its
|
||||
`status_code`, `error_code`, `request_id`, `retry_after`, and `retryable`
|
||||
attributes let a caller implement bounded backoff or a circuit breaker without
|
||||
turning an API outage into a false `not_detected` result. One function call still
|
||||
performs at most one upload.
|
||||
|
||||
## Remove visible marks
|
||||
|
||||
@@ -330,8 +352,9 @@ Timings and spatial artifacts are opt-in. Artifacts include image-identifying da
|
||||
such as a thumbnail and perceptual hash; aggregate feature families do not.
|
||||
|
||||
`identify_from_evidence` does not reopen the source file by default: it evaluates
|
||||
metadata only, and registered visible marks and pixel-backed invisible watermarks
|
||||
remain in the path-based `identify` call.
|
||||
metadata only, and the pixel-backed checks remain in the path-based `identify`
|
||||
call: registered visible marks, open invisible-watermark decoders, and the
|
||||
experimental generation-pipeline lattice signal.
|
||||
|
||||
Pass `image_path` together with `check_visible` or `check_invisible` to add those
|
||||
pixel detectors on top of the SAME evidence. That is how a caller asking one file
|
||||
|
||||
Reference in New Issue
Block a user