Skip to main content

invisible-watermark-gpu

PyPI

invisible-watermark-gpu is a python library and command line tool for creating invisible watermark over image (a.k.a. blink image watermark, digital image watermark). The algorithm doesn't rely on the original image.

Note that this library is adapted from invisible-watermark in an attempt to optimize the performance and accuracy of a few of the algorithms.

Installation

It's a little more complex than the CPU-only version since we need to make sure we can link to the proper CUDA libraries.

# 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

You should NOT proceed until this test passes:

# 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'

Once that works, you should be off to the races!

ALgorithms

supported algorithms

speed

  • default embedding method dwtDct is fast and suitable for on-the-fly embedding
  • dwtDctSvd is 3x slower and rivaGan is 10x slower, for large image they are not suitable for on-the-fly embedding

accuracy

  • The algorithm cannot guarantee to decode the original watermarks 100% accurately even though we don't apply any attack.
  • Known defects: Test shows all algorithms do not perform well for web page screenshots or posters with homogenous background color

Supported Algorithms

  • dwtDct: DWT + DCT transform, embed watermark bit into max non-trivial coefficient of block dct coefficents

  • dwtDctSvd: DWT + DCT transform, SVD decomposition of each block, embed watermark bit into singular value decomposition

  • rivaGan: encoder/decoder model with Attention mechanism + embed watermark bits into vector.

background:

Library API

Embed watermark

  • example embed 4 characters (32 bits) watermark
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)

Note that if you want to avoid the cold start problem of loading CUDA libraries, you'll need to warmup the GPU first. You can do this by running the following code before you start encoding images:

from imwatermark import WatermarkEncoder

# only supported for method "dwtDct" currently
WatermarkEncoder().warmup_gpu()

Decode watermark

  • example decode 4 characters (32 bits) watermark
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 Usage

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)

Test Result

For better doc reading, we compress all images in this page, but the test is taken on 1920x1080 original image.

Methods are not robust to resize or aspect ratio changed crop but robust to noise, color filter, brightness and jpg compress.

rivaGan outperforms the default method on crop attack.

only default method is ready for on-the-fly embedding.

Input

  • Input Image: 1960x1080 Image
  • Watermark:
    • For freq method, we use 64bits, string expression "qingquan"
    • For RivaGan method, we use 32bits, string expression "qing"
  • Parameters: only take U frame to keep image quality, scale=36

Attack Performance

Watermarked Image

wm

Attacks Image Freq Method RivaGan
JPG Compress wm_jpg Pass Pass
Noise wm_noise Pass Pass
Brightness wm_darken Pass Pass
Overlay wm_overlay Pass Pass
Mask wm_mask_large Pass Pass
crop 7x5 wm_crop_7x5 Fail Pass
Resize 50% wm_resize_half Fail Fail
Rotate 30 degress wm_rotate Fail Fail

Running Speed (CPU Only)

Image Method Encoding Decoding
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

Running Speed (GPU Only)

TODO: fill this in!

RivaGAN Experimental

Further, We will deliver the 64bit rivaGan model and test the performance on GPU environment.

Detail: 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]

Metadata

Release files for invisible-watermark-gpu 0.2.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for invisible-watermark-gpu 0.2.4
File Size Uploaded
invisible-watermark-gpu-0.2.4.tar.gz 1.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for invisible-watermark-gpu 0.2.4
File Interpreter ABI Platform
invisible_watermark_gpu-0.2.4-py3-none-any.whl Python 3 none any Details

Total release size: 3.3 MB

Release files / invisible-watermark-gpu-0.2.4.tar.gz

Download URL invisible-watermark-gpu-0.2.4.tar.gz
Size 1.6 MB
Tags Source
SHA-256 checksum
How to use checksums
93022965d4db5a58273eda0f5c7c10761e6812d257894496c5ad5b9389cb89fc
BLAKE2b-256 checksum
How to use checksums
2eacd12a783a1c433cd5b25a3f88747b0d4251276cacc99f8c85fb7597450b28
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.18

Release files / invisible_watermark_gpu-0.2.4-py3-none-any.whl

Download URL invisible_watermark_gpu-0.2.4-py3-none-any.whl
Size 1.6 MB
Tags Python 3
SHA-256 checksum
How to use checksums
fcc0df735431e40ef2a4e6d7188ceb0c6de9ccfb0ffdfff5845dcde928c3412b
BLAKE2b-256 checksum
How to use checksums
9963437436432aa06938bebce63afca649e8d1149c730ef138e56111fa70c8c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.18

Release history Release notifications | RSS feed

This release

0.2.4 This release

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page