GithubHelp home page GithubHelp logo

guofei9987 / blind_watermark Goto Github PK

View Code? Open in Web Editor NEW
5.3K 36.0 638.0 4.47 MB

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

Home Page: https://blindwatermark.github.io/blind_watermark/#/en/

License: MIT License

Python 100.00%
watermark watermark-image blind-watermark image-processing

blind_watermark's Introduction

blind-watermark

Blind watermark based on DWT-DCT-SVD.

PyPI Build Status codecov License Python Platform stars fork Downloads Discussions

install

pip install blind-watermark

For the current developer version:

git clone [email protected]:guofei9987/blind_watermark.git
cd blind_watermark
pip install .

How to use

Use in bash

# embed watermark into image:
blind_watermark --embed --pwd 1234 examples/pic/ori_img.jpeg "watermark text" examples/output/embedded.png
# extract watermark from image:
blind_watermark --extract --pwd 1234 --wm_shape 111 examples/output/embedded.png

Use in Python

Original Image + Watermark = Watermarked Image

origin_image + '@guofei9987 开源**!' = 打上水印的图

See the codes

Embed watermark:

from blind_watermark import WaterMark

bwm1 = WaterMark(password_img=1, password_wm=1)
bwm1.read_img('pic/ori_img.jpg')
wm = '@guofei9987 开源**!'
bwm1.read_wm(wm, mode='str')
bwm1.embed('output/embedded.png')
len_wm = len(bwm1.wm_bit)
print('Put down the length of wm_bit {len_wm}'.format(len_wm=len_wm))

Extract watermark:

