对创建和解析不可见图像水印的库进行GPU适配
项目描述
invisible-watermark-gpu
invisible-watermark-gpu
是一个 python 库和命令行工具,用于在图像上创建不可见水印(又称 闪烁图像水印,数字图像水印)。该算法不依赖于原始图像。
注意: 此库是从 invisible-watermark
适配的,旨在优化一些算法的性能和准确性。
安装
与仅CPU版本相比,安装略复杂,因为我们需要确保可以链接到正确的CUDA库。
# find your GPU's gencode here, and set the PYCUDWT_CC environment variable to it
# for example, for an A100, it would be "80" for SM80:
# https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/
export PYCUDWT_CC=80
# also, load your CUDA version and set any and all needed environment variables. this might
# depend on your CUDA version + GPU type. I'm using CUDA 12.1 on an A100
module load cuda/12.1
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/cuda/lib64
export CUDA_PATH=/usr/local/cuda
export PYCUDWT_CC=80
export CUDAHOME=/usr/local/cuda-12.1
# install !
pip install invisible-watermark-gpu --no-cache-dir
在通过此测试之前,您不应继续操作
# without this test passing, your pycudwt package will NOT work properly, and it will
# only output zeros, silently causing you to not be able to decode anything!
python -m pytest -k 'test_pycudwt_installed_correctly'
一旦成功,您就可以开始运行了!
算法
- 默认嵌入方法
dwtDct
速度快,适用于即时嵌入 dwtDctSvd
慢3倍,rivaGan
慢10倍,对于大图像,它们不适用于即时嵌入
准确性
- 尽管我们没有应用任何攻击,但算法 无法保证 100%准确地解码原始水印。
- 已知缺陷:测试表明所有算法在具有单一背景颜色的网页截图或海报上表现不佳
支持的算法
dwtDct: DWT + DCT 变换,将水印位嵌入到块 dct 系数中最大非平凡系数
dwtDctSvd: DWT + DCT 变换,每个块的 SVD 分解,将水印位嵌入到奇异值分解中
- rivaGan: 具有注意力机制的编码器/解码器模型,将水印位嵌入到向量中。
背景
库 API
嵌入水印
- 示例 嵌入 4 个字符(32 位)水印
import cv2
from imwatermark import WatermarkEncoder
bgr = cv2.imread('test.png')
wm = 'test'
encoder = WatermarkEncoder()
encoder.set_watermark('bytes', wm.encode('utf-8'))
bgr_encoded = encoder.encode(bgr, 'dwtDct')
cv2.imwrite('test_wm.png', bgr_encoded)
注意,如果您想避免加载 CUDA 库时的冷启动问题,您需要首先预热 GPU。您可以通过在开始编码图像之前运行以下代码来实现。
from imwatermark import WatermarkEncoder
# only supported for method "dwtDct" currently
WatermarkEncoder().warmup_gpu()
解码水印
- 示例 解码 4 个字符(32 位)水印
import cv2
from imwatermark import WatermarkDecoder
bgr = cv2.imread('test_wm.png')
decoder = WatermarkDecoder('bytes', 32)
watermark = decoder.decode(bgr, 'dwtDct')
print(watermark.decode('utf-8'))
CLI 使用方法
embed watermark: ./invisible-watermark -v -a encode -t bytes -m dwtDct -w 'hello' -o ./test_vectors/wm.png ./test_vectors/original.jpg
decode watermark: ./invisible-watermark -v -a decode -t bytes -m dwtDct -l 40 ./test_vectors/wm.png
positional arguments:
input The path of input
optional arguments:
-h, --help show this help message and exit
-a ACTION, --action ACTION
encode|decode (default: None)
-t TYPE, --type TYPE bytes|b16|bits|uuid|ipv4 (default: bits)
-m METHOD, --method METHOD
dwtDct|dwtDctSvd|rivaGan (default: maxDct)
-w WATERMARK, --watermark WATERMARK
embedded string (default: )
-l LENGTH, --length LENGTH
watermark bits length, required for bytes|b16|bits
watermark (default: 0)
-o OUTPUT, --output OUTPUT
The path of output (default: None)
-v, --verbose print info (default: False)
测试结果
为了更好地阅读文档,我们压缩了本页上的所有图像,但测试是在 1920x1080 的原始图像上进行的。
方法对 调整大小 或宽高比改变的 裁剪 不太鲁棒,但对 噪声、颜色过滤器、亮度 和 JPG 压缩 鲁棒。
rivaGan 在裁剪攻击方面优于默认方法。
只有默认方法适用于即时嵌入。
输入
- 输入图像:1960x1080 图像
- 水印
- 对于频率方法,我们使用 64 位,字符串表达式 "qingquan"
- 对于 RivaGan 方法,我们使用 32 位,字符串表达式 "qing"
- 参数:仅取 U 帧,以保持图像质量,
scale=36
攻击性能
水印图像
攻击 | 图像 | 频率方法 | RivaGan |
---|---|---|---|
JPG 压缩 | 通过 | 通过 | |
噪声 | 通过 | 通过 | |
亮度 | 通过 | 通过 | |
叠加 | 通过 | 通过 | |
掩码 | 通过 | 通过 | |
裁剪 7x5 | 失败 | 通过 | |
调整大小 50% | 失败 | 失败 | |
旋转 30 度 | 失败 | 失败 |
运行速度(仅 CPU)
图像 | 方法 | 编码 | 解码 |
---|---|---|---|
1920x1080 | dwtDct | 300-350ms | 150ms-200ms |
1920x1080 | dwtDctSvd | 1500ms-2s | ~1s |
1920x1080 | rivaGan | ~5s | 4-5s |
600x600 | dwtDct | 70ms | 60ms |
600x600 | dwtDctSvd | 185ms | 320ms |
600x600 | rivaGan | 1s | 600ms |
运行速度(仅 GPU)
待补充:填写此内容!
RivaGAN 实验性
进一步,我们将提供 64 位 rivaGan 模型,并在 GPU 环境中测试其性能。
详情: https://github.com/DAI-Lab/RivaGAN
Zhang, Kevin Alex and Xu, Lei and Cuesta-Infante, Alfredo and Veeramachaneni, Kalyan. Robust Invisible Video Watermarking with Attention. MIT EECS, September 2019.[PDF]
项目详情
散列值 for invisible_watermark_gpu-0.2.4-py3-none-any.whl
算法 | 散列摘要 | |
---|---|---|
SHA256 | fcc0df735431e40ef2a4e6d7188ceb0c6de9ccfb0ffdfff5845dcde928c3412b |
|
MD5 | 485d5cf089a0fe4c2ea6b52e7d1b0947 |
|
BLAKE2b-256 | 9963437436432aa06938bebce63afca649e8d1149c730ef138e56111fa70c8c6 |