A fast command-line tool that removes visible and invisible watermarks from images and videos generated by Google Gemini, Veo, and NotebookLM. Each download is self-contained and runs on a clean system with nothing to install. macOS builds are Developer ID signed and Apple-notarized, so they pass Gatekeeper with no extra steps.
| Watermark | Found on | Removal method | Status |
|---|---|---|---|
| Gemini sparkle logo | Gemini images | Reverse alpha-blend + AI denoise | ✅ Full |
| Veo video watermark | Veo videos | Per-frame reverse alpha-blend | ✅ Full |
| NotebookLM logo + wordmark | NotebookLM videos | Per-scene AI inpaint (MI-GAN) | ✅ Full |
| SynthID (invisible) | Gemini images | Spectral subtraction |
detect can also locate watermarks (including SynthID) without modifying the file.
Grab a prebuilt binary from the Releases page (no build step). Every package is self-contained (bundles the AI models and any runtime libraries it needs).
| Asset | Platform | Run |
|---|---|---|
wmr-macos-arm64.zip |
macOS 14+ (Apple Silicon) | unzip wmr-macos-arm64.zip && cd wmr-macos-arm64 && ./wmr |
wmr-macos-x86_64.zip |
macOS 14+ (Intel) | unzip wmr-macos-x86_64.zip && cd wmr-macos-x86_64 && ./wmr |
wmr-linux-x86_64.tar.gz |
Linux | tar xzf wmr-linux-x86_64.tar.gz && cd wmr-linux-x86_64 && ./wmr |
wmr-windows-x86_64.zip |
Windows | extract, run wmr.exe |
- macOS ships native CoreML MI-GAN (Neural Engine, ~28 ms/frame). macOS 14+ required.
- Linux/Windows ship ONNX Runtime MI-GAN (~225 ms/frame, CPU).
- AI denoise (FDnCNN) uses the GPU via Vulkan/MoltenVK when available, else the CPU.
- macOS builds are Developer ID signed and notarized, so Gatekeeper allows them on first launch (a one-time online check). If Gatekeeper still blocks a build (for example on an offline machine), run
xattr -dr com.apple.quarantine <extracted-dir>. - Third-party licenses:
LICENSE-THIRD-PARTY.md.
# Gemini image (auto-detects + removes the sparkle logo)
wmr remove image.png -o clean.png
# Gemini / Veo video (auto-detects the watermark position + size)
wmr video video.mp4 -o clean.mp4
# Veo legacy text watermark
wmr video veo.mp4 --legacy -o clean.mp4
# NotebookLM video (auto-detects the logo + wordmark)
wmr video notebooklm.mp4 --notebooklm -o clean.mp4
# SynthID invisible watermark (no codebook needed)
wmr synthid image.png --codebook-free -o clean.pngBatch a folder: wmr remove folder/ -o cleaned/ --recursive.
Which command? Image →
remove· Gemini/Veo video →video· NotebookLM video →video --notebooklm· Invisible (SynthID) →synthid· Just locate →detect
Supported inputs: PNG / JPEG / WebP images; MP4 and other FFmpeg-supported video.
| Command | Does |
|---|---|
remove (default) |
Auto-detect + remove visible (and optionally SynthID) watermarks |
visible |
Remove only the visible watermark |
synthid |
Remove only the SynthID invisible watermark |
video |
Remove watermarks from video (Gemini / Veo / NotebookLM) |
detect |
Detect watermarks without modifying |
build-codebook |
Build a SynthID spectral codebook from reference images |
| Flag | Applies to | Description |
|---|---|---|
-o, --output |
most | Output path (required for files; batch defaults to cleaned/) |
-f, --force |
remove, visible, synthid, video | Skip detection, assume a watermark is present |
--force-small / --force-large |
remove, visible | Force 48×48 / 96×96 Gemini logo size |
--legacy |
remove | Pin legacy Gemini (pre-3.5) V1 still-image profile |
--no-legacy |
remove | Pin current (Gemini 3.5+) V2 profile; disable auto-fallback |
--legacy |
video | Use the Veo legacy text profile |
-r, --recursive |
remove | Process directories recursively |
-v, --verbose / -V, --version |
all | Verbosity / version |
| Flag | Description |
|---|---|
--codebook <path> |
Use a spectral codebook (.wcb) |
--codebook-free |
Estimate the carrier from the image's noise residual (no codebook) |
--phase-adaptive |
Use the image's own phase (conjugate subtraction; uniform images) |
--synthid-strength |
0.0–2.0 (default 0.50) |
--synthid (remove only) |
Also attempt SynthID removal during a remove pass |
Build a codebook from clean + watermarked reference pairs: wmr build-codebook refs/ -o codebook.wcb.
| Flag | Description |
|---|---|
--notebooklm |
Target the NotebookLM logo + wordmark |
--rect x,y,w,h |
Manual watermark rect (overrides auto-detect; Gemini/Veo and NotebookLM) |
--notebooklm-method {auto|ns|migan} |
Inpaint method override (auto = platform default: MI-GAN-everywhere on Apple Silicon, complexity-gated elsewhere) |
--complexity-threshold |
NS↔MI-GAN gate (default 15; consulted only on non-arm64 auto) |
--variant |
Force geometry: 720p-1, 720p-2, 1080p (otherwise it is auto-detected) |
--no-auto-geometry |
Skip the content-based geometry search, fall back to the resolution guess |
--scenes |
Split multi-scene videos into separate files |
--scene-threshold |
Scene-cut sensitivity 0.0–1.0 (default 0.3) |
--crf / --preset / --codec |
Encode settings (default CRF 14, slow, libx264) |
--inpaint-strength |
0.0–1.0 (default 0.85) |
Measuring a NotebookLM --rect: if auto-detection misses, grab a full-resolution frame and measure the mark's x,y,width,height in any image editor:
ffmpeg -ss 30 -i input.mp4 -frames:v 1 frame.png # then measure the mark in frame.pngLeave ~1px border around the mark, and pick a frame where it's clearly visible (it can be faint or absent on some scenes).
Release binaries ship an FDnCNN denoiser (NCNN/Vulkan, CPU fallback) that cleans residual artifacts after reverse-blending. It's the default cleanup when built.
wmr remove in.png --denoise ai -o out.png # AI (default in releases)
wmr remove in.png --denoise soft -o out.png # Gaussian
wmr remove in.png --denoise off -o out.png # reverse-blend only, no cleanup
wmr remove in.png --sigma 75 --strength 150 -o out.png # tune| Flag | Range | Default | Notes |
|---|---|---|---|
--denoise |
ai|soft|ns|telea|off |
ai (when built) |
Cleanup method |
--sigma |
1–150 | 50 | FDnCNN noise level (AI) |
--strength |
0–300 % | 120 | Cleanup strength |
--radius |
1–25 | 10 | Gaussian/TELEA/NS radius |
Source/dev builds default to AI-OFF (a lean fast build), exposing only --inpaint-strength. Use WMR_AI_DENOISE=1 to build with AI (see Build from source).
Visible watermarks (Gemini, Veo) are alpha-blended overlays: watermarked = α·logo + (1−α)·original. Since Gemini's logo and alpha map are known, removal inverts the blend exactly: original = (watermarked − α·logo)/(1−α). An optional denoise pass then cleans compression artifacts. Two logo sizes: 48×48 (images ≤1024px) and 96×96 (larger), bottom-right corner. Video applies the same reverse-blend per frame, with shot-level detection and anchor-based fallback so no frame is skipped; audio is passed through untouched.
NotebookLM marks are semi-transparent and color-adaptive (not a reversible alpha overlay), so they're removed by AI inpainting rather than reverse-blending. MI-GAN (MIT, ICCV 2023) synthesizes the missing region; on Apple Silicon it runs on the Neural Engine (~28 ms/frame), elsewhere on ONNX Runtime CPU, falling back to Navier-Stokes. The mark is auto-detected per video via template matching (polarity-invariant, stable across scene cuts). On Apple Silicon every scene uses MI-GAN by default; elsewhere a complexity gate picks MI-GAN for textured backgrounds and NS for uniform ones. --notebooklm-method overrides.
SynthID invisible watermarks live in the frequency domain. Removal estimates the carrier signal and subtracts it, either from a prebuilt spectral codebook (--codebook) or from the image's own noise residual (--codebook-free). Limitation: effective on uniform/dark images where the carrier dominates; on content-rich images the carrier is <0.1% of spectral energy, so reliable removal isn't currently possible.
| Path | Speed | Notes |
|---|---|---|
| Gemini image (reverse-blend + AI) | milliseconds | GPU denoise when Vulkan/MoltenVK is present, else CPU |
| NotebookLM, macOS Apple Silicon | ~28 ms/frame | CoreML on the Neural Engine |
| NotebookLM, Linux/Windows | ~225 ms/frame | ONNX Runtime CPU |
| Video encode | x264, CRF 14, slow |
Pipeline is encode-bound, not inpaint-bound |
Requires CMake 3.21+, a C++20 compiler, Ninja.
vcpkg (all platforms):
cmake -B build -S . -GNinja
cmake --build buildmacOS (Homebrew): scripts/build.sh self-heals stale caches and verifies formulas:
brew install cmake ninja opencv fftw ffmpeg fmt spdlog cli11 catch2
scripts/build.sh # release + testsWith AI denoise + MI-GAN (matches the release binaries; macOS uses CoreML, no ORT):
brew install vulkan-volk vulkan-loader vulkan-headers molten-vk
WMR_AI_MIGAN=1 WMR_AI_DENOISE=1 scripts/build.shTests: ctest --test-dir build --output-on-failure.
Single-pass C++20 tool. Everything compiles into one wmr binary. Pipeline: detect → remove → inpaint, orchestrated by WatermarkEngine.
src/
├── core/ engine, alpha blend, FFT, inpaint, ai_denoise, migan_inpainter
├── detection/ NCC visible detector, SynthID Bayesian detector
├── synthid/ spectral codebook, codebook/noise-residual subtractors, builder
├── video/ FFmpeg reader/writer, processor, scene + NotebookLM detectors
├── cli/ CLI11 subcommands, batch processor
└── main.cpp
assets/ embedded alpha-map PNGs + AI models (.mlpackage / .onnx, Git LFS)
tests/ Catch2 unit + integration
See CLAUDE.md for the full architecture deep-dive, and CHANGELOG.md for version history.
PRs welcome. Tests use Catch2; integration tests need the project root as CWD (they look for test-images/). Build with tests via scripts/build.sh, then ctest --test-dir build --output-on-failure. See CLAUDE.md for conventions, platform quirks, and the design notes behind each watermark path.
Built on research and code from:
- GeminiWatermarkTool & VeoWatermarkRemover: reverse alpha-blend, NCC detection, inpainting, FDnCNN conversion (Allen Kuo)
- reverse-SynthID: SynthID spectral analysis
- Picsart-AI-Research/MI-GAN: MI-GAN inpainting (MIT, ICCV 2023)
- KAIR/FDnCNN · Tencent/ncnn · zeux/volk · microsoft/onnxruntime: AI inference stack
MIT. Bundled third-party licenses (NCNN, volk, KAIR/FDnCNN, MI-GAN, ONNX Runtime, OpenCV) are in LICENSE-THIRD-PARTY.md.