bwm1 = WaterMark(password_img=1, password_wm=1)
wm_extract = bwm1.extract('output/embedded.png', wm_shape=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(password_wm=1, password_img=1)
# read original image
bwm1.read_img('pic/ori_img.jpg')
# read watermark
bwm1.read_wm('pic/watermark.png')
# embed
bwm1.embed('output/embedded.png')

Extract watermark:

bwm1 = WaterMark(password_wm=1, password_img=1)
# notice that wm_shape is necessary
bwm1.extract(filename='output/embedded.png', wm_shape=(128, 128), out_wm_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(password_img=1, password_wm=1)
bwm1.read_ori_img('pic/ori_img.jpg')
bwm1.read_wm([True, False, True, True, True, False], mode='bit')
bwm1.embed('output/embedded.png')

Extract:

bwm1 = WaterMark(password_img=1, password_wm=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

blind_watermark's People

Contributors

chy31694 avatar dobmod avatar guofei9987 avatar ilikega avatar mannam95 avatar semikonductor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blind_watermark's Issues

亮度攻击抵抗力较差

这里我做了一下小改动:

wm[i] = wm_extract[:, i::self.wm_size].mean()

本质上是对每个block按bit打上的水印,这里也把每个block提取到的水印由浮点数转为0和1:
wm[i] = (wm_extract[:, i::self.wm_size].mean()>0.5)*1
然后可以将提取到的水印和原始水印做同或得到误码率来评价抗攻击的效果。
最后结论是亮度调低10%攻击下误码率就已达到29%...对比之下裁剪50%和缩放50%下误码率分别是2%和1%。
其实也可以理解,水印嵌在图像的中低频,亮度攻击正是改变了图像的中低频(然而调亮度往往是最常见的修改,比如美图秀秀加个滤镜拉下曝光...)。
不知道po主有无更好的方案,在不改变(或尽量少改变)图像画质的前提下,获得更好的抗亮度攻击的方案呢?或有相关领域的paper可以推荐?

剪裁之后解不出来 水印

你好 我在使用代码进行图片水印嵌入的时候 在测试 剪裁后提取信息时遇到了问题 请问下是我的代码哪里有问题吗?

源图片:
target_color
水印图片:
wm2

代码:

from blind_watermark import WaterMark

bwm1 = WaterMark(password_wm=1, password_img=1)
# read original image
bwm1.read_img('target_color.png')
# read watermark
bwm1.read_wm('wm2.png')
# embed
bwm1.embed('output_color.png')

将获取的 output_color.png 剪裁为 如下:
output_color

再通过以下代码提取信息 :

bwm1 = WaterMark(password_wm=1, password_img=1)
bwm1.extract(filename='output_color.png', wm_shape=(60, 60), out_wm_name='extracted_color_cut.png', )

提取说出来的信息已经变成无法识别了:
extracted_color_cut

关于截屏的attack

关于截屏的attack会失败。大佬这种可以解决吗?
另外有一种跨媒介的技术,比如拍照也可以恢复,我也正在研究中。。。

字符串水印解码的时候出现'utf-8' codec can't decode byte 0xa7 in position问题。

在用文字加密,解密的时候,小图片加密可以正常,但是解密就出现下面的问题:

File "D:\program\Anaconda3\lib\site-packages\blind_watermark-0.2.1-py3.7.egg\blind_watermark\blind_watermark.py", line 73, in extract
wm = bytes.fromhex(hex(int(byte, base=2))[2:]).decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa7 in position 13: invalid start byte

如果是用附例的图片 ori_img.jpg 则没有问题。 同用img方法加水印,也会出现小点的图片出错。
请问下,对图片大小,有要求吗,是否可以设置小于多少象素的图片不打水印? 自动拷贝原图或者不操作?

时间较长

老哥,我4核8G的电脑,打水印需要70秒的时间,占有较高的CPU,希望可以优化一下~

pip install fail

使用阿里的镜像源,没有找到这个包
ERROR: No matching distribution found for blind-watermark

请问源图片有什么要求?有些图片用文字水印解不出来,或者解出来是乱码

import sys; print('Python %s on %s' % (sys.version, sys.platform))
sys.path.extend(['E:\ygSoft\blindWaterMark\blind_watermark-master', 'E:/ygSoft/blindWaterMark/blind_watermark-master'])
PyDev console: starting.
Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)] on win32
runfile('E:/ygSoft/blindWaterMark/blind_watermark-master/examples/origin_str.py', wdir='E:/ygSoft/blindWaterMark/blind_watermark-master/examples')
Put down the length of wm_bit 239
239
x�AE�T
Traceback (most recent call last):
File "", line 1, in
File "E:\pycharm2020.3.2\plugins\python\helpers\pydev_pydev_bundle\pydev_umd.py", line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "E:\pycharm2020.3.2\plugins\python\helpers\pydev_pydev_imps_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "E:/ygSoft/blindWaterMark/blind_watermark-master/examples/origin_str.py", line 21, in
assert wm == wm_extract, '提取水印和原水印不一致'
AssertionError: 提取水印和原水印不一致
1010

缺少包

缺少包,无法安装。ModuleNotFoundError: No module named 'pywt'
image

截图之后保存,解析报错

Traceback (most recent call last):
File "unwm.py", line 4, in
print(bwm.extract('output/test4.png', wm_shape=96, mode='str'))
File "/Library/Python/3.8/site-packages/blind_watermark/blind_watermark.py", line 73, in extract
wm = bytes.fromhex(hex(int(byte, base=2))[2:]).decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xae in position 2: invalid start byte

请问图片要大于多少象素,才可以?

我看了:ori_img.jpg 图是 1920X1200象素,但是我有个图是1080X608,水印同样是128X128象素的。就不行了。就会有如下提示:

File "D:\program\Anaconda3\lib\site-packages\blind_watermark-0.2.1-py3.7.egg\blind_watermark\bwm_core.py", line 30, in init_block_index
'最多可嵌入{}kb信息,多于水印的{}kb信息,溢出'.format(self.block_num / 1000, self.wm_size / 1000))
AssertionError: 最多可嵌入10.26kb信息,多于水印的16.384kb信息,溢出

把图片1080X608放大一倍,变成2160X1216 则就可以正常打水印了。

请问下老哥,原图尺寸,和水印图尺寸,大小有什么要求吗?

解水印报错

image

我用命令行的方式加水印 解水印,用demo没有问题的,
但是我只是将 "watermark text" 改成 "watermark textasd" ,解水印就报错了

py3有版本的兼容问题

Python 3.7.0

Traceback (most recent call last):
  File "origin.py", line 9, in <module>
    bwm1.embed('output/打上水印的图.png')
  File "/.pyenv/versions/3.7.0/lib/python3.7/site-packages/blind_watermark/blind_watermark.py", line 98, in embed
    self.idx_shuffle = np.random.RandomState(self.password_img) \
AttributeError: 'mtrand.RandomState' object has no attribute 'random'

大佬,做了攻击之后还是需要原图大小才能提取水印?

