49 KiB
Note
本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
English · 原始项目 · 上游 README
原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。
Remove-AI-Watermarks
从 Google Gemini(Nano Banana)、ChatGPT / DALL-E、Stable Diffusion、Adobe Firefly、Midjourney 及其他 AI 模型生成的图像中移除可见与不可见 AI 水印。
一条命令即可剥离 SynthID、C2PA Content Credentials(内容凭证)、EXIF/XMP「Made with AI」标签及可见闪光叠加层。
在线试用:raiw.cc
无需 Python、GPU 或安装配置。可见水印与元数据移除免费。不可见水印移除(SynthID / SDXL 再生)通常需要本地 GPU 和约 2 GB 模型。在 raiw.cc 上可一键在云端 GPU 运行,按图收取少量费用。
若本工具为你节省了时间,欢迎赞助其开发.
仅供合法用途。 发布与运行本软件本身合法;任何下游使用及遵守当地法律的责任完全由用户承担。部分司法管辖区限制移除 AI 标签本身(见法律说明)。作者不赞成用于欺骗、欺诈或任何非法活动。
适用范围
本工具移除平台盖印在你自行生成内容上的 AI 溯源水印——SynthID、Gemini / Nano Banana 闪光、豆包 / 即梦 / Samsung 可见 AI 标签、中国 TC260「由…AI生成」标签,以及 C2PA / IPTC / EXIF「Made with AI」元数据。目的在于让你对自己的输出拥有自主权。
它不针对保护他人付费或版权内容的的水印——图库机构叠加层(Shutterstock、Getty、iStock、Adobe Stock)、分类信息网站标记,或任何用于阻止购买的平铺「预览」水印。按设计,移除此类水印不在范围内。erase 是面向用户自选区域的通用工具,用于处理你自己的对象,而非自动图库水印移除器。
功能
- 可见水印移除 — 针对常见位置已知标记的注册表:Gemini / Nano Banana 闪光、豆包「豆包AI生成」文字条、即梦「★ 即梦AI」标识,以及 Samsung Galaxy AI「✦ Contenuti generati dall'AI」条带(左下角,按区域检测)。每个标记先定位到足迹遮罩再填充:引擎找到标记,在其足迹上构建二值遮罩,再由一套可共享、可替换的填充算法对该区域进行修复。通过
--backend选择填充方式:cv2(经典修复,无额外依赖,保底方案)、migan(MI-GAN,轻量,在 LaMa 放不下的内存紧张场景下的选择),或lama(big-LaMa,质量最佳,更重,有学习型后端时自动优先);默认auto按 LaMa > MI-GAN > cv2 选用最佳可用方案。定位器为轻量 CPU(cv2/numpy),随处可运行;较重的 MI-GAN/LaMa 填充为可选。检测依据各标记自身形状(与捕获轮廓做 NCC;由scripts/visible_alpha_solve.py重建的 alpha 用于检测与塑造遮罩,而非像素恢复)。视觉检测器不依赖元数据,但边缘(模糊或移位)标记仅在有多重佐证时才被信任:--sensitivity(默认auto)在本地元数据确认厂商或发现同产品兄弟标记时放宽该标记的门槛;--sensitivity assume-ai在断言图像为 AI 生成时放宽所有标记,可恢复保守门槛在已剥离元数据的截图上跳过的移位或重渲染标记(strict永不放宽)。visible --mark auto一次遍历查找并移除所有检测到的标记。快速、离线、无需 GPU。(任意 logo/对象见erase。) - 通用区域擦除器(
erase) — 移除你指定框内任意位置的 logo / 水印 / 对象,不论位置或颜色。默认 cv2 修复(CPU,即时);可选通过 onnxruntime 使用 big-LaMa(lama额外依赖)以获得更高质量 - 不可见水印移除 — SynthID、StableSignature、TreeRing,通过基于扩散的再生实现(需本地 GPU,或无需配置在 raiw.cc) 上运行)
- AI 元数据剥离 — EXIF、PNG 文本块、C2PA 溯源清单(PNG / JPEG / AVIF / HEIF / JPEG-XL,容器级 MP4 / MOV / M4V / M4A,以及通过 ffmpeg 无损处理 WebM / MP3 / WAV / FLAC / OGG)、XMP DigitalSourceType
- 「Made with AI」标签移除 — 移除平台读取以自动贴标的 AI 披露元数据(可用于清除经人工编辑照片上的误报标签)
- Analog Humanizer(模拟胶片感) — 可选的胶片颗粒与色差后处理
- 文字与人脸保留(默认) — 默认流水线使用 canny ControlNet,在移除过程中保持文字与人脸结构清晰(不复制原始像素,因此 SynthID 仍会被移除)。对无文字或人脸的输入,可用
--pipeline sdxl做纯 SDXL img2img(更轻,无需额外模型下载)。实验性--pipeline qwen运行 Qwen-Image(20B,Apache-2.0)img2img,在同等强度下比 SDXL 更好地保留文字(含 CJK 与小字);需 CUDA/云端级算力(不适配 MPS),其强度下限尚未认证(请显式传入--strength,尤其是 Gemini 内容)。注意:实测保真度(scripts/fidelity_metrics.py)显示 Qwen 在文字上更优,但 controlnet 对人脸保留更好(Qwen 对皮肤平滑更多),因此 Qwen 并非全面升级。Canny 保留的是人脸结构,而非身份(再生后人脸相似度会漂移)。库不附带人脸修复扩展:评估过的所有方案(GFPGAN-on-cleaned、PhotoMaker-V2、InstantID txt2img、InstantID img2img-on-cleaned)均通过 SDXL 再生成人脸,使输出比清理后图像更显 AI 感。清理后的 controlnet 输出是在不重新引入 SynthID 前提下可达到的最少 AI 感人脸状态。 - 批量处理 — 处理整个目录
- 检测 — 三阶段 NCC 水印检测与置信度评分
- 溯源检测(
identify) — 汇总 C2PA 签发方、C2PA 软绑定取证水印厂商(Adobe TrustMark、Digimarc、Imatag 等)、IPTC「Made with AI」及 IPTC 2025.1AISystemUsed字段、内嵌 SD/ComfyUI 参数、EXIF/XMP 生成器标签、xAI/Grok EXIF 签名、中国 TC260 AIGC 标签(XMP、PNG 块、EXIF 或 JPEG 段)、HuggingFacehf-job-id作业标记、SynthID 元数据代理、C2PA 云端清单引用(Adobe Durable Content Credentials,当内嵌清单被剥离时)、可见标记(Gemini 闪光及豆包「豆包AI生成」/ 即梦「即梦AI」/ Samsung Galaxy AI「Contenuti generati dall'AI」文字标记)、开放 SD/SDXL/FLUX 不可见水印,以及(配合trustmark扩展)开放 Adobe TrustMark 水印,输出单一来源平台 + 水印清单判定(--json供机器读取)
示例
| 处理前(含水印) | 处理后(已清理) |
|---|---|
![]() |
![]() |
支持的模型
| AI 模型 | 可见水印 | 不可见水印 | 元数据 | 我们的方案 |
|---|---|---|---|---|
| Google Gemini / Nano Banana / Gemini 3 Pro | ✅ 闪光 logo | ✅ SynthID v1 + v2(默认 SDXL 流水线,原生分辨率) | ✅ C2PA + EXIF | 定位 + 填充 + 扩散 + 元数据剥离 |
| OpenAI DALL-E 3 / ChatGPT | — | — | ✅ C2PA 清单 | 元数据剥离 |
| OpenAI ChatGPT Images 2.0 (gpt-image-2) | — | ✅ SynthID + 内容相关像素水印(自 2026 年 5 月起;无本地解码器,openai.com/verify 预言机) | ✅ C2PA 清单(已验证) | 扩散再生 + 元数据剥离 |
| Stable Diffusion / SDXL (AUTOMATIC1111, ComfyUI) | — | ✅ DWT-DCT(imwatermark — 可本地检测) | ✅ PNG 文本块 | 扩散再生 + 元数据剥离 |
| Black Forest Labs FLUX | — | ✅ DWT-DCT(imwatermark — 可本地检测) | ✅ C2PA(FLUX.2 Pro) | 扩散再生 + 元数据剥离 |
| Adobe Firefly | — | — | ✅ Content Credentials(C2PA) | 元数据剥离 |
| Stability AI (DreamStudio / Stable Image) | — | — | ✅ C2PA(「Stability AI Ltd」) | 元数据剥离 |
| Microsoft Designer / Bing Image Creator | — | ✅ 经 DALL-E 后端的 SynthID(Designer) | ✅ C2PA(Bing 运行 MAI-Image,签名「Microsoft」) | 元数据剥离 |
| xAI Grok (Aurora) | — | — | ✅ EXIF 签名方案(无 C2PA):Signature: blob + UUID Artist |
已检测(identify);元数据剥离 |
| Midjourney | — | — | ✅ EXIF + XMP(prompt、model、seed) | 元数据剥离 |
| Meta AI | — | — | ✅ IPTC「Made with AI」(digitalSourceType) | 元数据剥离(移除标签) |
| Doubao(ByteDance)/ 中国 AIGC 生成器 | ✅「豆包AI生成」文字条(右下角) | — | ✅ TC260 AIGC 标签(<TC260:AIGC> XMP、AIGC PNG 块或 EXIF JSON)+ C2PA(ByteDance Volcano Engine 签名,volcengine) |
定位字形足迹 + 填充 + 元数据剥离 |
| Jimeng / Dreamina(即梦AI,ByteDance) | ✅「★ 即梦AI」标识(右下角) | — | ✅ TC260 AIGC 标签 + C2PA(Volcano Engine) | 定位字形足迹 + 填充 + 元数据剥离 |
| Samsung Galaxy AI(Generative Edit、Sketch to Image 等) | ✅「✦ Contenuti generati dall'AI」条带(左下角,意大利区域检测) | — | ✅ C2PA(签名方「Samsung Galaxy」)+ trainedAlgorithmicMedia / 专有 genAIType 标记 |
定位字形足迹 + 填充 + 元数据剥离 |
| Black Forest Labs(FLUX API) | — | — | ✅ C2PA(Black Forest Labs API + c2pa.ai_generated_content + trainedAlgorithmicMedia) |
元数据剥离 |
| StableSignature(Meta) | — | ✅ 模型内水印 | — | 扩散再生 |
| TreeRing | — | ✅ 潜空间水印 | — | 扩散再生 |
Google Gemini / Nano Banana(sparkle 徽标)、字节跳动的豆包(Doubao,「豆包AI生成」角标文字)、即梦 / Dreamina(Jimeng,「★ 即梦AI」字标),以及 Samsung Galaxy AI(「✦ Contenuti generati dall'AI」条带,左下角,随区域设置而定)均使用可见叠加层。移除方式均为:将标记定位到足迹掩码(footprint mask),再用同一套填充进行修复(默认 cv2,也可通过
--backend选用 MI-GAN 或 big-LaMa);定位器对 CPU 开销很低,较重的填充方案为可选。其他服务依赖不可见水印和/或元数据;我们基于扩散(diffusion)的再生成可对抗像素域或频域中的任何不可见水印。对于来自任何其他来源的可见标记(任意位置、任意颜色),请使用通用命令erase --region。
检测:
remove-ai-watermarks identify <image>会报告上述所有信号的来源平台与水印清单——C2PA 签发方、C2PA 软绑定(soft-binding)取证水印厂商(TrustMark / Digimarc / Imatag / ...)、IPTC「Made with AI」以及 IPTC 2025.1 的AISystemUsed字段、中国 TC260 AIGC 标签(XMP、PNG chunk、EXIF 或 JPEG 段)、HuggingFacehf-job-id作业标记、内嵌生成参数、EXIF/XMP 生成器标签、xAI/Grok EXIF 签名、SynthID 元数据代理、C2PA 云端清单引用(Adobe Durable Content Credentials,当内嵌清单被剥离时)、可见标记(Gemini sparkle 以及豆包「豆包AI生成」/ 即梦「即梦AI」/ Samsung Galaxy AI「Contenuti generati dall'AI」文字标记),以及(配合[detect]/[trustmark]扩展)开放的 SD/SDXL/FLUX 与 Adobe TrustMark 不可见水印。SynthID 及专有软绑定水印(Digimarc 等)没有本地解码器,因此仅通过元数据代理 / 厂商名称进行报告。
工作原理
移除 Gemini / Nano Banana sparkle 水印
Google Gemini(内部代号 Nano Banana)通过 alpha 混合为生成图像添加可见的 sparkle 徽标:
watermarked = α × logo + (1 − α) × original
多尺度 NCC(归一化互相关,Normalized Cross-Correlation)检测器在右下角区域动态查找 sparkle 的位置与尺度(带误报门控),因此即使图像经过缩放或裁剪仍可工作。移除流程为 先定位再填充:sparkle 足迹由捕获的 alpha 经低阈值处理构建(以包含微弱光晕),再按 sparkle 相对边距膨胀,该掩码由共享填充修复。捕获的 alpha 贴图仅用于检测 sparkle 与塑造掩码,不用于恢复像素。若本地元数据已确认来源为 Google(Google / Gemini C2PA 签发方),检测信任门控会放宽,以便仍能捕获被移动或重新渲染的 sparkle。通过 --backend 选择填充方案(默认 cv2,可选 MI-GAN 或 big-LaMa)。
速度:使用默认 cv2 填充时,CPU 上速度很快。无需 GPU。
移除豆包「豆包AI生成」文字水印
豆包(Doubao,字节跳动)在每张输出图像的右下角加盖一条浅色、半透明的「豆包AI生成」文字条——这是中国 TC260 标准要求的可见 AIGC 标签。检测通过将字形轮廓与角落进行匹配(归一化互相关),因此依据的是「豆包AI生成」的形状,而非角落纹理。移除流程为 先定位再填充:浅色字形块被定位到实心、膨胀后的足迹掩码(无需模板,因此重新渲染或位置不同的标记仍会被掩蔽),再由共享填充修复。在语料图像上,填充区域在数个 LAB 色阶内与周围融合,无色彩偏移、无暗坑。通过 --backend 选择填充方案(默认 cv2,可选 MI-GAN 或 big-LaMa)。
速度:使用默认 cv2 填充时,CPU 上速度很快,无需 GPU。
移除即梦「★ 即梦AI」字标
即梦 / Dreamina(即梦AI,同属字节跳动,与豆包不同)在右下角加盖「★ 即梦AI」字标——四尖 sparkle 后跟即梦AI 字符。检测依据字标的字形轮廓(与捕获的剪影进行 NCC 匹配)。visible --mark auto 可检测并移除(也可用 --mark jimeng 强制处理)。移除流程为 先定位再填充:字形块被定位到实心、膨胀后的足迹掩码,再由共享填充修复,因此重新渲染或位置不同的标记仍会被清除。在语料图像上,填充区域在数个 LAB 色阶内与周围融合,无色彩偏移。两个字节跳动标记不会混淆 auto:检测分别依据各自标记的字形轮廓(即梦检测器在豆包条带上得分远低于其阈值,反之亦然)。
remove-ai-watermarks visible jimeng.png -o clean.png # --mark auto picks Jimeng
remove-ai-watermarks visible jimeng.png --mark jimeng -o clean.png
移除 Samsung Galaxy AI「✦ Contenuti generati dall'AI」标记
三星设备端生成式 AI 编辑(Generative Edit、Sketch to Image、Portrait Studio)在 左下角 烙入可见的 sparkle +「generated with AI」字符串——一条微弱、低不透明度、半透明的白色叠加层。检测通过匹配字形剪影(NCC),移除流程为 先定位再填充:字形块被定位到实心、膨胀后的足迹掩码,再由共享填充修复。visible --mark auto 可检测并移除(也可用 --mark samsung 强制处理);因其位于左下角,绝不会与右下角的 Gemini/豆包/即梦标记混淆。检测随区域设置而定——本构建仅检测意大利语「Contenuti generati dall'AI」变体,因此其他三星区域版本不会被检测(也就不会被移除),需要各自的捕获检测模板(请在 issue #37 上提供样本)。填充掩码本身与区域设置无关。
remove-ai-watermarks visible samsung.jpg -o clean.jpg # --mark auto picks Samsung
remove-ai-watermarks visible samsung.jpg --mark samsung -o clean.jpg
通用区域擦除器
对于专用引擎未覆盖的任何可见标记——任意位置的徽标、任意颜色——erase --region x,y,w,h 会修复你指定的矩形区域。默认 cv2 后端即时且零依赖;可选 lama 后端(通过 onnxruntime 的 big-LaMa,lama 扩展,首次使用时下载约 200 MB 模型)在纹理区域上提供更干净的填充,但每次调用约需 3–4 GB RAM。
移除 SynthID 及其他不可见水印
Google 将 SynthID 嵌入 Gemini / Nano Banana 生成的每张图像。其他 AI 服务使用 StableSignature、TreeRing 及类似方案。这些难以察觉的频域图案可经受裁剪、缩放与 JPEG 压缩。
移除流水线(默认配置,SDXL):
image → encode to latent space (VAE) at native resolution
→ add controlled noise (forward diffusion)
→ denoise (reverse diffusion, ~50 steps; strength is vendor-adaptive:
0.20 OpenAI / 0.30 Google / 0.30 unknown, same for both pipelines;
override with --strength)
→ decode back to pixels (VAE)
- 大尺寸输入以原生分辨率运行(无先缩小再放大往返,那是 issue #10 中主要质量损失的来源);仅在超大输入上使用
--max-resolution N以限制 GPU/MPS 显存。对于在原生分辨率下 GPU/MPS 显存不足的输入,--tile是--max-resolution的无损替代:它以重叠、羽化混合的瓦片(每块接近 SDXL 的 1024 px 尺寸)再生成图像,从而无降采样、无可见接缝。仅当长边超过--tile-size(默认 1024;重叠--tile-overlap,默认 128)时启用;请与--max-resolution 0配合使用。小尺寸输入(长边不足 1024 px)会在扩散前自动上采样至 1024 px 下限,因为 SDXL 在极小潜空间上会失真,结果再恢复至原始尺寸(透明的质量提升)。用--min-resolution 0可禁用该下限。下限上采样默认使用 Lanczos;--upscaler esrgan(esrgan扩展)会先运行 Real-ESRGAN 以获得更锐利的细节,若无该扩展则回退到 Lanczos。ESRGAN 是通用照片/纹理 GAN,无面部/字形先验,因此最适合照片/纹理内容——它可能劣化面部(扩散阶段会再生成,故最终可恢复)和细文字;文字较多的输入请保留 Lanczos。
默认强度为供应商自适应(无需标志)。 该工具会读取 C2PA 签发方以检测存在哪家供应商的 SynthID,并据此选择相应强度:OpenAI gpt-image →
0.20,Google Gemini →0.30,未知来源 →0.30。两条流水线使用同一强度阶梯 — 这些是 oracle 认证的controlnet下限(2026 年 6 月 Modal 认证,多 seed)。它们同样覆盖纯sdxl:两条流水线各有相反的困难场景(controlnet 在写实照片上留下 SynthID,sdxl 在扁平图形上),但在各自的困难场景下 sdxl 是较弱的去除器,因此至少需要 controlnet 的强度 — 使用一套认证阶梯是更安全的选择(对 sdxl 基于余量,未单独认证)。主导因素是供应商(Google 的 SynthID 约强 3 倍)。没有本地 SynthID 检测器,因此若 oracle 仍能读到 SynthID,请提高--strength;若你更在意保留精细细节,则降低它。(注意:Google 的0.30仅在--max-resolution 1536处验证过;非常大的原生 Gemini 图像可能需要约0.35+。)默认流水线为
controlnet— 它保留文字与人脸结构。 它运行相同的 SDXL img2img scrub,但额外加入 canny ControlNet,在图像边缘图上条件化再生成,使文字与结构在去除 SynthID 的强度下仍保持锐利。水印去除仍来自 img2img 再生成(--strength);ControlNet 仅保留结构 — 不会复制或冻结任何原始像素。默认强度阶梯(OpenAI0.20/ Google0.30)是 oracle 认证的 controlnet 下限。--controlnet-scale调节保留强度(越高越接近原始结构)。在 mps/cpu 上以 fp32 运行(仅在 cuda/xpu 上使用 fp16,此时会自动加载 fp16 修复版 SDXL VAE)。对不含文字或人脸的输入,可传入--pipeline sdxl以使用纯 SDXL img2img(更轻量,无需额外下载模型)。库中不提供 face-restore 附加组件。 我们评估的每种基于 ArcFace 的再生成方案(GFPGAN-on-cleaned、PhotoMaker-V2、InstantID txt2img、InstantID img2img-on-cleaned 三次参数扫描,2026-06-04 至 2026-06-08 Modal 认证扫描)均通过 SDXL 扩散再生成人脸 — 输出人脸像素为扩散新生成(未重新引入 SynthID),但人脸本质上比清理后的图像更显 AI 生成感(SDXL「干净皮肤」光泽、丢失原始身份精度)。主 controlnet 0.20 遍产生的清理图像是我们在不重新引入 SynthID 前提下能达到的最少 AI 感人脸状态。经验结论见
docs/synthid-robust-identity-research-2026-06-08.md。
SDXL 自 2026 年 5 月起为默认:经验证可在 Gemini 3 Pro 输出上击败 SynthID v2,而旧的 768 px SD-1.5 流水线不能。一旦确认 SD-1.5 路径无法处理 v2 即被移除。请注意范围:这击败的是 SynthID 验证器,并不等同于在取证层面与真实照片无法区分。近期工作(arXiv:2605.09203) shows watermark-removal pipelines leave detectable traces, so a separate "this image was processed" classifier can still flag the output.
Oracle 与
identify可能不一致,这是预期行为。 在线验证器读取实际的 SynthID 像素 水印,且仅检测其自身供应商的内容 — openai.com/research/verify states "OpenAI generation signals will only be detected if the image was generated with our tools". 我们的identify无法解码像素水印(没有供应商提供本地解码器),因此改为从 C2PA 元数据 推断 SynthID。因此 SDXL 处理后 oracle 可能显示「无 SynthID」(像素水印已消失),而identify仍会从残留的 C2PA manifest 报告 SynthID。它们测量的是不同信号。运行metadata --remove(或all)也可剥离 manifest;请注意,安静的元数据代理并不能证明像素水印本身已消失。
技术深入: 参见
docs/synthid.md获取带一手文献引用的 SynthID 机制分解(事后 encoder/decoder、136 位 payload、像素空间嵌入)、经验上能存活什么(JPEG、裁剪、缩放:arXiv:2510.09263 在 0.1% FPR 下约 99.98% TPR)、什么能去除它,以及取证隐蔽性权衡(arXiv:2605.09203 指出所有已知去除攻击在 >98% TPR@1%FPR 下仍可检测)。
文字与人脸保留(默认流水线;--pipeline sdxl 可降级为纯 SDXL):canny ControlNet 在去除过程中保持文字与人脸结构锐利,且不复制或冻结任何原始像素(因此 SynthID 仍会被去除)。用 --controlnet-scale 调节保留强度。Canny 保留结构但不保留人脸身份:再生成的人脸在相似度上会漂移。库不提供 face-restore 附加组件(见上文说明)。
Analog Humanizer:可选的胶片颗粒与色差注入,模拟屏幕照片效果,提高 AI 生成图像分类器的门槛。(可挫败通用分类器,但不保证取证不可见 — 见上文 arXiv:2605.09203 说明。)
剥离 C2PA、EXIF 与「Made with AI」元数据
AI 工具会嵌入生成元数据,社交平台据此显示「Made with AI」标签:
- EXIF 标签 — prompt、seed、model hash、sampler 设置(Stable Diffusion、Midjourney)
- XMP DigitalSourceType — Instagram、Facebook 与 X (Twitter) 用于显示「Made with AI」的
trainedAlgorithmicMedia标签 - PNG text chunks — ComfyUI 工作流、AUTOMATIC1111 参数
- C2PA Content Credentials — 来自 Google Imagen、OpenAI DALL-E、Adobe Firefly 的加密溯源 manifest
清理器逐层解析,移除 AI 相关字段,并保留标准元数据(Author、Copyright、Title)。
安装
Homebrew (macOS / Linux)
brew install wiltodelta/tap/remove-ai-watermarks
这会安装核心命令界面(identify、metadata、visible、
erase)作为独立 CLI。基于扩散的 invisible / all
流水线需要重型 ML 依赖(torch、diffusers、数 GB)且未包含在
Homebrew 构建中;若需要,可通过 pip 的 gpu extra 添加:
pip install "remove-ai-watermarks[gpu]"
conda
conda-forge 配方正在审核中 (staged-recipes PR). 合并后,核心包可通过以下方式安装:
conda install -c conda-forge remove-ai-watermarks
与 Homebrew 构建一样,这是核心命令界面;通过 pip 的 gpu extra 添加扩散
invisible / all 流水线。
推荐
作为独立 CLI 工具安装 — 无需管理虚拟环境:
# Using pipx (https://pipx.pypa.io)
pipx install git+https://github.com/wiltodelta/remove-ai-watermarks.git
# Or using uv (https://docs.astral.sh/uv)
uv tool install git+https://github.com/wiltodelta/remove-ai-watermarks.git
更新到最新版本:
pipx upgrade remove-ai-watermarks
# or
uv tool upgrade remove-ai-watermarks
从仓库安装
前置条件: Python 3.10+ 与 pip(或 uv).
# 1. Clone the repository
git clone https://github.com/wiltodelta/remove-ai-watermarks.git
cd remove-ai-watermarks
# 2. Install the package in editable mode
pip install -e .
# Or, if you use uv:
uv pip install -e .
安装后 remove-ai-watermarks 命令可在系统范围内使用。
注意:基础安装涵盖可见水印去除与元数据剥离。 若要去除不可见水印(SynthID 等),请安装 GPU 依赖:
pip install -e ".[gpu]" # or: uv pip install -e ".[gpu]"若不安装
[gpu]extra,all仍会运行可见与元数据步骤,但 会跳过不可见(SynthID)步骤、打印明确警告,并以 非零状态退出,以免将跳过的步骤误认为干净结果。要让
identify解码开放的 Stable Diffusion / SDXL / FLUX 不可见 水印,请安装detectextra(添加invisible-watermark解码器):pip install -e ".[detect]" # or: uv pip install -e ".[detect]"若要同时解码开放的 Adobe TrustMark 水印(位于 Adobe Durable Content Credentials 之后),请安装
trustmarkextra(会拉取 torch 并在 首次使用时下载模型权重):pip install -e ".[trustmark]" # or: uv pip install -e ".[trustmark]"若要在扩散前对小型输入进行更锐利的放大(
--upscaler esrgan、 Real-ESRGAN),请安装esrganextra。它通过 spandrel(MIT,无 basicsr)加载; Real-ESRGAN 权重(BSD-3-Clause)在首次使用时下载:pip install -e ".[esrgan]" # or: uv pip install -e ".[esrgan]"
隐形水印移除
隐形水印移除使用扩散模型(diffusion models)和 GPU,以获得合理的处理速度。
# On first run, the model (~2 GB) will be downloaded automatically.
# Device is auto-detected: CUDA (Linux/Windows) > MPS (macOS) > CPU.
# To force a device: --device cuda / --device mps / --device cpu
# Optional: set a HuggingFace token for gated/private models
cp .env.example .env
# Edit .env and set HF_TOKEN=hf_your_token_here
开发者环境配置
# Install with dev dependencies (pytest, ruff, pyright)
pip install -e ".[dev]"
# Or with uv:
uv pip install -e ".[dev]"
# Run tests
pytest
# Run linters
./maintain.sh
ComfyUI
提供自定义节点(custom nodes),可在 ComfyUI 图(graph)中运行水印工具: ComfyUI-remove-ai-watermarks (registry).
通过 ComfyUI Manager 安装(搜索 "Remove AI Watermarks"),或手动安装:
cd ComfyUI/custom_nodes
git clone https://github.com/wiltodelta/ComfyUI-remove-ai-watermarks
pip install -r ComfyUI-remove-ai-watermarks/requirements.txt
节点:Remove Visible Watermark、Detect Visible Watermark、Erase Region(按遮罩 mask)、Remove Invisible Watermark / SynthID(需要 gpu extra)。
用法
CLI
# Remove all watermarks from a single image (visible + invisible + metadata)
remove-ai-watermarks all image.png -o clean.png
# Process an entire directory
remove-ai-watermarks batch ./images/ --mode all
单独命令
# Identify provenance: where an image was made + its watermark inventory.
# Aggregates C2PA, IPTC "Made with AI", embedded SD/ComfyUI params, EXIF/XMP
# generator tags (incl. inside AVIF/HEIF), the SynthID proxy, the visible Gemini
# sparkle, and (with the [detect] extra) the open SD/SDXL/FLUX invisible
# watermark into one verdict. Reports "unknown"
# (never "clean") when no signal is found, since stripped metadata is not proof
# of a clean origin. Add --json for machine-readable output.
remove-ai-watermarks identify image.png
# Visible watermark only — fast, offline, CPU. --mark auto (default) removes every
# detected known mark (Gemini sparkle / Doubao "豆包AI生成" / Jimeng "即梦AI" /
# Samsung Galaxy AI "Contenuti generati dall'AI"); force one with
# --mark gemini / doubao / jimeng / samsung. Removal localizes each mark to a
# footprint mask and inpaints it with a shared fill; --backend auto|cv2|migan|lama
# (default auto) picks the fill (auto = LaMa > MI-GAN > cv2, best available).
# --sensitivity auto|strict|assume-ai (default auto) sets how hard a borderline
# mark is trusted; use assume-ai on a metadata-stripped screenshot to recover a
# moved or faint mark the conservative gate would skip.
# If no known visible mark is found, it writes no output and exits 2 (not 0),
# pointing you to `all` (for an invisible/metadata mark) or `erase` (for an
# arbitrary logo) instead of handing back the unchanged image.
remove-ai-watermarks visible image.png -o clean.png
# Metadata-stripped screenshot: assert it is AI to relax detection and recover
# a moved/faint mark (a wrong guess just fills a small corner near-losslessly).
remove-ai-watermarks visible screenshot.png --sensitivity assume-ai -o clean.png
# Erase arbitrary region(s) — universal, any logo/watermark/object, any position.
# Default cv2 inpainting (CPU). --backend lama uses big-LaMa (extra 'lama').
remove-ai-watermarks erase image.png --region 1640,1930,400,100 -o clean.png
# Invisible watermark only (SynthID etc.) — requires GPU
remove-ai-watermarks invisible image.png -o clean.png --humanize 4.0 --unsharp 0.5
# --humanize adds film grain, --unsharp counters the soft "AI" look (both opt-in).
# Large images run at native resolution; small ones are upscaled to a 1024 floor
# first (disable with --min-resolution 0); --upscaler esrgan uses Real-ESRGAN for
# that floor upscale (needs the 'esrgan' extra). On a very large image that OOMs the
# GPU/MPS, either cap the long side (--max-resolution 2048, lossy) or pass --tile
# to regenerate in overlapping feather-blended tiles at native resolution (lossless).
# Strength is vendor-adaptive by default (OpenAI 0.20 / Google 0.30, same
# for both pipelines); override with --strength. controlnet (text/face
# structure preservation) is the default pipeline; --pipeline sdxl opts down
# to plain SDXL for non-structure inputs. Tune structure preservation with
# --controlnet-scale, the CFG with --guidance-scale (default 7.5), and the
# diffusion model with --model (default: SDXL base).
# --adaptive-polish (ON by default) restores the input's detail level (sparing
# text) to counter the over-smoothed look; it self-limits to a no-op where
# there is no detail deficit. Disable with --no-adaptive-polish.
# By default, if no invisible AI watermark is locally detectable, the diffusion
# scrub is SKIPPED (regenerating pixels would only degrade a clean image): for
# `invisible` that writes no output and exits 2, for `all` it skips step 2 but
# still strips metadata and exits 0. A skip never claims the image is clean
# (a pixel SynthID is undetectable once its metadata is gone). Pass --force to
# regenerate regardless when you know the image is AI-generated.
# Check / strip AI metadata (C2PA, EXIF, "Made with AI" labels)
# --check also flags SynthID-bearing sources: a C2PA manifest signed by
# Google or OpenAI implies an invisible SynthID watermark in the pixels
# (both vendors pair the two). Adobe Firefly / Microsoft sign C2PA without
# SynthID, so they are reported as C2PA only.
remove-ai-watermarks metadata image.png --check
remove-ai-watermarks metadata image.png --remove
# Batch with a specific mode
remove-ai-watermarks batch ./images/ --mode visible
# Batch accepts the full invisible knob set (--strength/--guidance-scale/--model/
# --pipeline/...); --adaptive-polish is on by default (--no-adaptive-polish to disable)
remove-ai-watermarks batch ./images/ --mode all
Python API
一次高层调用即可通过定位(localize)再填充(fill)的方式,移除所有检测到的可见标记(Gemini sparkle、Doubao / Jimeng / Samsung 文本、Jimeng pill)。对文件而言,它会自动读取元数据溯源(metadata provenance)并保留 alpha 通道;import remove_ai_watermarks 开销很低(重型依赖在首次使用时延迟加载)。
import remove_ai_watermarks as raiw
# Clean a file -> writes clean.png, returns the array and what was removed.
result, removed = raiw.remove_visible("watermarked.png", "clean.png")
print("removed:", removed) # e.g. ['Google Gemini sparkle']
# An empty list means nothing known was found (route to `all` or `erase` instead).
# Array in, array out (BGR numpy). Pick the fill backend: cv2 (default), migan, lama.
import cv2
clean, removed = raiw.remove_visible(cv2.imread("in.png"), backend="cv2")
# Metadata-stripped screenshot you know is AI-generated: relax detection to recover a
# moved or faint mark (a wrong guess just fills a small corner near-losslessly).
raiw.remove_visible("screenshot.png", "clean.png", sensitivity="assume_ai")
# What the file's metadata confirms (drives the default `auto` sensitivity):
raiw.visible_provenance("in.png") # e.g. frozenset({'gemini'})
# Full provenance verdict (platform + watermark inventory + confidence):
from remove_ai_watermarks.identify import identify
report = identify("in.png")
隐形水印移除(diffusion)
from pathlib import Path
from remove_ai_watermarks.invisible_engine import InvisibleEngine
# pipeline: "controlnet" (default, preserves text/face structure) or "sdxl" (plain).
# model_id=None uses the SDXL base; controlnet_conditioning_scale tunes preservation.
engine = InvisibleEngine(pipeline="controlnet")
engine.remove_watermark(
Path("watermarked.png"),
Path("clean.png"),
strength=None, # None = vendor-adaptive default (OpenAI 0.20 / Google 0.30)
num_inference_steps=50,
guidance_scale=None, # None = the library default (7.5)
seed=None, # set for reproducible output
adaptive_polish=True, # detail-targeted polish, self-gating (default on in the CLI)
min_resolution=1024, # upscale tiny inputs to this floor before diffusion
max_resolution=0, # 0 = native; set only to cap GPU/MPS memory
upscaler="lanczos", # or "esrgan" for the floor upscale (needs the 'esrgan' extra)
)
元数据剥离
from remove_ai_watermarks.metadata import has_ai_metadata, remove_ai_metadata
from pathlib import Path
if has_ai_metadata(Path("image.png")):
remove_ai_metadata(Path("image.png"), Path("clean.png"))
环境要求
- Python ≥ 3.10
- 可见水印去除 / 元数据:仅需 CPU,无需 GPU
- 不可见水印去除:建议使用 GPU(CUDA 或 MPS),也可在 CPU 上运行(较慢)
故障排除
SSL 证书错误(CERTIFICATE_VERIFY_FAILED):
# Install certifi (the tool auto-detects it)
pip install certifi
# macOS only: run the Python certificate installer
/Applications/Python\ 3.*/Install\ Certificates.command
首次运行较慢——这是正常现象。该工具在首次启动时会下载模型权重(约 2 GB)。后续运行将使用缓存的模型。
致谢
- noai-watermark by mertizci — 不可见水印去除引擎
- GeminiWatermarkTool by Allen Kuo (MIT) — 可见水印去除算法
- controlnet-canny-sdxl-1.0 by xinsir —
controlnet流程所用的 SDXL canny ControlNet,用于保留文字/面部结构 - NeuralBleach (MIT) — 模拟人类化(analog humanizer)技术
路线图
已跟踪但尚未实现:
- SynthID-Image v2 自动化回归测试。默认 SDXL 配置在针对 Gemini app's "Verify with SynthID" 功能对 Gemini 3 Pro 输出(2026 年 5 月)进行的手动检查中可击败 v2。端到端自动化测试需要以编程方式访问 SynthID Detector portal(面向媒体专业人士和研究人员的候补名单),或采用离线替代检测器。reverse-SynthID 的频谱相位相干性替代方案经评估后,无法区分带水印图像与已清理的真实内容图像(仅在精确分辨率的受控纯色参考图上触发),因此不能作为可用 oracle。状态:开放。
- 本地 SynthID 像素 检测器。目前不可行:Google 的解码器为专有技术,且幅度/载波频谱方法无法区分真实内容(经三项独立评估确认,包括从零开始的 gpt-image 试点;见 docs/known-limitations.md)。受阻于:(a) 可编程生成路径(OpenAI / Gemini API)以大规模构建按(模型、分辨率)标注的语料库,或 (b) 原始带水印输出数据集。若数据到位,下一步将尝试在多样化内容上使用学习型分类器,而非固定载波码本。
- 扩充 SynthID 参考语料库(
data/synthid_corpus/),为各模型与分辨率添加 oracle 标注样本(Google 使用 Gemini app,OpenAI 使用 openai.com/verify)。这是任何像素检测器尝试及自动化去除回归集的前提。 - 真实非 PNG C2PA 测试样例。针对 JPEG / WebP / AVIF 的 SynthID 来源检测目前仅由合成字节块覆盖;需替换为真实厂商生成的文件,以夯实二进制扫描路径。
- 维护债务。严格 pyright 现已在
src/中全部通过(0 个错误):纯逻辑文件已完全类型化,cv2 / torch / diffusers 边界文件带有已文档化的逐文件放宽 pragma,本地typings/piexif桩覆盖 piexif。剩余工作:全项目pyright(无路径)在此 ML 密集型仓库中仍会导致 node OOM,因此必须限定在src/;随着上游桩改进,将边界 pragma 逐步收紧至完全严格是长期任务。(自idna升级至 3.16 以来,uv-secure已干净。) - AVIF / HEIF
Exif项位于meta盒内。meta盒内 AI 标签 XMP 数据包现已在原位清空(v0.6.9),但以meta盒Exif项 形式存储的 EXIF 仍未移除——需要完整的iinf/iloc手术(偏移重写,存在损坏风险)或exiftool(非捆绑二进制依赖)。优先级较低:我们针对的 AI 标签为 XMP,而非 EXIF,因此仅 EXIF 的 meta-box 情况较为罕见。 - 更多 C2PA 设备签名方。Leica、Nikon、Google Pixel、Sony 和 Truepic 拍摄相机已映射(均经真实签名文件验证);Samsung Galaxy AI、Black Forest Labs (FLUX) 和 ByteDance Volcano Engine(Doubao / Jimeng)现已归因(经真实签名文件验证)。Canon 仍暂缓,直至出现真实签名样本——目前尚无公开直接下载的 C2PA 文件(仅支持上传验证 / 新闻机构授权)。
- Resemble PerTh 音频检测——已评估,公共 API 不可行:
get_watermark()返回原始位数组且无存在/置信度标志,因此若无 Resemble 固定载荷或置信度服务,无法可靠区分带水印与干净音频。与 SynthID 像素检测器面临同样壁垒。 - 视频流程(
noai-video):针对 Sora 2 动态 logo、Veo 3.1 徽章、Kling、Runway 的逐帧修复与跟踪。独立软件包,不并入本仓库。
不予修复:
- Nightshade / Glaze / PhotoGuard 去除。这些是艺术家用于保护作品免遭抓取进入 AI 训练集的防御性扰动。去除它们攻击的是艺术家,而非 AI 溯源。超出范围。
局限性
- 可见标记去除为局部修复(inpainting);元数据去除为无损操作。 每个可见标记限定在足迹掩膜内,并通过修复(cv2、MI-GAN 或 big-LaMa)填充,因此仅重建小块掩膜区域,并在数个 LAB 色阶内与周围融合;定位略有偏差时,也只是在邻近区域近乎无损地填充,而非留下色偏涂抹。元数据剥离从不触及图像数据。
- 不可见(SynthID)路径为有损且不保证成功。 它运行低强度 SDXL img2img 再生成,因此会柔化精细细节,且效果因内容而异。没有公开的 SynthID 解码器,工具无法在本地验证去除效果;请使用 Gemini app 的 "Verify with SynthID" oracle 确认,若仍可检测请提交
--strength。厂商可随时更改方案,因此应将其视为军备竞赛,而非永久修复。 - 大图:默认原生分辨率,可选分块以应对 OOM。 SynthID 路径在扩散模型原生分辨率下运行;在内存受限的 GPU/MPS 上,可用
--max-resolution限制长边(有损缩小),或传入--tile以原生分辨率在重叠、羽化混合的分块中再生成(无损、无缝)。分块是内存变通方案,并非相对单次原生处理的画质提升:每块均为独立的低强度再生成。(Nano Banana 2 原生为 1024px;GPT Image 2 实验性支持 4K。) - 超出范围: 击败 Hive 等训练型 AI 与真实分类器(见 威胁模型)、视频中可见 logo 去除,以及任何关于剥离副本在服务端不可追溯的保证。
法律
多个司法管辖区现已对 AI 生成内容的加水印与溯源进行监管。下表汇总 2026 年 5 月状态。以下内容不构成法律建议。
| 司法管辖区 | 法规/文件 | 状态(2026 年 5 月) | 相关性 |
|---|---|---|---|
| 欧盟 | AI Act,第 50 条 | 透明度义务自 2026 年 8 月 2 日起适用。遗留生成式系统(该日期前投放市场)依据 Digital Omnibus(欧盟委员会 2025 年 11 月提案;共同立法者 2026 年 5 月 7 日政治协议)对第 50(2) 条标记义务享有宽限期至 2026 年 12 月 2 日。第 50 条指南与标记行为准则正于 2026 年定稿。 | 以欺骗为目的移除强制性溯源标记,可能依据各国实施规定受到处罚。 |
| 美国(联邦) | COPIED Act(S. 1396,第 119 届国会) | 2025 年 4 月重新提出;尚未颁布(已提交参议院商务委员会)。 | 若通过,将设定 NIST 溯源标准并禁止篡改/移除溯源信息。工具本身合法;使用方式可能不合法。 |
| 美国(州) | CA AB 2655、TX SB 751(2019)等 | TX SB 751(2019)已生效;CA AB 2655 被联邦法院驳回(加州东区,2025 年 8 月,Kohls v. Bonta),理由为被 Section 230 优先适用;法院未审理第一修正案问题(配套法律 AB 2839 已另案基于第一修正案被禁制)。 | 针对特定内容(选举 deepfake、色情 deepfake)。非针对工具本身。 |
| 美国(州) | CA AB 853(修订 California AI Transparency Act) | 核心提供方义务自 2026 年 8 月 2 日起生效(自 2026 年 1 月 1 日推迟);大型平台 2027 年 1 月 1 日;拍摄设备 2028 年 1 月 1 日。 | 覆盖提供方(月活 100 万+)必须嵌入“永久或极难移除”的隐式披露,并提供免费检测工具。移除该披露正是本工具所做之事。 |
| 韩国 | AI Framework Act(AI 基本法),第 31 条 | 自 2026 年 1 月 22 日起生效(颁布后一年过渡期)。 | 第 31(3) 条:难以与现实区分的 AI 输出必须标注,使用户“清楚识别”;执法令草案接受机器可读(不可见水印)标签。艺术/创意作品享有展示例外。 |
| 中国 | 《人工智能生成合成内容标识办法》(+ GB 45438-2025) | 自 2025 年 9 月 1 日起生效。 | 强制要求显式(可见)+ 隐式(元数据)标签,覆盖图像/音频/视频;禁止篡改、伪造或移除标签。 |
| 印度 | 《信息技术(中介指南与数字媒体道德规范)修正案规则》,2026 | 自 2026 年 2 月 20 日起生效(2026 年 2 月 10 日公布)。 | 所有“合成生成信息”必须显著标注并携带永久元数据/溯源标识符;规则明确禁止修改、压制或移除该标签或元数据。覆盖图像、音频及视听内容。 |
| 英国 | Online Safety Act 2023 / Ofcom 指南 | 已生效,但无法定 AI 溯源或加水印义务。 | Ofcom 鼓励将加水印/溯源元数据作为自愿“归属措施”;属平台义务,非用户义务。 |
威胁模型
本工具会移除特定的、已知的信号:嵌入的 SynthID 像素水印、可见的厂商标记,以及平台用于自动打上「Made with AI」标签所读取的 C2PA / EXIF / IPTC 来源元数据。它并非通用的检测规避工具。它无法击败经过训练的统计式 AI 与真实内容分类器(例如 Hive Moderation),轻度扩散处理也无法可靠地欺骗这类分类器,因此在移除后仍被分类器命中是预期行为,而非缺陷。它也不会追溯性地匿名化生成过程。而且,水印本身是一种薄弱的信任信号:几乎总是存在却又极易移除的标记,可能让被清理过的伪造内容看起来更可信,而非更不可信——这也是持久来源证明更可能来自对真实内容的签名,而非对合成内容加水印的原因。
具体而言,SynthID(Google DeepMind)已嵌入 Google 的生成式媒体技术栈——Imagen(图像)、Veo(视频)、Lyria(音频)——以及 Gemini 应用的图像输出(Nano Banana / Gemini 3 Pro;我们通过 Gemini 应用的 SynthID oracle 验证为阳性);Google 报告称截至 2025 年 12 月已有超过 100 亿项内容被加水印。它携带多比特载荷——研究论文中的 SynthID-O 变体在 512x512 图像中编码 136 比特载荷(arxiv 2510.09263).))。据信该载荷编码的是用户/会话标识符。若原始带水印文件曾经过提示发起方所控制的系统(例如保存的 Gemini 账户历史、上传到 Google 产品的截图、备份),Google 仍能将该原始文件与生成账户关联。从你持有的副本中剥离水印,并不会抹去 Google 的服务端记录。
适用本威胁模型的用例:
- 你自己生成了图像,希望将其作为个人作品发布,并接受 Google 日后公布其检测日志所带来的后果。
- 你正在进行安全/鲁棒性评估。
- 你自己的真实照片经轻度 AI 编辑(例如在 Gemini 或 ChatGPT 中修图)后带有 SynthID 或 C2PA 标签,夸大了其 AI 生成程度,而你希望从自己的副本中清除该标签。
不适用本威胁模型的用例:
- 生成图像后,指望移除水印就能对 Google 实现匿名。这做不到。
- 分发 AI 生成内容却声称是人类创作。水印只是若干可追溯层之一。
本工具面向以下合法用途:
- 隐私保护(移除会泄露用户账户标识符的元数据)。
- 艺术保存与合理使用研究。
- 从经人类编辑的照片中移除误报的「Made with AI」标签。
- 安全研究与水印鲁棒性研究。
谁承担法律责任。 这是通用软件,其发布与运行本身合法;法律责任归于移除标记的人以及结果随后如何被使用,关键在意图。为将 AI 生成内容冒充人类创作、实施欺诈、制作未经同意的 deepfake,或掩盖版权侵权而移除 AI 来源证明,可能使移除者承担法律责任。有两类风险值得了解:
- 下游行为。 欺骗、欺诈、诽谤、知识产权侵权,或违反平台条款——按意图与损害评判,而非按编辑元数据这一行为本身。在美国,DMCA(17 U.S.C. § 1202) 明确禁止出于隐瞒或促成侵权之目的移除「版权管理信息」。
- 移除行为本身。 某些司法管辖区会将篡改标签/元数据本身作为处罚对象,而不论下游用途——尤其包括中国(Labeling Measures)和印度(IT Amendment Rules 2026),二者明确禁止移除或压制 AI 标签与来源元数据。若美国 COPIED Act 获得通过,也将采取相同做法。
合法用途——发布你自己的作品、隐私保护(剥离泄露账户标识符的元数据)、安全/鲁棒性研究,或从经人类编辑的照片中移除误报的「Made with AI」标签——通常合法。用户须自行确保其使用符合所有适用法律。作者不赞成将本工具用于欺骗、欺诈或任何违反适用法律或法规的活动。以上内容不构成法律建议。
License
Apache 2.0. Copyright 2025-2026 wiltodelta.

