Skip to content

Repository files navigation

AI-Image Detectors

This repo now contains two detectors:

  1. ai_detector/ — learned, generator-agnostic (recommended). A CLIP + linear probe that answers "is this AI-generated?" for one image and generalizes to generators it never saw (held-out AUC ~0.99). See ai_detector/README.md.
  2. detect.py — watermark-template matcher (research/broken). The original idea below. It does not work on new images — keep reading.

⚠️ The watermark-template detector does not generalize

Validation (leave-one-out and a 110-image held-out test) showed detect.py only scores high on the exact images used to build each template — self-correlation. On a new AI image it returns ~0, the same as a real photo: it detected 0 of 33 held-out AI images. The high scores in the demo come entirely from testing on the template's own training images. Use ai_detector/ for real detection, or Google's SynthID Detector / OpenAI Verify for authoritative watermark reads.


Watermark-template detector (detect.py) — original design

Detects invisible watermarks in AI-generated images from:

  • Google Gemini Nano Banana Pro (SynthID)
  • Google Gemini Nano Banana 2 (SynthID)
  • OpenAI GPT-Image2

Does NOT rely on metadata or EXIF — works on screenshots, re-saved images, and images with stripped metadata. Caveat (measured): only matches images already in its templates; see the notice above.

Model coverage (as of July 2026)

Watermark keys change with model releases, so each template only matches the model version it was built from.

Even for the models below, "covered" only means the template was built from that model — it does not mean new images are detected (see the ⚠️ notice above; the method fails held-out). Templates were built May 2026.

Model API ID Template built from it?
Nano Banana Pro gemini-3-pro-image yes (but no held-out detection)
Nano Banana 2 gemini-3.1-flash-image yes (but no held-out detection)
GPT-Image2 gpt-image-2 yes, pre–May 19 2026 images (OpenAI added SynthID + C2PA after)
Nano Banana 2 Lite gemini-3.1-flash-lite-image no (released June 30, 2026)
Nano Banana (legacy) gemini-2.5-flash-image no

How it works

Each AI image model embeds a fixed noise-level watermark pattern in every generated image. This pattern is imperceptible to humans but statistically consistent across all images from the same model.

  1. Build phase: Average the noise residuals of many AI-generated images from the same source. Random content cancels out; the fixed watermark signal reinforces.
  2. Detect phase: Extract noise residual from a test image (subtract Gaussian-denoised version), then compute normalized correlation with known templates. High correlation = watermark present.

Based on research from reverse-SynthID.

Setup

pip install -r requirements.txt

Usage

Step 1: Build templates (one-time)

You need 10+ images per AI source. More images = better template.

python detect.py build \
  --synthid path/to/nano_banana_pro_images/ \
  --gptimage path/to/gpt_image2_images/ \
  --nb2 path/to/nano_banana_2_images/

Step 2: Detect watermarks

# Basic detection
python detect.py check image.jpg

# Verbose output with all scores
python detect.py check -v image.jpg

# Multiple images
python detect.py check -v img1.png img2.jpg img3.webp

# JSON output
python detect.py check --json image.jpg

# Custom threshold (default: 0.08)
python detect.py check -t 0.05 image.jpg

Output

image.jpg: WATERMARK DETECTED - synthid (score=0.283)
photo.png: no watermark detected

Exit codes:

  • 0 — no watermark detected
  • 1 — file error
  • 2 — SynthID detected (Nano Banana Pro)
  • 3 — GPT-Image2 detected
  • 4 — Nano Banana 2 detected

Performance

  • ~46ms per image (CPU only, no GPU needed)
  • Tested accuracy: AI images score 0.15-0.55, real photos score < 0.01
  • Dependencies: numpy, Pillow, scipy

Robustness

Transformation Survives?
JPEG compression Yes
Resize Yes (resized to 512x512 internally)
Screenshot (no crop) Yes
Format conversion Yes
Metadata stripping Yes
Crop No
Rotation No