大佬,请教一下!
比如说对图片进行裁剪,裁剪成原来的1/2,如果不还原成原图大小,那么 这样提取出的水印就是错的,所以说在受到不同攻击后,还是需要原图的大小才能提取出水印,请问怎么解决这个问题呢?
还有若是做了旋转攻击,需要知道旋转角度,进行还原,才能提取出水印,在日常中我们不知道受到了怎样的攻击,这个问题咋解决呢?
请大佬指教一下,谢谢🙏

耗时太长了

$ time python3 origin.py
python3 origin.py 15.72s user 10.52s system 162% cpu 16.190 total

只做一个加水印操作,要16秒

String WaterMark -- ValueError: non-hexadecimal number found in fromhex() arg at position 9

(yolov5) ➜  BlindWatermark python
Python 3.7.9 (default, Aug 18 2020, 06:22:45) 
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
(yolov5) ➜  BlindWatermark pip list | grep blind
blind-watermark        0.0.6
(yolov5) ➜  BlindWatermark pip list | grep PyWavelets
PyWavelets             1.1.1
(yolov5) ➜  BlindWatermark cat demo.py 
import argparse
from blind_watermark import WaterMark


if __name__=='__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-in", "--imagePath", type=str, help="the path of source image.")
    parser.add_argument("-wm", "--waterMark", type=str, default='@guofei9987 开源**!', help="the string of watermark.")
    parser.add_argument("-ou", "--imageOutPath", type=str, help="the path of output image.")

    args = parser.parse_args()
    im_path = args.imagePath
    wm_strs = args.waterMark
    im_out_path = args.imageOutPath

    bwm1 = WaterMark(password_img=1, password_wm=1)
    bwm1.read_img(im_path)
    bwm1.read_wm(wm_strs, mode='str')
    bwm1.embed(im_out_path)
    len_wm = len(bwm1.wm_bit)
    print('Embed water mark: {}'.format(wm_strs))
    print('Put down the length of wm_bit {len_wm}'.format(len_wm=len_wm))

    wm_extract = bwm1.extract(im_out_path, wm_shape=len_wm, mode='str')
    print('Extract water mark: {}'.format(wm_extract))
(yolov5) ➜  BlindWatermark python demo.py -in K9290200015200921002_-1_crop.jpg -wm "epbox.cn" -ou K9290200015200921002_-1_crop_embed.jpg
Embed water mark: epbox.cn
Put down the length of wm_bit 63
Traceback (most recent call last):
  File "demo.py", line 24, in <module>
    wm_extract = bwm1.extract(im_out_path, wm_shape=len_wm, mode='str')
  File "/home/tianzx/.virtualenvs/yolov5/lib/python3.7/site-packages/blind_watermark/blind_watermark.py", line 165, in extract
    wm = bytes.fromhex(hex(int(byte, base=2))[2:]).decode('utf-8')
ValueError: non-hexadecimal number found in fromhex() arg at position 9

jpeg

Hi! the watermark disappear with jpeg compression. Do you have any idea how to solve it?

Cannot extract string from jpg correctly

Here is the code

#!/usr/bin/python3

from blind_watermark import WaterMark

print('Embed string...')
bwm1 = WaterMark(password_img=1, password_wm=1)
bwm1.read_img('ori.jpg')
wm = "Just a test - by Syize"
print("Embed string:", wm)
bwm1.read_wm(wm, mode="str")
bwm1.embed('out.jpg')
len_wm = len(bwm1.wm_bit)
print('Put down the length of wm_bit {}\n'.format(len_wm))

print('Extract string...')
wm_extract = bwm1.extract('out.jpg', wm_shape=len_wm, mode="str")
print(wm_extract)

The string is: "Just a test - by Syize"


And here is what the script extracted

Screenshot_20211009_193206

对Mark.png 的大小有限制吗?

运行的时候报错:
assert self.wm_size < self.block_num, IndexError(
AssertionError: 最多可嵌入81.0kb信息,多于水印的750.519kb信息,溢出

裁切、截屏图片水印丢失

使用Windows自带的照片等工具进行裁切生成的图片水印丢失,截屏水印也丢失(使用了anti_cut_att进行补全)

拍照之后可以提取吗?

2

344

from blind_watermark import WaterMark

bwm1 = WaterMark(password_img=1, password_wm=1)
bwm1.read_img('2.jpg')
wm = '@guofei9987 开源**!'
bwm1.read_wm(wm, mode='str')
bwm1.embed('embedded.png')
len_wm = len(bwm1.wm_bit)
print('Put down the length of wm_bit {len_wm}'.format(len_wm=len_wm))

bwm1 = WaterMark(password_img=1, password_wm=1)
wm_extract = bwm1.extract('344.jpg', wm_shape=len_wm, mode='str')
print(wm_extract)

Traceback (most recent call last):
File "C:\Users\yu\Desktop\pic\1.py", line 12, in
wm_extract = bwm1.extract('344.jpg', wm_shape=len_wm, mode='str')
File "C:\Users\yu\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\blind_watermark\blind_watermark.py", line 165, in extract
wm = bytes.fromhex(hex(int(byte, base=2))[2:]).decode('utf-8')
ValueError: non-hexadecimal number found in fromhex() arg at position 1

提取文字水印的时候省略wm_shape是否可行

这段提取文字水印的代码需要基于加水印时的len_wm = len(bwm1.wm_bit),那就得先知道文字水印是什么才可以提取。不知道在原理上是否可以省略提取文字水印时的wm_shape这个值?

bwm1 = WaterMark(password_img=1, password_wm=1)
wm_extract = bwm1.extract('output/embedded.png', wm_shape=len_wm, mode='str')
print(wm_extract)

缺少pywt库支持 lack of pywt lib support

安装模组:pip install blind_watermark, 成功
module install:pip install blind_watermark, SUCCESS

运行示范代码,记录如下:
Run Demo Code, log:

C:\Users\40411>F:\<REDACTED>\加密.py
Traceback (most recent call last):
  File "F:\<REDACTED>\加密.py", line 1, in <module>
    from blind_watermark import WaterMark
  File "C:\Program Files\Python39\lib\site-packages\blind_watermark\__init__.py", line 1, in <module>
    from .blind_watermark import WaterMark
  File "C:\Program Files\Python39\lib\site-packages\blind_watermark\blind_watermark.py", line 9, in <module>
    from pywt import dwt2, idwt2
ModuleNotFoundError: No module named 'pywt'

随后输入pip install pywt, 记录如下:
Run pip install pywt in cmd, log:

C:\Users\40411>pip install pywt
ERROR: Could not find a version that satisfies the requirement pywt
ERROR: No matching distribution found for pywt

目前可用解决方案:使用豆瓣镜像,成功
Current solution: Use Douban mirror, SUCCESS

C:\Users\40411>pip install pywt -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
Looking in indexes: http://pypi.douban.com/simple/
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPConnectionPool(host='pypi.doubanio.com', port=80): Read timed out. (read timeout=15)")': /simple/pywt/
Collecting pywt
  Downloading http://pypi.doubanio.com/packages/36/e7/f66773672b8d6ab98594c0f3116745810b03ba5399647a51985243978914/pywt-1.0.6-py3-none-any.whl (3.7 kB)
Requirement already satisfied: requests in c:\program files\python39\lib\site-packages (from pywt) (2.25.0)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\program files\python39\lib\site-packages (from requests->pywt) (1.26.2)
Requirement already satisfied: idna<3,>=2.5 in c:\program files\python39\lib\site-packages (from requests->pywt) (2.10)
Requirement already satisfied: certifi>=2017.4.17 in c:\program files\python39\lib\site-packages (from requests->pywt) (2020.12.5)
Requirement already satisfied: chardet<4,>=3.0.2 in c:\program files\python39\lib\site-packages (from requests->pywt) (3.0.4)
Installing collected packages: pywt
Successfully installed pywt-1.0.6

微信压缩

大佬,请问有没有办法可以做到抗微信压缩(不发原图)

我有个9856*1400的图片可以嵌入水印,但抗攻击性非常差

如题,稍微抠一点内容就会报如下异常:
imgcodecs\src\loadsave.cpp:738: error: (-215:Assertion failed) !_img.empty() in function 'cv::imwrite'
但代码中提供的图片,或我自己小点的图片,是可以嵌入与提取的,且抗攻击性不错。
不知道作者是否能提供新的解决方法,感谢!

图片质量下降

加水印的一个难题是对源图片的质量破坏,从例子来看,对图片的破坏,还是有点严重,有继续研究对图片质量影响更低的加水印方法吗?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.