blind_watermark教程:三步上手图片盲水印,提取无须原图
【免费下载链接】blind_watermarkBlind&Invisible Watermark ,图片盲水印,提取水印无须原图!项目地址: https://gitcode.com/GitHub_Trending/bl/blind_watermark
你发在网上的照片被人截图、裁剪、加了滤镜之后二次发布,你想证明"这张图是我的",却拿不出证据。贴一个可见的 logo 水印虽然直接,却会毁掉画面。blind_watermark 就是来解决这件事的开源 Python 图片盲水印工具:它把一段文字、一张图或一串比特流隐形地写进照片里,肉眼看不出来,而提取水印时不需要原图,图片被旋转、裁剪、缩放之后依然有机会把水印取回来。
项目速览:能力清单与版本要求
| 项目 | 说明 |
|---|---|
| 定位 | 基于频域的图片盲水印,嵌入不可见,提取无须原图 |
| 水印类型 | 文字(str)、图片(img)、比特流(bit)三种模式 |
| 平台支持 | Windows / Linux / macOS |
| Python 版本 | >= 3.5 |
| 主要依赖 | numpy、opencv-python、PyWavelets |
| 开源协议 | MIT |
| 当前版本 | 0.4.4(嵌入与提取请使用同一版本) |
| 使用方式 | Python API + 命令行工具blind_watermark |
| 并行处理 | 可通过processes参数指定线程数,默认用满全部线程 |
上手路径:从安装到第一次产出盲水印
整个流程很短:装包、嵌入、提取,三步就能跑通。
第一步,安装
pip install blind-watermark如果想用最新开发版本,也可以先克隆仓库再本地安装:
git clone https://gitcode.com/GitHub_Trending/bl/blind_watermark cd blind_watermark pip install .第二步,第一次嵌入并提取
仓库在 examples/ 目录下提供了现成的测试图片(如examples/pic/中的样图),你可以直接拿它跑下面的最小示例:
from blind_watermark import WaterMark bwm = WaterMark(password_img=1, password_wm=1) bwm.read_img('pic/ori_img.jpeg') bwm.read_wm('my first blind watermark', mode='str') bwm.embed('output/embedded.png') bwm1 = WaterMark(password_img=1, password_wm=1) print(bwm1.extract('output/embedded.png', wm_shape=len(bwm.wm_bit), mode='str'))运行后output/embedded.png看起来和原图几乎没有区别,打印出来的却正是你写入的那段文字。不想写代码的话,也可以直接敲命令行:嵌入用blind_watermark --embed --pwd 1234 图片 水印文字 输出文件,提取时用--extract并加上--wm_shape指定水印长度,命令行参数细节可以看 blind_watermark/cli_tools.py。
水印鲁棒性验证:图片被加工后还能不能取出来
这是用盲水印前最该问的问题。仓库把答案做成了可复现的脚本 examples/example_str.py:先嵌入一句文字水印,然后依次施加旋转、随机截屏(裁剪+缩放)、多遮挡、裁剪、缩放、椒盐噪声、亮度变化七种攻击,再逐一提取,每一步都有assert断言提取结果与原文一致。官方给出的对照结果里,这几种攻击下的提取结果全部与原水印吻合。
需要说明的是,鲁棒性不是无条件的。旋转后的图需要先反向旋转回正,裁剪或截屏后的图需要先恢复到原图尺寸(仓库提供了recover_crop和estimate_crop_parameters,后者能在不知道裁剪参数时自动估计),然后再提取。也就是说:轻度到中等程度的加工扛得住,但提取前通常要先做一步"还原"。
盲水印是怎么做到的:原理通俗化
把图片想象成一块布料。可见水印相当于把标签印在布面上,一眼就能看到;盲水印则是把信息织进布料的纹路里。
具体做法是:先把图片切成 4x4 的小块,对每个小块做离散小波(DWT)和离散余弦(DCT)变换把数据搬到频域,再通过奇异值分解(SVD)把水印的每一比特写进奇异值上一丁点人眼察觉不到的偏移里。密码的作用有两层:一是打乱每个块内部系数的读取顺序,二是打乱水印比特本身的存放顺序。所以即使有人拿到图片,不知道密码也读不出你藏了什么;而图片被旋转、缩放后,只要把块找回来,纹路还在,信息就能重新读出。
代码地图:看懂三个文件就够
- blind_watermark/blind_watermark.py:
WaterMark类,对外接口都在这。read_img读图、read_wm读水印(支持 str/img/bit 三种模式)、embed嵌入、extract提取。 - blind_watermark/bwm_core.py:核心算法本体。逐块做 DWT→DCT→SVD 嵌入,三个颜色通道各自嵌入再求平均,提取时用一维 K-means 卡阈值,还内置了并行处理。
- blind_watermark/att.py:攻击模拟工具,实现旋转、裁剪、遮挡、椒盐、缩放、亮度等攻击函数;配套的 blind_watermark/recover.py 负责裁剪参数估计与图片还原,两者配合完成了前面提到的鲁棒性测试。
落地场景:盲水印能做的几件事
- 版权自证:把"作者ID+编号"作为文字水印写进每张对外发布的图,被搬运时提取水印即可证明出处。
- 内容溯源:给不同渠道、不同期数的素材写入不同的隐藏编号,就能追踪内容是从哪条链路流出去的。
- 防伪验证:产品图、证书图、票据图里预先埋入校验信息,验真时提取比对,不需要保留原始底图。
- 数据通道:用 bit 模式在图片里夹带少量二进制数据,适合做轻量级的信息隐藏实验。
⚠️ 避坑提醒:参数、版本与常见失败原因
- 密码必须成对一致:
password_img和password_wm在嵌入和提取时要完全相同,换一个密码提取出来就是乱码。 wm_shape不能忘:提取时必须传水印长度(文字模式就是len(bwm.wm_bit),图片模式是(高, 宽),比特模式是位数),传错长度结果必错。- 嵌入与提取用同一版本:程序启动时会提示版本信息,混用不同版本可能导致不兼容。
- 水印太长会溢出:可嵌入的比特数取决于图片能切出多少块,水印比容量大时
embed会直接报溢出错误——换更大的图或缩短水印。 - 先还原,再提取:对旋转、裁剪、截屏过的图,要先反向旋转或用
recover_crop恢复到原尺寸再提取,否则成功率会明显下降。 - 少做有损压缩:
embed支持输出 JPEG 时指定压缩质量,反复有损压缩会累积失真,能存 PNG 就存 PNG。
适合谁:一句收尾
如果你是需要给作品留一手版权证据的个人创作者,或者想在自己项目里快速集成一个免原图提取的图片盲水印的开发者,blind_watermark 的 API 和示例脚本都足够你半天内上手。它不是绝对防伪造的手段,而是一把应对常规加工的可靠工具:用之前,按仓库里的攻击脚本自己跑一遍,心里就有数了。
【免费下载链接】blind_watermarkBlind&Invisible Watermark ,图片盲水印,提取水印无须原图!项目地址: https://gitcode.com/GitHub_Trending/bl/blind_watermark
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考