guofei9987
blind_watermark
Python

Blind&Invisible Watermark ,图片盲水印,提取水印无须原图!

Last updated Jul 8, 2026
14.1k
Stars
1.4k
Forks
51
Issues
+98
Stars/day
Attention Score
91
Language breakdown
Python 100.0%
Files click to expand
README

blind-watermark

Blind watermark based on DWT-DCT-SVD.

PyPI Build Status codecov License Python Platform stars fork Downloads Discussions Featured|HelloGitHub

install

pip install blind-watermark

For the current developer version:

git clone git@github.com:guofei9987/blind_watermark.git cd blind_watermark pip install .

How to use

Use in bash

# embed watermark into image:
blindwatermark --embed --pwd 1234 examples/pic/oriimg.jpeg "watermark text" examples/output/embedded.png

extract watermark from image:

blindwatermark --extract --pwd 1234 --wmshape 111 examples/output/embedded.png

Use in Python

Original Image + Watermark = Watermarked Image

origin</em>image + '@guofei9987 开源万岁!' = 打上水印的图

See the codes

Embed watermark:

from blind_watermark import WaterMark

bwm1 = WaterMark(passwordimg=1, passwordwm=1) bwm1.readimg('pic/oriimg.jpg') wm = '@guofei9987 开源万岁!' bwm1.read_wm(wm, mode='str') bwm1.embed('output/embedded.png') lenwm = len(bwm1.wmbit) print('Put down the length of wmbit {lenwm}'.format(lenwm=lenwm))

Extract watermark:

bwm1 = WaterMark(passwordimg=1, passwordwm=1) wmextract = bwm1.extract('output/embedded.png', wmshape=len_wm, mode='str') print(wm_extract)
Output: >@guofei9987 开源万岁!

attacks on Watermarked Image

|attack method|image after attack|extracted watermark| |--|--|--| |Rotate 45 Degrees|旋转攻击|'@guofei9987 开源万岁!'| |Random crop|截屏攻击|'@guofei9987 开源万岁!'| |Masks| 多遮挡攻击 |'@guofei9987 开源万岁!'| |Vertical cut|横向裁剪攻击|'@guofei9987 开源万岁!'| |Horizontal cut|纵向裁剪攻击|'@guofei9987 开源万岁!'| |Resize|缩放攻击|'@guofei9987 开源万岁!'| |Pepper Noise|椒盐攻击|'@guofei9987 开源万岁!'| |Brightness 10% Down|亮度攻击|'@guofei9987 开源万岁!'|

embed images

embed watermark:

from blind_watermark import WaterMark

bwm1 = WaterMark(passwordwm=1, passwordimg=1)

read original image

bwm1.readimg('pic/oriimg.jpg')

read watermark

bwm1.read_wm('pic/watermark.png')

embed

bwm1.embed('output/embedded.png')

Extract watermark:

bwm1 = WaterMark(passwordwm=1, passwordimg=1) 

notice that wm_shape is necessary

bwm1.extract(filename='output/embedded.png', wmshape=(128, 128), outwm_name='output/extracted.png', )

|attack method|image after attack|extracted watermark| |--|--|--| |Rotate 45 Degrees|旋转攻击|| |Random crop|截屏攻击|多遮挡_提取水印| |Mask| 多遮挡攻击 |多遮挡</em>提取水印|

embed array of bits

See it here

As demo, we embed 6 bytes data:

wm = [True, False, True, True, True, False]

Embed:

from blind_watermark import WaterMark

bwm1 = WaterMark(passwordimg=1, passwordwm=1) bwm1.readoriimg('pic/ori_img.jpg') bwm1.read_wm([True, False, True, True, True, False], mode='bit') bwm1.embed('output/embedded.png')

Extract:

bwm1 = WaterMark(passwordimg=1, passwordwm=1, wm_shape=6) wm_extract = bwm1.extract('output/打上水印的图.png', mode='bit') print(wm_extract)
Notice that wm_shape (shape of watermark) is necessary

The output wm_extract is an array of float. set a threshold such as 0.5.

Concurrency

WaterMark(..., processes=None)
  • processes number of processes, can be integer. Default None, which means using all processes.

Related Project

© 2026 GitRepoTrend · guofei9987/blind_watermark · Updated daily from GitHub