把水印藏进奇异值:950 行盲水印库扛住截图压缩,还能溯源谁泄了密(1.3 万 Star)
一句话总结:blind_watermark 是阿里算法工程师郭飞(scikit-opt 作者)用约 950 行 Python 写成的图片盲水印库——把不可见水印用 DWT-DCT-SVD 频域算法藏进图像的奇异值里,提取时无须原图,且能扛住 JPEG 压缩、缩放、截图、旋转、遮挡。它是中文社区的盲水印事实标准、7 年成熟的「小而美 done software」;典型应用是版权保护与「给每个接收者嵌唯一水印」的泄密溯源——后者也带来隐私/合规的双面性。
值得关注的理由
- 「小而美 done software」的典范。约 950 行核心代码、7 年成熟、近 1.3 万 star、近一年几乎零提交却仍以每月百级速度吸星——这是「单一功能做到极致、长期被依赖」的最佳样本,是「done software(功能完整、API 稳定、不是烂尾而是不需要再改)」的活教材。
- 频域盲水印的鲁棒性,是一堂生动的 DSP 课。相比改像素最低位、一压缩就失效的 LSB 隐写,它走 DWT→DCT→SVD,把信息量化嵌入图像的奇异值——这就是它能抗 JPEG 压缩/缩放/截图/旋转/遮挡的根本原因。README 自带「攻击后仍能提取水印」的强可视化证据。
- 「提取无须原图」的盲水印工程。靠读量化级别 + 冗余嵌入 + 多通道平均 + 1D k-means 纠错,无需原图即可还原水印,部署门槛极低。
- 泄密溯源应用有传播性也有思辨空间。给每个接收者嵌入唯一水印,文件/截图泄露后反查泄露源——是企业防泄密/版权维权的实用手段,也触及「无感追踪」的隐私伦理边界。
- 作者血统:郭飞(guofei9987)是阿里算法工程师、scikit-opt(启发式优化,6.6K★)作者、SciPy 贡献者——懂频域变换/SVD/算法的工程师把学术课题做成了人人能
pip install的极简库。
项目展示
README 自带「原图 vs 含水印图(肉眼无差异)」+「各种攻击后仍能提取水印」的鲁棒性演示矩阵:

官方文档站(中英双语):https://blindwatermark.github.io/blind_watermark/;社交卡片兜底:
https://opengraph.githubassets.com/1/guofei9987/blind_watermark
项目画像
| 维度 | 数据 |
|---|---|
| 全名 | guofei9987/blind_watermark |
| 定位 | 图片盲水印库(不可见 + 提取无须原图),DWT-DCT-SVD 频域算法 |
| Star / Fork | 12,958 ⭐ / 1,320 🍴(CSV 抓取 9,963,仍稳定吸星) |
| License | MIT |
| 主语言 | Python(核心 ~950 行);注释比 0.327(高) |
| 代码规模 | 总 1,774 行 / 33 文件;核心 blind_watermark/ 约 950 行 |
| 建库时间 | 2019-07(约 7 年) |
| 维护状态 | done software(提交集中 2020-2022,近一年约 1 次提交,低维护但成熟稳定) |
| 提交 | 147 commit;4 tag(最新 0.2.1,语义化版本) |
| 贡献者 | 11 人,郭飞 guofei9987 绝对主导(~90%) |
| 作者 | 郭飞(阿里算法工程师 · scikit-opt/text_blind_watermark/HideInfo 作者 · SciPy 贡献者) |
| 算法 | DWT(Haar)→4×4 分块→DCT→密码置乱→SVD→QIM 量化嵌入奇异值 |
作者视角
问题发现
数字水印是个经典学术课题(频域变换 + SVD),但学术实现往往门槛高、不易用。郭飞作为懂频域/SVD/优化算法的工程师,把它做成了人人能 pip install、三行 API 上手的极简库。blind_watermark 不是孤立爆款,而是其「隐藏信息」开源主线的一环:配套有 text_blind_watermark(文本盲水印,1.8K★,用零宽字符把水印藏进文字)+ HideInfo(信息隐藏合集),与本库构成「图片 + 文本」盲水印组合拳;另一条主线是 scikit-opt(启发式优化,6.6K★)。
解法哲学
「单一功能做到极致 + 极简易用 + 鲁棒优先」。算法上选频域(DWT-DCT-SVD)而非 LSB,用奇异值量化换鲁棒性;工程上把复杂的频域变换封装进 read_img → read_wm → embed / extract 的极简 API + CLI;文档上中英双语 + 攻击演示矩阵,对中文开发者零门槛。代码紧凑(核心 232 行 bwm_core.py)但注释比 0.327 偏高——算法型作者的「小代码量却扎实」。
背景知识迁移
作者的算法血统(scikit-opt 的优化算法、SciPy 贡献、SVD/频域功底)直接体现在实现里:用 numpy.linalg.svd + cv2.dct + pywt.dwt2 三件套搭频域管线;用 NumPy stride_tricks.as_strided 做零拷贝的 4×4 分块;用 1D k-means 做自适应二值化阈值;用 RandomState(seed) 的置乱做密码加密。这些都是「懂数值计算的工程师」的手法。
战略图景
不追求持续演进,而是把库做成「成熟可依赖的稳定件」——done software。被 HelloGitHub 收录、知乎/CSDN 大量教程围绕它展开,在「盲水印 python」中文搜索里几乎是头部默认答案。同赛道中文小库(linyacool/blind-watermark 傅里叶版 517★ 等)star 量级远低于它——它是中文盲水印的事实标准实现。
核心价值提炼
创新点(工程层面的扎实,而非首创算法)
1. DWT-DCT-SVD 频域盲水印 + QIM 量化嵌入 — 新颖度 3/5 · 实用性 5/5 · 可迁移性 4/5
核心管线(bwm_core.py):图像 BGR→YUV→补偶数白边 → 每通道 DWT(Haar 小波)取低频 ca → stride_tricks 切 4×4 块 → 每块 DCT → 密码置乱系数 → SVD → 把 1 bit 水印量化嵌入最大奇异值:s[0] = (s[0] // d1 + 1/4 + 1/2*wm) * d1(d1=36/d2=20 控鲁棒性 vs 失真)→ 重构 → 逆置乱 → IDCT → 反组装 → IDWT。改奇异值而非像素,是抗压缩/缩放/截图的根本。适用:任何需鲁棒不可见水印的场景。
2. 真·盲提取(无须原图) — 新颖度 3/5 · 实用性 5/5 · 可迁移性 4/5
提取时同样 DWT→分块→DCT→置乱→SVD,靠读量化级别还原 bit:wm = (s[0] % d1 > d1/2)。无须原图比对,部署门槛极低——这是 QIM(量化索引调制)的天然优势。
3. 冗余嵌入 + 多通道平均 + 1D k-means 纠错 — 新颖度 3/5 · 实用性 5/5 · 可迁移性 5/5
水印 bit 被循环冗余嵌入到所有块(wm_bit[i % wm_size])× 3 通道;提取时 extract_avg 对所有冗余副本求平均(抗局部损坏/噪声),再用 one_dim_kmeans 自适应二值化(无固定阈值)。这套「冗余 + 平均 + 自适应阈值」的纠错思路可迁移到任何噪声信道下的信息恢复。
4. 双密码安全 + 攻击模拟/几何恢复工具链 — 新颖度 2/5 · 实用性 4/5 · 可迁移性 3/5
password_wm 置乱水印 bit、password_img 置乱 DCT 系数,缺一不可提取;att.py(225 行)模拟旋转/裁剪/遮挡/缩放/椒盐噪声/亮度/JPEG 压缩等攻击用于鲁棒性测试,recover.py(100 行)做几何攻击后的对齐恢复(裁剪/旋转后填补还原)。
可复用模式
- 频域量化嵌入(QIM on SVD):把信息量化进奇异值而非像素 — 鲁棒不可见水印。
- 冗余循环嵌入 + 多副本平均 + 自适应 k-means 阈值:噪声信道下的信息纠错恢复 — 任何需抗损坏的编解码。
- stride_tricks 零拷贝分块:NumPy
as_strided做高效图像分块 — 图像/矩阵分块处理。 - 密码置乱做轻量加密:
RandomState(seed).argsort置乱系数/数据 — 简单可逆的数据加密。 - 极简三段式 API(read → embed/extract)+ CLI:把复杂算法封装成傻瓜接口 — 任何算法库的易用性设计。
关键设计决策
- 选 YUV + 只对低频 ca 嵌入:转 YUV 后在每通道的 DWT 低频近似系数上嵌入——低频对压缩/缩放更稳定,是鲁棒性的关键选择;补偶数白边处理非整除尺寸,嵌入后裁回原尺寸。Trade-off:低频嵌入鲁棒但容量受限(容量与图片尺寸正相关,#62 报「最多 4.096kb」溢出)。
- fast_mode 取舍:
block_add_wm_fast跳过置乱、只嵌 s[0],更快但鲁棒性/安全性略降;默认 slow mode 置乱 + 嵌 s[0]/s[1]。 - 多进程 pool(pool.py AutoPool):对每块的 SVD 嵌入/提取并行化,支持批量/大图加速。
竞品格局
| 竞品 | 定位 | 优势 | 劣势/差异 |
|---|---|---|---|
| blind_watermark(本项目) | 频域盲水印 Python 库 | 频域鲁棒(抗压缩/截图/几何)、提取无须原图、极简 pip 易用、中文一手文档 | 怕色相/滤镜攻击、怕二次压缩、有容量上限、提取需预知 wm_shape |
| invisible-watermark(ShieldMnt) | 不可见图片水印,SD 给 AIGC 图打水印 | 算法同源(dwtDctSvd)、国际知名、嵌入 SD 生态 | 偏「给生成图打固定标记」、中文文档弱;同源不同命运的对照样本 |
| OpenStego / LSB 类(stegano) | 老牌隐写 / 通用隐写 | 简单、容量大 | LSB 改最低位,一压缩/截图即失效——与频域鲁棒形成最鲜明反差 |
| Digimarc | 商业数字水印(印刷/媒体) | 工业级鲁棒、生态成熟 | 闭源、收费、重型 |
| Google SynthID / C2PA | AIGC 内容水印 / 内容来源标准 | 大厂出品、专为生成内容溯源 / 跨厂商标准 | 闭源绑生态 / C2PA 是元数据(剥离即丢,需水印兜底) |
关键对照轴:① 频域盲水印(鲁棒)vs LSB 隐写(脆弱);② 提取无须原图(盲)vs 需原图比对;③ 开源易用 + 中文文档 vs 商业/标准;④ 通用文件水印 vs AIGC 专用(SynthID/invisible-watermark)。
综合结论——差异化生态位:「频域盲水印 + 鲁棒抗攻击 + 极简 pip 易用 + 中文一手文档」四合一。它与 invisible-watermark 同算法源、不同生态(一个进了 Stable Diffusion 的 AIGC 流水线、一个成了中文社区的通用版权工具),是天然的对照样本。竞争风险:① 项目低维护期(非持续演进),作者主导度极高、社区贡献稀薄;② 鲁棒性有明确边界(见下);③ AIGC 水印赛道被大厂(SynthID)+ 标准(C2PA)卡位,通用库难进入主流 AIGC 溯源体系。生态定位:成熟可依赖的中文盲水印事实标准件。
套利机会分析
- 对要做版权/溯源的开发者:三行 API 即可给图片打不可见水印,
pip install blind_watermark即用;给每个接收者嵌唯一水印做泄密溯源是开箱即用的方案(注意合规,见风险)。 - 对学 DSP/信号处理的人:~232 行
bwm_core.py是一份极佳的 DWT-DCT-SVD 频域水印教学代码——QIM 量化嵌入、盲提取、冗余纠错、置乱加密一应俱全,比论文更易读。 - 对做信息编解码的工程师:「冗余循环嵌入 + 多副本平均 + 1D k-means 自适应阈值」是可迁移到任何噪声信道的纠错范式;
stride_tricks零拷贝分块是 NumPy 性能技巧。 - 对内容创作者:「950 行 1.3 万 Star 的 done software」「频域 vs LSB 的鲁棒性对照」「泄密溯源的技术与伦理」都是有传播力的选题。
风险与不足
- 鲁棒性有明确边界(不可神化):强在抗几何/压缩/截图,但怕色相/滤镜类色彩变换(#136「手机加个滤镜直接全部乱码,目前无解」)、怕社交软件二次压缩/裁剪(#175 微信传一遍可能提取失败)。「实验室鲁棒」与「微信传一遍」之间有 gap。
- 容量硬上限:嵌入容量与图片尺寸正相关,图越小/水印越大越易溢出(#62「最多 4.096kb」)。
- 提取需预知 wm_shape:提取端必须预先知道水印尺寸/长度,对字符串水印尤其反直觉——是新手第一道坎(#107/#126/#28)。
- 画质 tradeoff:嵌入强度(d1/d2)越大鲁棒性越强但失真越明显(#57),频域改奇异值并非完全无损。
- 低维护期:近一年约 1 次提交、作者主导度极高、社区贡献稀薄——是「成熟稳定件」而非「持续演进型」。
- 泄密溯源的 dual-use 与合规(重点):给每人嵌唯一水印追溯泄露源,正向是企业防泄密/版权维权;另一面对「群聊截图溯源」等场景意味着个体在不知情下被追踪,触及隐私/监控伦理。中文语境下《个人信息保护法》对员工信息处理设限,「告知—同意」与最小必要原则是这类落地绕不开的合规线。技术中立,关键在使用方是否透明、是否取得同意、用途是否正当。
行动建议
- 用它:
pip install blind_watermark,WaterMark(password_img, password_wm) → read_img → read_wm → embed;或 CLIblind_watermark --embed --pwd <密码> <图> "<文字>" <输出>。提取记得提供wm_shape。 - 学它:精读
blind_watermark/bwm_core.py(232 行频域水印全流程)——是 DWT-DCT-SVD + QIM + 盲提取 + 纠错的最佳教学样本;att.py/recover.py看鲁棒性测试与几何恢复。 - fork/扩展它:MIT 可自由二次开发;若做溯源系统,配
text_blind_watermark做「图片 + 文本」双重水印。 - 合规先行:用于溯源前评估隐私/合规(告知—同意、最小必要),尤其涉及个人信息的场景。
知识入口
| 入口 | 链接 | 用途 |
|---|---|---|
| GitHub 仓库 | https://github.com/guofei9987/blind_watermark | 源码 / Issue |
| 官方文档站 | https://blindwatermark.github.io/blind_watermark/ | 中英双语用法 + 攻击演示矩阵 |
| DeepWiki | https://deepwiki.com/guofei9987/blind_watermark | AI 架构导览 |
| 核心算法 | 仓库内 blind_watermark/bwm_core.py | DWT-DCT-SVD 频域水印教学代码 |
| 同源对照 | https://github.com/ShieldMnt/invisible-watermark | dwtDctSvd(SD 生态,算法同源) |
| 作者矩阵 | scikit-opt / text_blind_watermark / HideInfo | 理解作者「优化 + 信息隐藏」血统 |
| 作者主页 | https://github.com/guofei9987 / guofei.site | 郭飞(阿里算法工程师) |