Restructure documentation, validate metadata removal, consolidate assets
No files matched your search
@@ -0,0 +1,38 @@
|
||||
# Repository data
|
||||
|
||||
Tracked data is organized by purpose:
|
||||
|
||||
```text
|
||||
data/
|
||||
fixtures/
|
||||
provenance/ Real format and provenance fixtures used by tests
|
||||
calibration/
|
||||
<vendor>/ Minimal controlled inputs needed to rebuild detector assets
|
||||
synthid/
|
||||
originals/ Canonical provider-oracle fixtures, stored once
|
||||
manifest.csv Provenance and verification record for each original
|
||||
full-pipeline-quality.csv
|
||||
Reusable full-pipeline evaluation selection
|
||||
evaluations/
|
||||
fidelity/ Evaluation instructions and hand-verified ground truth
|
||||
```
|
||||
|
||||
## Storage rules
|
||||
|
||||
1. Store each binary image once. Evaluation manifests and documentation point
|
||||
to its canonical location.
|
||||
2. Put executable test fixtures in `fixtures/`.
|
||||
3. Put only the minimal reproducible detector inputs in `calibration/`.
|
||||
4. Put externally verified SynthID originals in `synthid/originals/` and keep
|
||||
both CSV files synchronized.
|
||||
5. Keep evaluation outputs outside the repository. Record reproducible
|
||||
commands, hashes, and oracle verdicts instead of committing another corpus
|
||||
copy. A small curated before-and-after example may live in `docs/images/`
|
||||
when it is part of the public documentation.
|
||||
6. Runtime detector assets belong in `src/remove_ai_watermarks/assets/`.
|
||||
Unregistered research candidates belong in
|
||||
`scripts/assets/visible-mark-candidates/` so they are not shipped in the
|
||||
wheel.
|
||||
|
||||
The source distribution excludes `data/`; the wheel contains only package
|
||||
runtime assets.
|
||||
@@ -1,17 +1,17 @@
|
||||
# Doubao visible watermark capture
|
||||
|
||||
> **Status (captured 2026-05-29; alpha rebuilt 2026-05-31):** the black/gray/white captures were
|
||||
> taken and are now **committed** in `captures/` (solid colour + watermark, content-free). The alpha
|
||||
> map is rebuilt by `scripts/visible_alpha_solve.py doubao` (the careful gray-self solve shared with
|
||||
> Jimeng). The first build claimed "pixel-exact" but left a readable outline on the real sample (issue
|
||||
> #13 follow-up); removal now reverse-alphas, NCC-aligns, and applies a thin residual inpaint. See the
|
||||
> `doubao_engine.py` notes in the root `CLAUDE.md`. The text below is kept as the historical capture plan.
|
||||
> **Status (captured 2026-05-29; asset rebuilt 2026-05-31):** the
|
||||
> black and gray captures are committed here. The generated alpha
|
||||
> asset is now a detection silhouette and mask-shaping input only. Current
|
||||
> removal localizes the mark and sends its footprint to the shared fill backend.
|
||||
> Reverse-alpha recovery was retired. The details below preserve the historical
|
||||
> capture rationale.
|
||||
|
||||
Goal: capture the Doubao "豆包AI生成" visible watermark over known flat backgrounds so we can
|
||||
build a per-pixel alpha map and a reverse-alpha-blend remover, the same way the Gemini sparkle
|
||||
engine works (`src/remove_ai_watermarks/gemini_engine.py`).
|
||||
rebuild and validate the detection silhouette used by
|
||||
`src/remove_ai_watermarks/doubao_engine.py`.
|
||||
|
||||
## What we already know (verified from prior art, 2026-05-26)
|
||||
## Historical findings from the capture work
|
||||
|
||||
- Blend model: **alpha compositing with a white logo** `watermarked = a*logo + (1-a)*original`,
|
||||
`logo = (255,255,255)`. Inversion: `original = (watermarked - a*logo) / (1-a)`.
|
||||
@@ -19,14 +19,13 @@ engine works (`src/remove_ai_watermarks/gemini_engine.py`).
|
||||
both say "alpha map"). One commercial blog (pixelcleanai) claims "screen blend" instead; the gray
|
||||
capture below settles it empirically.
|
||||
- Position: **bottom-right corner**, small margins (right ~8-20px, bottom ~5px), scales with image size.
|
||||
Confirmed by our sample `data/samples/doubao-1.png` (2048x2048) plus three sources.
|
||||
Confirmed by our sample `data/fixtures/provenance/doubao-1.png` (2048x2048) plus three sources.
|
||||
- Size **scales with resolution**. Third-party numbers (~90x18 at <=1024, ~180x40 at >1024) are
|
||||
approximate and calibrated for ~1024-1280 outputs; at 2048 the strip is much larger. A shipped
|
||||
third-party alpha map is only 120x20, too small for our 2K/4K target -> capture fresh.
|
||||
- The planning assumption was that clean inversion leaves residue on textured backgrounds, so the
|
||||
remover would pair the alpha map with inpainting. After the capture this turned out unnecessary at
|
||||
the native width (recovery is pixel-exact there and inpaint is off); the shipped remover is
|
||||
reverse-alpha only, with a residual inpaint applied off-native only.
|
||||
- The original implementation used reverse-alpha recovery. That path was later
|
||||
removed in favor of localize then fill because the latter also handles moved
|
||||
and re-rendered marks.
|
||||
|
||||
## Use doubao.com specifically
|
||||
|
||||
@@ -35,7 +34,7 @@ the captured template matches our target.
|
||||
|
||||
## How to capture (image-edit path, most reliable)
|
||||
|
||||
For each seed in `seeds/`:
|
||||
For each locally generated solid-color seed:
|
||||
|
||||
1. Open Doubao image generation, use the image-edit / reference mode, upload the seed.
|
||||
2. Prompt (Chinese preferred):
|
||||
@@ -70,16 +69,15 @@ extracted by per-pixel min/median.
|
||||
- Original download, never a screenshot. PNG preferred; if Doubao only gives JPEG, note it.
|
||||
- No crop / edit / re-save. Default settings, watermark left ON.
|
||||
|
||||
## Naming, drop into `captures/`
|
||||
## Committed inputs
|
||||
|
||||
```
|
||||
doubao_black_1x1_1.png
|
||||
doubao_white_1x1_1.png
|
||||
doubao_gray128_1x1_1.png
|
||||
doubao_black_16x9_1.png
|
||||
doubao_content_1x1_1.png
|
||||
doubao_gray_1x1_1.png
|
||||
```
|
||||
|
||||
The black and gray captures feed `scripts/visible_alpha_solve.py doubao`.
|
||||
|
||||
## Also report back
|
||||
|
||||
1. Which resolutions and aspect ratios the Doubao UI actually offers.
|
||||
@@ -1,8 +1,10 @@
|
||||
# Gemini (Nano Banana) visible sparkle capture
|
||||
|
||||
> **Status (captured 2026-05-31):** black/gray/white captures taken and **committed**
|
||||
> in `captures/` (solid colour + the sparkle, content-free). The sparkle-on-black assets
|
||||
> **Status (captured 2026-05-31):** the required black capture is committed
|
||||
> here. The sparkle-on-black assets
|
||||
> `gemini_bg_{96,48}.png` are rebuilt by `scripts/visible_alpha_solve.py gemini`.
|
||||
> They support detection and footprint geometry. Current pixel recovery uses the
|
||||
> shared fill backend, not reverse-alpha inversion.
|
||||
|
||||
Google Gemini (Nano Banana) stamps a four-point sparkle icon in the bottom-right corner
|
||||
via alpha compositing: `watermarked = a*logo + (1-a)*original`. Unlike the Doubao/Jimeng
|
||||
@@ -20,7 +22,7 @@ text marks, the sparkle is captured over a **pure-black** background, where
|
||||
|
||||
## How to capture (image-edit path)
|
||||
|
||||
For each solid-colour seed (`seeds/seed_{black,gray,white}_2048.png`, gitignored):
|
||||
For each locally generated black, gray, or white 2048 px seed:
|
||||
|
||||
1. Open Gemini image generation, image-edit / reference mode, upload the seed.
|
||||
2. Prompt: `Recreate this image exactly as it is, keep it identical, do not add or change anything`
|
||||
@@ -28,16 +30,15 @@ For each solid-colour seed (`seeds/seed_{black,gray,white}_2048.png`, gitignored
|
||||
|
||||
Black is the key one (sparkle on black -> exact alpha). Gray/white cross-check.
|
||||
|
||||
## Naming, drop into `captures/`
|
||||
## Committed input
|
||||
|
||||
```
|
||||
gemini_black_2048.png # the key capture (sparkle on black)
|
||||
gemini_gray_2048.png
|
||||
gemini_white_2048.png
|
||||
```
|
||||
|
||||
The solid captures are **committed** (content-free). The synthetic `seeds/` and any
|
||||
real-content `gemini_content_*.png` validation download are gitignored (local-only).
|
||||
The gray and white captures were calibration cross-checks and are not needed to
|
||||
rebuild the assets. Synthetic seeds and real-content validation downloads stay
|
||||
local.
|
||||
Rebuild the assets with:
|
||||
|
||||
```
|
||||
@@ -1,15 +1,13 @@
|
||||
# Jimeng (即梦AI) visible watermark capture
|
||||
|
||||
> **Status (completed 2026-05-30):** solid black/gray/white Jimeng captures were
|
||||
> obtained (issue #13, from @powersee) and the alpha map was solved. Removal is
|
||||
> reverse-alpha plus a residual inpaint over the glyph footprint; see the
|
||||
> `jimeng_engine.py` notes in the root `CLAUDE.md`. The text below is kept as the
|
||||
> capture plan.
|
||||
> **Status (completed 2026-05-30):** solid black and gray Jimeng captures were
|
||||
> obtained and the detection asset was solved. The asset now supports detection
|
||||
> and mask geometry only. Current removal localizes the wordmark and uses the
|
||||
> shared fill backend. The text below records the capture and calibration work.
|
||||
|
||||
Goal: capture the Jimeng / Dreamina "★ 即梦AI" visible wordmark over known flat
|
||||
backgrounds so we can build a per-pixel alpha map and a reverse-alpha remover, the
|
||||
same way the Gemini sparkle and Doubao strip engines work
|
||||
(`src/remove_ai_watermarks/gemini_engine.py`, `doubao_engine.py`).
|
||||
backgrounds so we can rebuild and validate the silhouette used by
|
||||
`src/remove_ai_watermarks/jimeng_engine.py`.
|
||||
|
||||
## What we learned (verified from the captures, 2026-05-30)
|
||||
|
||||
@@ -32,11 +30,10 @@ same way the Gemini sparkle and Doubao strip engines work
|
||||
width; a real 1440-wide download matched width_frac ~0.21.
|
||||
- **Per-image render variation:** the alpha maps solved independently from the
|
||||
black and the gray capture correlate 0.998 but not 1.0 (mean |Δa| ~0.02). Jimeng
|
||||
re-rasterizes the mark per generation AND jitters its position a few px, so a
|
||||
single alpha map does NOT pixel-cancel the mark the way Doubao's deterministic
|
||||
overlay does. Removal therefore: NCC-aligns the alpha to the actual mark (always,
|
||||
not only off-native), reverse-alphas, then clears the residual with a THIN inpaint
|
||||
over the glyph footprint (a wide full-footprint pass smeared the texture/edges).
|
||||
re-rasterizes the mark per generation and jitters its position a few pixels.
|
||||
This was one reason the old reverse-alpha path needed alignment and residual
|
||||
inpainting. The current path instead detects the silhouette, localizes the
|
||||
glyph footprint, and fills that footprint.
|
||||
|
||||
## How to capture (image-edit path, most reliable)
|
||||
|
||||
@@ -56,19 +53,15 @@ pure white (the mark is nearly invisible on white, as expected).
|
||||
- Original download, never a screenshot. PNG preferred; if Jimeng only gives JPEG, note it.
|
||||
- No crop / edit / re-save. Default settings, watermark left ON.
|
||||
|
||||
## Naming, drop into `captures/`
|
||||
## Committed inputs
|
||||
|
||||
```
|
||||
jimeng_cap_A.png # black seed run through Jimeng
|
||||
jimeng_cap_B.png # white seed
|
||||
jimeng_cap_C.png # gray seed
|
||||
jimeng_content_1.png # a normal-content download, for end-to-end validation
|
||||
```
|
||||
|
||||
The solid `jimeng_cap_{A,B,C}.png` captures are **committed** (content-free: a solid
|
||||
colour + the watermark; the source for `scripts/visible_alpha_solve.py jimeng`). The
|
||||
synthetic `seeds/` and the real-content `jimeng_content_*.png` validation download are
|
||||
gitignored (local-only). Rebuild the alpha asset with:
|
||||
The A and C captures feed
|
||||
`scripts/visible_alpha_solve.py jimeng`. Rebuild the detection asset with:
|
||||
|
||||
```
|
||||
uv run python scripts/visible_alpha_solve.py jimeng # or: all
|
||||
@@ -1,15 +1,14 @@
|
||||
# Samsung Galaxy AI visible watermark capture
|
||||
|
||||
> **Status (built 2026-06-05):** flat black/gray/white Samsung Galaxy AI captures
|
||||
> were obtained (issue #37, from @f-liva) and the alpha map was solved. Removal is
|
||||
> reverse-alpha plus a thin residual inpaint over the glyph footprint; see the
|
||||
> `samsung_engine.py` notes in the root `CLAUDE.md`. The text below is the capture
|
||||
> plan and the open quality follow-up.
|
||||
> **Status (built 2026-06-05):** flat black and gray Samsung Galaxy AI captures
|
||||
> were obtained and the detection asset was solved. The asset now supports
|
||||
> detection and mask geometry only. Current removal localizes the wordmark and
|
||||
> uses the shared fill backend. The text below records the capture plan and its
|
||||
> locale and resolution limits.
|
||||
|
||||
Goal: capture the Samsung Galaxy AI "✦ Contenuti generati dall'AI" visible wordmark
|
||||
over known flat backgrounds so we can build a per-pixel alpha map and a reverse-alpha
|
||||
remover, the same way the Gemini sparkle and the Doubao / Jimeng strips work
|
||||
(`src/remove_ai_watermarks/gemini_engine.py`, `doubao_engine.py`, `jimeng_engine.py`).
|
||||
over known flat backgrounds so we can rebuild and validate the silhouette used
|
||||
by `src/remove_ai_watermarks/samsung_engine.py`.
|
||||
|
||||
## What we learned (verified from the captures, 2026-06-05)
|
||||
|
||||
@@ -51,15 +50,11 @@ On a Samsung Galaxy AI device (set the UI language to the target locale):
|
||||
|
||||
## Files
|
||||
|
||||
- `captures/samsung_black_1.png`, `samsung_gray_1.png`, `samsung_white_1.png` --
|
||||
portrait flat edits (1086 wide), the primary calibration set.
|
||||
- `captures/samsung_black_2.png`, `samsung_gray_2.png`, `samsung_white_2.png` --
|
||||
a second (landscape 1920) set.
|
||||
- `captures/samsung_content_*` -- real-photo validation downloads, **gitignored**
|
||||
(user content, repo is public).
|
||||
- `seeds/` -- synthetic solid-color inputs, gitignored (regenerable).
|
||||
- `samsung_black_1.png` and `samsung_gray_1.png` are the retained solver inputs.
|
||||
- White, secondary-resolution, and real-content captures were validation
|
||||
material and are not required to rebuild the asset.
|
||||
|
||||
Rebuild the alpha asset with:
|
||||
Rebuild the detection asset with:
|
||||
|
||||
```
|
||||
uv run python scripts/visible_alpha_solve.py samsung
|
||||
|
Before Width: | Height: | Size: 1.2 MiB |
@@ -0,0 +1,37 @@
|
||||
# Pipeline fidelity evaluation
|
||||
|
||||
This evaluation compares diffusion pipelines with
|
||||
`scripts/fidelity_metrics.py`. The images themselves have one canonical home
|
||||
in `data/synthid/originals/`; this directory stores only evaluation-specific
|
||||
ground truth and instructions.
|
||||
|
||||
| Original | Provider | Content | Exercises |
|
||||
| --- | --- | --- | --- |
|
||||
| `ChatGPT Image May 31, 2026, 02_03_55 PM.png` | OpenAI | Multilingual typography | Text preservation |
|
||||
| `Gemini_Generated_Image_633uuy633uuy633u.png` | Google | Landscape with a Chinese sign | CJK text preservation |
|
||||
| `Gemini_Generated_Image_y48j3cy48j3cy48j.png` | Google | Portrait grid | Face identity and skin texture |
|
||||
|
||||
## Text ground truth
|
||||
|
||||
`ground-truth.json` contains hand-verified OCR for the two text-bearing
|
||||
originals. To regenerate an OCR seed:
|
||||
|
||||
```bash
|
||||
uv run scripts/fidelity_metrics.py ocr \
|
||||
"data/synthid/originals/ChatGPT Image May 31, 2026, 02_03_55 PM.png" \
|
||||
data/synthid/originals/Gemini_Generated_Image_633uuy633uuy633u.png \
|
||||
--langs en,ru,ch \
|
||||
--out data/evaluations/fidelity/ground-truth.json
|
||||
```
|
||||
|
||||
Verify and correct the generated text by hand before using it as ground truth.
|
||||
|
||||
## Compare
|
||||
|
||||
```bash
|
||||
uv run scripts/fidelity_metrics.py compare \
|
||||
--original data/synthid/originals/Gemini_Generated_Image_y48j3cy48j3cy48j.png \
|
||||
--variant controlnet=<out>.png \
|
||||
--variant qwen=<out>.png \
|
||||
--ocr-langs ""
|
||||
```
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"ChatGPT Image May 31, 2026, 02_03_55 PM.png": "This is a longer sample text in English.\nTypography can flow smoothly from large to medium size.\nSmaller lines help demonstrate hierarchy, rhythm, and clarity.\nEven the finest text should remain clean and readable.\n这是一段较长的中文示例文本。\n排版可以从大字号逐渐过渡到中字号。\n更小的文字能够展示层次、节奏与清晰度。\n即使是最小的一行,也应该保持清楚易读。\nЭто более длинный пример текста на русском языке.\nТипографика может плавно переходить от крупного размера к среднему.\nБолее мелкие строки показывают иерархию, ритм и ясность.\nДаже самый маленький текст должен оставаться чистым и читаемым.",
|
||||
"Gemini_Generated_Image_633uuy633uuy633u.png": "每天都是一个新的机会。\n用微笑开始它。\n世界也会向你微笑。"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 715 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 373 KiB |
@@ -1,35 +0,0 @@
|
||||
# qwen_in — pipeline-fidelity eval set
|
||||
|
||||
A small, **stable** set of AI-generated images used to compare the diffusion
|
||||
removal pipelines (`controlnet` / `sdxl` / `qwen`) for fidelity with
|
||||
`scripts/fidelity_metrics.py`. Fixing the set in the repo keeps comparisons
|
||||
reproducible across runs and pipelines.
|
||||
|
||||
All four are AI-generated test content (they carry SynthID + C2PA from their
|
||||
generator — verify with `remove-ai-watermarks identify`), same class as the
|
||||
`data/samples/` fixtures. No real-person photos.
|
||||
|
||||
| file | vendor (SynthID) | content | exercises |
|
||||
|---|---|---|---|
|
||||
| `openai_1_original.png` | OpenAI | typography sheet (EN + RU + ZH) | text (multi-script) |
|
||||
| `openai_2_original.png` | OpenAI | Raiw.cc poster | text (EN, small) |
|
||||
| `gemini_1_original.png` | Google | landscape + Chinese sign | text (CJK) |
|
||||
| `gemini_3_original.png` | Google | 3x3 portrait grid | faces (identity / skin texture) |
|
||||
|
||||
## Text ground truth
|
||||
|
||||
`ground_truth.json` (`{basename: text}`) is the **hand-verified** OCR of the
|
||||
text-bearing originals, seeded by `fidelity_metrics.py ocr` and corrected by
|
||||
hand (PaddleOCR mis-reads stylized Cyrillic in particular). It is the reference
|
||||
for the text CER metric — much cleaner than OCR-vs-OCR. Regenerate the seed with:
|
||||
|
||||
uv run scripts/fidelity_metrics.py ocr data/qwen_in/openai_1_original.png \
|
||||
data/qwen_in/openai_2_original.png data/qwen_in/gemini_1_original.png \
|
||||
--langs en,ru,ch --out data/qwen_in/ground_truth.json
|
||||
# then re-verify by hand before trusting it.
|
||||
|
||||
## Compare
|
||||
|
||||
uv run scripts/fidelity_metrics.py compare \
|
||||
--original data/qwen_in/gemini_3_original.png \
|
||||
--variant controlnet=<out>.png --variant qwen=<out>.png --ocr-langs ""
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"openai_1_original.png": "This is a longer sample text in English.\nTypography can flow smoothly from large to medium size.\nSmaller lines help demonstrate hierarchy, rhythm, and clarity.\nEven the finest text should remain clean and readable.\n这是一段较长的中文示例文本。\n排版可以从大字号逐渐过渡到中字号。\n更小的文字能够展示层次、节奏与清晰度。\n即使是最小的一行,也应该保持清楚易读。\nЭто более длинный пример текста на русском языке.\nТипографика может плавно переходить от крупного размера к среднему.\nБолее мелкие строки показывают иерархию, ритм и ясность.\nДаже самый маленький текст должен оставаться чистым и читаемым.",
|
||||
"openai_2_original.png": "raiw.cc\nRaiw.cc – The Platform for the Future\nRaiw.cc is a modern project built for those who value quality, innovation, and reliability.\nSecurity & Reliability\nWe use advanced technologies to protect your data and ensure stable service performance.\nInnovation\nWe continuously explore and implement better solutions to help you stay one step ahead.\nCommunity\nRaiw.cc is an active community of like-minded people who share knowledge, experience, and ideas.\nProgress Together\nWhether you're a developer, creator, or dreamer — raiw.cc is your partner in achieving your goals.\nOur mission is to create opportunities and inspire people to reach new heights.\nRaiw.cc\nVisit raiw.cc today\nExplore more possibilities and start your journey to the future!\nGet Started\nSecure\nInnovative\nCommunity\nForward-Thinking\nINNOVATE · CONNECT · CREATE · GROW",
|
||||
"gemini_1_original.png": "每天都是一个新的机会。\n用微笑开始它。\n世界也会向你微笑。"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 1.7 MiB |
@@ -1,41 +0,0 @@
|
||||
# OpenAI ChatGPT Images 2.0 sample
|
||||
|
||||
Reference image generated by OpenAI's ChatGPT Images 2.0 (`gpt-image-2`, launched 2026-04-21). Kept in the repo so the C2PA manifest parser and invisible-watermark pipeline can be re-verified against a real production output.
|
||||
|
||||
## `amur-leopard.png`
|
||||
|
||||
- Resolution: 1055 x 1491, PNG, 3.0 MB
|
||||
- Downloaded: 2026-04-22
|
||||
- Content: AI-generated infographic about the Amur leopard (*Panthera pardus orientalis*), chosen to exercise the model's new accurate-text-rendering feature
|
||||
|
||||
### Embedded C2PA manifest (caBX chunk, 23607 bytes)
|
||||
|
||||
Parsed by `remove-ai-watermarks metadata --check`:
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| `claim_generator` | GPT-4o |
|
||||
| `c2pa_spec` | 2.2.0 |
|
||||
| `digital_source_type` | http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia |
|
||||
| `c2pa_actions` | created, converted |
|
||||
| Signer | OpenAI OpCo, LLC / OpenAI Media Service API |
|
||||
| Claim signing CA | Trufo C2PA Claim Signing CA (2025) -> Trufo C2PA Root CA (ECC P384) |
|
||||
| Timestamp authority | OpenAI TSA Issuing CA -> OpenAI TSA Root CA |
|
||||
|
||||
The `trainedAlgorithmicMedia` tag is what triggers "Made with AI" labels on Instagram, Facebook, and X.
|
||||
|
||||
### Invisible pixel-level watermark
|
||||
|
||||
OpenAI's system card for Images 2.0 states the model embeds an "imperceptible, robust, and content-specific" pixel-level watermark alongside C2PA. This sample was downloaded 2026-04-22, before OpenAI's 19 May 2026 rollout of Google's SynthID watermark across ChatGPT / Codex / the API, so it likely predates SynthID and carries only the original content-specific watermark. Since that rollout, the openai.com/verify tool (in preview) is the public oracle for both signals; there is still no local decoder, so bypass cannot be verified empirically here without the oracle.
|
||||
|
||||
## Reproducing the removal
|
||||
|
||||
```bash
|
||||
# C2PA strip only
|
||||
remove-ai-watermarks metadata amur-leopard.png --remove -o amur-leopard.clean.png
|
||||
|
||||
# Full pipeline (visible + diffusion regeneration + metadata)
|
||||
remove-ai-watermarks all amur-leopard.png -o amur-leopard.all.png --device mps
|
||||
```
|
||||
|
||||
Note: the diffusion step runs at native resolution by default (no pre-downscale), so fine text on a text-heavy infographic like this one is preserved. Pass `--max-resolution N` only if a very large image OOMs the GPU/MPS (that reintroduces a lossy downscale then upscale round-trip).
|
||||
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 317 KiB |
|
Before Width: | Height: | Size: 425 KiB |
|
Before Width: | Height: | Size: 815 KiB |
|
Before Width: | Height: | Size: 314 KiB |
@@ -1,11 +1,10 @@
|
||||
# SynthID reference corpus
|
||||
# SynthID oracle fixtures
|
||||
|
||||
A locally-collected, labeled image corpus for SynthID work. Two downstream uses:
|
||||
A compact set of externally verified originals for two uses:
|
||||
|
||||
1. **Per-resolution spectral codebook** for an experimental SynthID detector
|
||||
(carrier frequencies are resolution-dependent, so labels must record the
|
||||
exact native resolution).
|
||||
2. **Removal regression set** — verify that our pipeline turns a SynthID-positive
|
||||
1. **Signal and detector-limit research** with exact native resolutions and
|
||||
recorded verification sources.
|
||||
2. **Removal regression set**: verify that a pipeline turns a SynthID-positive
|
||||
image into a negative one.
|
||||
|
||||
There is no reliable local detector of the SynthID pixel watermark (Google's
|
||||
@@ -15,35 +14,29 @@ external oracle, recorded per image in `verified_via` (see below).
|
||||
## Layout
|
||||
|
||||
```
|
||||
data/synthid_corpus/
|
||||
README.md # this protocol (committed)
|
||||
manifest.csv # labels + provenance (committed; one row per tracked image)
|
||||
quality_sets/ # reusable test-suite manifests over corpus images
|
||||
images/ # the labeled corpus (committed)
|
||||
pos/ # SynthID present
|
||||
neg/ # SynthID absent (incl. reviewed real photos)
|
||||
cleaned/ # our pipeline output from a pos image
|
||||
refs/ # synthetic black/white calibration fills (gitignored, regenerable)
|
||||
data/synthid/
|
||||
README.md # collection and verification protocol
|
||||
manifest.csv # one row per committed original
|
||||
full-pipeline-quality.csv # reusable evaluation selection
|
||||
originals/ # one canonical copy of each verified source
|
||||
```
|
||||
|
||||
The labeled images are committed so the corpus is reproducible and the removal
|
||||
regression set runs in CI. `manifest.csv` is kept in sync with the files on
|
||||
disk (one row per tracked image; dangling rows are pruned when files are
|
||||
removed). Before adding any image, confirm it carries no private or
|
||||
identifiable content you would not publish -- this is a public repo and git
|
||||
history is permanent. The synthetic `refs/` fills stay gitignored (regenerable,
|
||||
not part of the labeled set).
|
||||
The originals are committed so the evaluation set is reproducible and its
|
||||
hashes can be checked in CI. `manifest.csv` is kept in sync with
|
||||
`originals/`, one row per file. Generated outputs do not belong here. Store
|
||||
them outside the repository and record only a reproducible verdict in the
|
||||
evaluation manifest or documentation.
|
||||
|
||||
## Reusable removal-quality set
|
||||
|
||||
`quality_sets/full_pipeline_quality_2026-07-25.csv` is the canonical reusable
|
||||
input set for full-pipeline visual-quality and watermark-removal tests. Its
|
||||
fixtures are cleared for permanent public test reuse. Tests, benchmarks, and
|
||||
manual evaluation bundles may read these images repeatedly without requesting
|
||||
new permission.
|
||||
`full-pipeline-quality.csv` is the canonical reusable input set for
|
||||
full-pipeline visual-quality and watermark-removal tests. Its fixtures are
|
||||
cleared for permanent public test reuse. Tests, benchmarks, and manual
|
||||
evaluation bundles may read these images repeatedly without requesting new
|
||||
permission.
|
||||
|
||||
The CSV preserves each platform's original filename and maps it to the one
|
||||
SHA-256-addressed corpus copy. Use `corpus_path` to read the input, but preserve
|
||||
canonical corpus copy. Use `corpus_path` to read the input, but preserve
|
||||
`source_filename` in generated result names and keep OpenAI and Gemini outputs
|
||||
in separate provider groups. This avoids duplicating large PNGs while retaining
|
||||
the names needed for the corresponding provider oracle.
|
||||
@@ -67,33 +60,25 @@ Ground-truth quality, strongest first:
|
||||
- `third-party` — label asserted by an external dataset, not independently verified.
|
||||
- `none` — unverified.
|
||||
|
||||
Prefer `gemini-app` for any image that will train the codebook or gate a test.
|
||||
Prefer `gemini-app` for any Google image that will gate a test.
|
||||
|
||||
## What to collect
|
||||
|
||||
For the **codebook** (per target resolution, e.g. 1024x1024, 1024x1536, 1536x2816):
|
||||
|
||||
- 30-50+ SynthID-positive outputs per resolution (more is better; ~150-200 per
|
||||
resolution materially improves carrier discovery).
|
||||
- At each target resolution, also a batch of **pure-black (#000000)** and
|
||||
**pure-white (#FFFFFF)** fills generated by the SynthID model — these isolate
|
||||
the content-independent carrier (the watermark is most of the signal there).
|
||||
|
||||
For the **regression set**:
|
||||
|
||||
- A handful of `pos` images, their `cleaned` counterparts (run through our
|
||||
pipeline), and the cleaned re-verified via `gemini-app` (should read negative).
|
||||
- `neg` controls: non-AI photos and outputs from non-SynthID models (SD,
|
||||
Midjourney, Firefly) verified negative.
|
||||
- A small number of positive originals with a recorded provider oracle.
|
||||
- A quality-set row for every original used by repeatable evaluation.
|
||||
- Re-run the provider oracle on each newly generated output. Do not commit the
|
||||
generated output as another corpus copy.
|
||||
|
||||
The corpus is committed to a public repo: review every image before adding it
|
||||
and keep out anything private or identifiable you would not publish.
|
||||
|
||||
## Ingesting
|
||||
|
||||
Use `scripts/synthid_corpus.py` — it copies a file in, records its sha256,
|
||||
resolution, format, and C2PA issuer (via our own detector), and appends a row
|
||||
to `manifest.csv`:
|
||||
Use `scripts/synthid_corpus.py` to copy a file into `originals/`, record its
|
||||
SHA-256, resolution, format, and C2PA issuer through our detector, and append a
|
||||
row to `manifest.csv`:
|
||||
|
||||
```bash
|
||||
uv run python scripts/synthid_corpus.py ingest path/to/*.png \
|
||||
@@ -105,6 +90,10 @@ uv run python scripts/synthid_corpus.py status # counts by label / resolution
|
||||
|
||||
## Autonomous collection via Chrome MCP
|
||||
|
||||
> Historical collection notes. Browser interfaces and download behavior can
|
||||
> change independently of this repository. These steps do not define package
|
||||
> behavior.
|
||||
|
||||
Generation can be driven through the browser (the account must be logged in):
|
||||
|
||||
- **Gemini** (`gemini.google.com`): type `Create an image: <prompt>`, wait, hover the
|
||||
@@ -145,8 +134,8 @@ Download; Leonardo serves the original JPEG in-chat (download button matches).
|
||||
|
||||
## Per-platform watermark map (observed, May 2026)
|
||||
|
||||
What each platform actually embeds, verified by byte-scan (and Gemini-app oracle
|
||||
where noted). The detector's coverage is complementary: metadata catches C2PA /
|
||||
This is a dated observation table, not a live provider compatibility promise.
|
||||
The detector's coverage is complementary: metadata catches C2PA /
|
||||
IPTC; `exif_generator` catches EXIF `Make`/`Software` + XMP `CreatorTool`;
|
||||
`invisible_watermark.py` (imwatermark) catches the open SD/SDXL/FLUX DWT-DCT
|
||||
watermark on pristine files; the visible detector catches the Gemini-family
|
||||
@@ -0,0 +1,8 @@
|
||||
provider,source_filename,corpus_path,sha256,original_signal_verified_via,final_clean_oracle
|
||||
openai,"ChatGPT Image May 30, 2026, 10_31_08 AM.png","originals/ChatGPT Image May 30, 2026, 10_31_08 AM.png",28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0,openai-verify,openai-verify-negative-2026-07-25
|
||||
openai,"ChatGPT Image May 31, 2026, 02_02_23 PM.png","originals/ChatGPT Image May 31, 2026, 02_02_23 PM.png",228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82,c2pa-metadata,not-checked-in-final-candidate
|
||||
openai,"ChatGPT Image May 31, 2026, 02_03_55 PM.png","originals/ChatGPT Image May 31, 2026, 02_03_55 PM.png",05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e,openai-verify,openai-verify-negative-2026-07-25
|
||||
gemini,"Gemini_Generated_Image_3mc4t93mc4t93mc4.png","originals/Gemini_Generated_Image_3mc4t93mc4t93mc4.png",2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856,gemini-app,gemini-app-negative-2026-07-25
|
||||
gemini,"Gemini_Generated_Image_633uuy633uuy633u.png","originals/Gemini_Generated_Image_633uuy633uuy633u.png",4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236,gemini-app,gemini-app-negative-2026-07-25
|
||||
gemini,"Gemini_Generated_Image_akdbeiakdbeiakdb.png","originals/Gemini_Generated_Image_akdbeiakdbeiakdb.png",8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e,gemini-app,gemini-app-negative-2026-07-25
|
||||
gemini,"Gemini_Generated_Image_y48j3cy48j3cy48j.png","originals/Gemini_Generated_Image_y48j3cy48j3cy48j.png",45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b,gemini-app,gemini-app-negative-2026-07-25
|
||||
|
@@ -0,0 +1,8 @@
|
||||
sha256,filename,label,source,model,width,height,format,c2pa_issuer,synthid_metadata,verified_via,added,notes
|
||||
05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e,"ChatGPT Image May 31, 2026, 02_03_55 PM.png",pos,ChatGPT,gpt-image,1122,1402,png,OpenAI,yes,openai-verify,2026-06-04T00:07:53Z,June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
|
||||
28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0,"ChatGPT Image May 30, 2026, 10_31_08 AM.png",pos,ChatGPT,gpt-image,1448,1086,png,OpenAI,yes,openai-verify,2026-06-04T00:07:53Z,June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
|
||||
4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236,Gemini_Generated_Image_633uuy633uuy633u.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
|
||||
8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e,Gemini_Generated_Image_akdbeiakdbeiakdb.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
|
||||
45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b,Gemini_Generated_Image_y48j3cy48j3cy48j.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
|
||||
2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856,Gemini_Generated_Image_3mc4t93mc4t93mc4.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
|
||||
228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82,"ChatGPT Image May 31, 2026, 02_02_23 PM.png",pos,ChatGPT,gpt-image,1122,1402,png,OpenAI,yes,c2pa-metadata,2026-07-25T20:21:33Z,Reusable full-pipeline quality fixture; original filename preserved in quality-set manifest; cleared for public test reuse
|
||||
|
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 7.6 MiB |
|
Before Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 7.3 MiB |
|
Before Width: | Height: | Size: 8.5 MiB |
|
Before Width: | Height: | Size: 2.7 MiB |
|
Before Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 7.1 MiB |
|
Before Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 2.7 MiB |
|
Before Width: | Height: | Size: 9.3 MiB |
|
Before Width: | Height: | Size: 8.2 MiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 3.1 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 8.3 MiB |
|
Before Width: | Height: | Size: 7.8 MiB |
|
Before Width: | Height: | Size: 8.6 MiB |
@@ -1,41 +0,0 @@
|
||||
sha256,filename,label,source,model,width,height,format,c2pa_issuer,synthid_metadata,verified_via,added,notes
|
||||
4ef377bde1a1d4eff141972841938643b173f5052992a018b9a21b31ac31731e,"4ef377bd-ChatGPT Image May 23, 2026, 02_43_02 PM.png",pos,ChatGPT,gpt-image,1254,1254,png,OpenAI,yes,openai-verify,2026-05-23T21:48:12Z,fresh post-rollout 2026-05-23; openai.com/verify: SynthID+C2PA detected
|
||||
d09f84c0e4c6d8b336bf4a9a7277314e940dcb5052ae7051e785cbb3bb42d656,d09f84c0-Gemini_Generated_Image_vq7wkwvq7wkwvq7w.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,c2pa-metadata,2026-05-23T21:52:40Z,"user: latest Gemini, SynthID v2"
|
||||
7b650522d42db09568e249c04d683c469fb3e280a2c53fcd1031cb9df27c619a,"7b650522-ChatGPT Image May 24, 2026, 12_19_54 PM.png",pos,ChatGPT,gpt-image,1602,982,png,OpenAI,yes,c2pa-metadata,2026-05-24T19:20:25Z,content: misty pine forest at dawn
|
||||
fb28dba2a82cc101a92fdee5714867b32610d0564f37737fe4bb70782b8ecf32,fb28dba2-Gemini_Generated_Image_dsjlnsdsjlnsdsjl.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,c2pa-metadata,2026-05-24T19:30:25Z,content: elderly fisherman portrait
|
||||
d20d4cc936dbdfe909c52502039a9e84ba93d97b42b24a0acee5b7d6c71930ae,d20d4cc9-Gemini_Generated_Image_ug6kdpug6kdpug6k.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,c2pa-metadata,2026-05-24T19:33:15Z,content: red coffee mug product shot
|
||||
28f323345f6496d936c3f1a72f671ddf59d0f81565c24a63bf3286860f633afe,28f32334-chatgpt_fisherman.png,pos,ChatGPT,gpt-image,1023,1537,png,OpenAI,yes,c2pa-metadata,2026-05-24T19:39:20Z,content: elderly fisherman portrait (fetch+blob dl)
|
||||
88e61a384c2e0b12d97bc66046e4a10542b2987448ba89c4b49e66311e969c84,88e61a38-chatgpt_tokyo.png,pos,ChatGPT,gpt-image,1023,1537,png,OpenAI,yes,c2pa-metadata,2026-05-24T19:42:02Z,content: tokyo street night (fetch+blob dl)
|
||||
1fa5f77f710c11a4cc69fed60195450def734401ed57c2600a84ce191f985440,1fa5f77f-IMG_0786.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:47Z,post photo; no C2PA/SynthID (verified)
|
||||
2ea228ed270cd169e9d38bc3f1a162de7edbf54b6e5ad3c701a3c90010ec7067,2ea228ed-IMG_1791.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:47Z,post photo; no C2PA/SynthID (verified)
|
||||
0bb4c176d83fbcbf4e628de7587d6183b9134c4f3fa85f55b96e94185273c7f6,0bb4c176-IMG_1790.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:47Z,post photo; no C2PA/SynthID (verified)
|
||||
3fc0c4253f86427777904f41355eacbdcc1a29f6897ec694c7fc68b6e7f70846,3fc0c425-IMG_1450.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
|
||||
2b148db2b1a314a87647a03828b3d235e7c4c939252f448b572b7658c7bb9723,2b148db2-IMG_1832.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
|
||||
2d02fed0b6d60ce1142eadac9837a83896569dddbdad7cc5cfdec018f0506d36,2d02fed0-IMG_1520.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
|
||||
8f170c06f843c2bcf4cf6e249dd76365287fdb3a322637ba93c570f50cb19772,8f170c06-IMG_1078.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
|
||||
3fc4c8316012abc462df5534d4d995e5af84d35076a2927331107ff994293d9e,3fc4c831-IMG_2566.HEIC,neg,iPhone (me/post_photos),,5712,4284,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
|
||||
5fe59521d579b536340253d2bcaa7c28ddd2485fa964fc27a9b9e5118ad0cdd1,5fe59521-IMG_1496.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
|
||||
4ead7918a5aeea7fba78b36af44358fea7ed1db7f46f4bc675152b9d04e68c38,4ead7918-IMG_1300.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
|
||||
4c795238b89178cf52a3674e721ed7f4cd5068028385491d12171a3c62545c35,4c795238-IMG_3034.HEIC,neg,iPhone (me/post_photos),,5712,4284,heic,,,none,2026-05-24T20:58:49Z,post photo; no C2PA/SynthID (verified)
|
||||
5abfaccb37c549de67c7f3a751a528a423e24a82c643fdb29094be8debbb206d,5abfaccb-IMG_3018.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:49Z,post photo; no C2PA/SynthID (verified)
|
||||
5fed1923d513c1e9ffcba2f240e617fa9344fb39d35144169570ece8b0bd0f33,5fed1923-IMG_0272.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:49Z,post photo; no C2PA/SynthID (verified)
|
||||
06b04d8fe8e1cd6bee9a973f93bfda37586924cbfec7d372f59d52aa9196160b,06b04d8f-IMG_1474.HEIC,neg,iPhone (me/post_photos),,5712,4284,heic,,,none,2026-05-24T20:58:49Z,post photo; no C2PA/SynthID (verified)
|
||||
8fdb574a94e65e14ac29017cf2d5a2ede18a8c4e3f12e04c64292b0d38570062,8fdb574a-IMG_3557.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:49Z,post photo; no C2PA/SynthID (verified)
|
||||
c86973424817f62510e2a312b85c52e05adf47ace87a8e717fd442607596f501,c8697342-aistudio_lake.png,pos,Google AI Studio (Nano Banana),gemini-2.5-flash-image,1024,1024,png,,,gemini-app,2026-05-24T21:39:09Z,"API/playground: SynthID pixel CONFIRMED (Gemini-app oracle) + visible sparkle, but NO C2PA/IPTC -> synthid_source blind spot"
|
||||
1f81827c06d67cf6f6c7f5d53ec8f9738183942a6d1d2717b161fea0fdcc540a,1f81827c-Designer.png,pos,Microsoft Designer,dall-e (Designer),1024,1024,png,"OpenAI, Microsoft",yes,c2pa-metadata,2026-05-24T22:18:40Z,C2PA issuer OpenAI+Microsoft; synthid_source=OpenAI (DALL-E surface inherits OpenAI SynthID+C2PA)
|
||||
f6dd47a5ffd319aea21bf10dcf9877097666420b02c2620080bac12b03976e7e,f6dd47a5-4ef377bd-gpt-image-2-cleaned.png,cleaned,"our pipeline (invisible/SDXL, native-res default)",stabilityai/stable-diffusion-xl-base-1.0,1254,1254,png,,,openai-verify,2026-05-25T20:50:38Z,"cleaned from 4ef377bd via v0.5.3 'all' at native 1254x1254 (prod-equivalent); openai.com/verify: SynthID NOT detected. Re-confirms #10 native-res default defeats OpenAI SynthID (closes #15 root cause). Note: native res OOMs on 20GB MPS, auto-fell back to CPU."
|
||||
05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e,05b836ec-openai_1_original.png,pos,ChatGPT,gpt-image,1122,1402,png,OpenAI,yes,openai-verify,2026-06-04T00:07:53Z,June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
|
||||
794e023ea7ae321267fe5af76f4080c98a84a9865669c0733ebfb9757b8638df,794e023e-openai_2_original.png,pos,ChatGPT,gpt-image,1024,1536,png,OpenAI,yes,openai-verify,2026-06-04T00:07:53Z,June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
|
||||
28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0,28ff8732-openai_3_original.png,pos,ChatGPT,gpt-image,1448,1086,png,OpenAI,yes,openai-verify,2026-06-04T00:07:53Z,June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
|
||||
4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236,4affd7f2-gemini_1_original.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
|
||||
8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e,8c1a6fb0-gemini_2_original.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
|
||||
45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b,45d79a68-gemini_3_original.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
|
||||
2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856,2c33e75a-gemini_4_original.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
|
||||
2e4ce41cfab456c1d9ea0898e47a5a1d434266ba24e88d4cc807a4180a56925f,2e4ce41c-openai_1_clean_s005.png,cleaned,"our pipeline (SDXL img2img, native)",stabilityai/stable-diffusion-xl-base-1.0,1122,1402,png,,,openai-verify,2026-06-04T00:08:05Z,cleaned at strength 0.05 native; openai.com/verify: SynthID NOT detected (docs/synthid.md 2.2)
|
||||
f7c52cdfeb14a6be2fff449e89b0181e66e365f36635ee4fcb21567e4cb770ef,f7c52cdf-openai_3_clean_s005.png,cleaned,"our pipeline (SDXL img2img, native)",stabilityai/stable-diffusion-xl-base-1.0,1448,1086,png,,,openai-verify,2026-06-04T00:08:05Z,cleaned at strength 0.05 native; openai.com/verify: SynthID NOT detected (docs/synthid.md 2.2)
|
||||
37b34274210888702e56eb74f4aa36578f15bf57157a3ebf394f0b8eaa820e19,37b34274-openai_2_clean_s010.png,cleaned,"our pipeline (SDXL img2img, native)",stabilityai/stable-diffusion-xl-base-1.0,1024,1536,png,,,openai-verify,2026-06-04T00:08:05Z,cleaned at strength 0.10 native (min captured for this subject); openai.com/verify: SynthID NOT detected
|
||||
f99bd9a51814265a23de467d14792db903fef99678b7e7c960d0c6813ed9b0fc,f99bd9a5-gemini_1_clean_s015_max1536.png,cleaned,"our pipeline (SDXL img2img, --max-resolution 1536)",stabilityai/stable-diffusion-xl-base-1.0,2816,1536,png,,,gemini-app,2026-06-04T00:08:05Z,cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
|
||||
4aa5f61c55c1f3fa9bbc49dffff8a404527722637ae694a932245629635b3f2b,4aa5f61c-gemini_2_clean_s015_max1536.png,cleaned,"our pipeline (SDXL img2img, --max-resolution 1536)",stabilityai/stable-diffusion-xl-base-1.0,2816,1536,png,,,gemini-app,2026-06-04T00:08:05Z,cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
|
||||
356196dd63abf011b30b582a0408ccecb726d746065af20ad3611dde72a88725,356196dd-gemini_3_clean_s015_max1536.png,cleaned,"our pipeline (SDXL img2img, --max-resolution 1536)",stabilityai/stable-diffusion-xl-base-1.0,2816,1536,png,,,gemini-app,2026-06-04T00:08:05Z,cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
|
||||
9e4160bb8e3e915d2d4593e37c71495ee7cfcec183602541166f622ebfd84403,9e4160bb-gemini_4_clean_s015_max1536.png,cleaned,"our pipeline (SDXL img2img, --max-resolution 1536)",stabilityai/stable-diffusion-xl-base-1.0,2816,1536,png,,,gemini-app,2026-06-04T00:08:05Z,cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
|
||||
228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82,"228e5441-ChatGPT Image May 31, 2026, 02_02_23 PM.png",pos,ChatGPT,gpt-image,1122,1402,png,OpenAI,yes,c2pa-metadata,2026-07-25T20:21:33Z,Reusable full-pipeline quality fixture; original filename preserved in quality-set manifest; cleared for public test reuse
|
||||
|
@@ -1,8 +0,0 @@
|
||||
provider,source_filename,corpus_path,sha256,original_signal_verified_via,final_clean_oracle
|
||||
openai,"ChatGPT Image May 30, 2026, 10_31_08 AM.png","images/pos/28ff8732-openai_3_original.png",28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0,openai-verify,openai-verify-negative-2026-07-25
|
||||
openai,"ChatGPT Image May 31, 2026, 02_02_23 PM.png","images/pos/228e5441-ChatGPT Image May 31, 2026, 02_02_23 PM.png",228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82,c2pa-metadata,not-checked-in-final-candidate
|
||||
openai,"ChatGPT Image May 31, 2026, 02_03_55 PM.png","images/pos/05b836ec-openai_1_original.png",05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e,openai-verify,openai-verify-negative-2026-07-25
|
||||
gemini,"Gemini_Generated_Image_3mc4t93mc4t93mc4.png","images/pos/2c33e75a-gemini_4_original.png",2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856,gemini-app,gemini-app-negative-2026-07-25
|
||||
gemini,"Gemini_Generated_Image_633uuy633uuy633u.png","images/pos/4affd7f2-gemini_1_original.png",4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236,gemini-app,gemini-app-negative-2026-07-25
|
||||
gemini,"Gemini_Generated_Image_akdbeiakdbeiakdb.png","images/pos/8c1a6fb0-gemini_2_original.png",8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e,gemini-app,gemini-app-negative-2026-07-25
|
||||
gemini,"Gemini_Generated_Image_y48j3cy48j3cy48j.png","images/pos/45d79a68-gemini_3_original.png",45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b,gemini-app,gemini-app-negative-2026-07-25
|
||||
|