Limitations

  • Not 100% accurate — false negatives can occur on heavily compressed images.
  • Heavy JPEG compression kills the watermark — if the image file is unusually small (e.g. 35KB for a 1024x1024 image), the watermark signal may be too degraded to detect. Check the file size before trusting a "no watermark" result.
  • Only detects covered model versions — each AI model version uses a different watermark key. Templates built from May 2026 images only work for those versions. Older Nano Banana versions (original, 1.5, early Pro) and newer models like Nano Banana 2 Lite (released June 30, 2026) will NOT be detected. See the coverage table above.
  • GPT-Image2 changed after templates were built — on May 19, 2026 OpenAI started embedding Google SynthID + C2PA manifests in every ChatGPT/API image. The gptimage2 template was built from earlier images; detection of post-change images is unverified.
  • Third-party platforms may strip watermarks — images generated via API proxies or shared through social platforms (QQ, WeChat, Twitter, etc.) may have their watermark destroyed by re-processing, re-compression, or resizing.
  • Requires 10+ reference images per AI source to build templates
  • Different model versions may need separate templates
  • Template quality improves with more reference images (50+ ideal)
  • Threshold may need tuning per deployment

Updating templates

Templates go stale whenever a model version ships with a new watermark key. To refresh or add coverage:

  1. Collect 10+ reference images from the target model. Options:
    • python gen_reference.py --model gemini-3.1-flash-lite-image --outdir refs/nb2lite --count 16 — requires a billed Gemini API key in GOOGLE_API_KEY (the free tier has zero quota for image-generation models)
    • Download full-resolution originals from a model-labeled gallery (e.g. opennana.com — the source of the current templates)
  2. Build the template: python detect.py build --source nb2lite=refs/nb2lite (the --source NAME=FOLDER flag accepts any new model name; repeatable)
  3. Export for the web UI: python export_web.py (regenerates docs/*.bin + docs/templates.json)
  4. Validate: held-out images from the same model should score > 0.1; real photos and other models' images should stay < 0.02

Official verification tools

For authoritative checks, prefer the vendors' own detectors — they read the actual watermark payload rather than a statistical fingerprint:

  • Google SynthID Detector — portal for images/audio/video/text (early access via waitlist); SynthID verification is also built into the Gemini app, Chrome, and Google Search
  • OpenAI Verify — checks C2PA manifests and SynthID watermarks in OpenAI-generated images (all OpenAI images carry both since May 19, 2026)

This tool remains useful for batch/offline checking, when those services are unavailable, and for images whose metadata was stripped.

Disclaimer

This is an experimental research tool. It should NOT be used as the sole basis for legal decisions, journalism fact-checking, or content moderation. False positives and false negatives can occur. Always verify results with multiple methods.

TODO

  • Build a Nano Banana 2 Lite template (blocked: needs a billed Gemini API key, or a Lite-labeled image source — opennana.com has no Lite category yet)
  • Re-validate the gptimage2 template against post–May 19, 2026 GPT-Image2 outputs (OpenAI added SynthID + C2PA)
  • Build stronger templates with 200+ images per model (currently 12-14)
  • Test against 50+ diverse real photos (phone cameras, DSLR, memes, screenshots) to validate false positive rate
  • Evaluate other generators for fixed watermark patterns (Grok Imagine, Seedance 2.0, Kakao — the latter adopted SynthID in 2026)
  • Investigate frequency-domain carrier detection for crop robustness

Files

  • detect.py — main detector (build + check)
  • gen_reference.py — generate reference images via the Gemini API (for template building)
  • export_web.py — export templates/*.npy to the web UI format in docs/
  • templates/ — extracted watermark templates (.npy files)
  • docs/ — client-side web UI (GitHub Pages) with quantized templates
  • requirements.txt — Python dependencies
  • gemini-synthid.jpg — reference fingerprint visualization
  • gptimage2-fingerprint.jpg — reference fingerprint visualization

About

Detect invisible watermarks in AI-generated images (SynthID, GPT-Image2, Nano Banana). Runs in browser.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages