Blind&Invisible Watermark ,图片盲水印,提取水印无须原图!
blind-watermark
Blind watermark based on DWT-DCT-SVD.
- Documentation: https://BlindWatermark.github.io/blind_watermark/#/en/
- 文档: https://BlindWatermark.github.io/blind_watermark/#/zh/
- 中文 readme READMEcn.md
- Source code: https://github.com/guofei9987/blind_watermark
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
+ '@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|
|
|
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)
processesnumber of processes, can be integer. DefaultNone, which means using all processes.
Related Project
- textblindwatermark (Embed message into text): https://github.com/guofei9987/textblind_watermark
- HideInfo(hide as image, hide as sounds, hide as text):https://github.com/guofei9987/HideInfo