ShieldMnt / invisible-watermark

python library for invisible image watermark (blind image watermark)
MIT License
1.57k stars 142 forks source link

Bug - dwtDct doesnt work for any image tried - The other two Methods work fine #2

Open amiga-500 opened 3 years ago

amiga-500 commented 3 years ago

I used your test code for reading/writing. I also left it on: dwtDct

No matter what test image i test, when i attempt to read it back i always get back garbled text.

It is only when i switch to the much slower dwtDctSvd or riv that the reading the wm works fine.

Seems its a bug.

Here is the code:

Write:

import cv2 from imwatermark import WatermarkEncoder bgr = cv2.imread('E:/Desktop/white.png') wm = '12345678' encoder = WatermarkEncoder() encoder.set_watermark('bytes', wm.encode('utf-8')) bgr_encoded = encoder.encode(bgr, 'dwtDct') cv2.imwrite('E:/Desktop/white-wm.png', bgr_encoded)

Read: import cv2 from imwatermark import WatermarkDecoder bgr = cv2.imread('E:/Desktop/white-wm.png') decoder = WatermarkDecoder('bytes', 64) watermark = decoder.decode(bgr, 'dwtDct') print('Decoded Message is:' + watermark.decode('utf-8'))

The white.png file is here: https://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Solid_white.svg/1024px-Solid_white.svg.png

When i read the decoded message is always blank

SgtBlade commented 2 years ago

I'm having the same issue. When using the default dwDct I keep getting a Invalid start byte error. I even took the exact code from the example.

  Test.py, line 8, in <module>
    dec = watermark.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
6sKaizen commented 1 year ago

@amiga-500 Thank you for sharing your code test samples. The 1024x1024 PNG file from WikiMedia does indeed return an empty watermark when decoding. Per https://pypi.org/project/invisible-watermark/:

Known defects: Test shows all algorithms do not perform well for web page screenshots or posters with homogenous background color

I created a similar test using your example. Source image is what I call a "Sharpherd" (Shar Pei + German Sheppard). https://s3.amazonaws.com/pet-uploads.adoptapet.com/c/4/0/2258582.jpg

Stability_Diffusion_Test_Watermark_Step1_Encode.py

# Write:
import cv2
from imwatermark import WatermarkEncoder
# bgr = cv2.imread('C:/Users/user/Downloads/white.png')
bgr = cv2.imread('C:/Users/user/Downloads/sharpherd.png')
wm = '12345678'
encoder = WatermarkEncoder()
encoder.set_watermark('bytes', wm.encode('utf-8'))
bgr_encoded = encoder.encode(bgr, 'dwtDct')
# cv2.imwrite('C:/Users/user/Downloads/white-wm.png', bgr_encoded)
cv2.imwrite('C:/Users/user/Downloads/sharpherd-wm.png', bgr_encoded)
print('Message *' + wm + '* Encoded.')

Stability_Diffusion_Test_Watermark_Step2_Decode.py

# Read:
import cv2
from imwatermark import WatermarkDecoder
# bgr = cv2.imread('C:/Users/user/Downloads/white-wm.png')
bgr = cv2.imread('C:/Users/user/Downloads/sharpherd-wm.png')
decoder = WatermarkDecoder('bytes', 64) # 8 x 8 (12345678 is 8 char * 8bits)
watermark = decoder.decode(bgr, 'dwtDct')
print('Decoded Message is: *' + watermark.decode('utf-8') + '*')

Output via miniconda3 and Stability Diffusion Virtual Environment:

(automatic) C:\Users\user\Desktop>python Stability_Diffusion_Test_Watermark_Step1_Encode.py
Message *12345678* Encoded.

(automatic) C:\Users\user\Desktop>python Stability_Diffusion_Test_Watermark_Step2_Decode.py
Decoded Message is: *12345678*

(automatic) C:\Users\user\Desktop>

Hope this helps!

chiragsanghvi1 commented 10 months ago

@6sKaizen : The code executes by adding 'replace in print('Decoded Message is: *' + watermark.decode('utf-8', 'replace') + '*')

But the output is not correct : Decoded Message is: *�0���8*

any idea on how can I fix this? @bt0r

rgill02 commented 10 months ago

Instead of using method 'dwtDct' try using method 'dwtDctSvd' as it seems to be more reliable (at the cost of performance).