Skip to content

Fix SDXL watermark encode so Stability detect.py recovers the bits - #15041

Open
gokay-ai wants to merge 1 commit into
huggingface:mainfrom
gokay-ai:fix/sdxl-watermark-uint8-encode
Open

gokay-ai wants to merge 1 commit into
huggingface:mainfrom
gokay-ai:fix/sdxl-watermark-uint8-encode

Conversation

@gokay-ai

Copy link
Copy Markdown

Summary

Fixes #15025.

StableDiffusionXLWatermarker.apply_watermark was passing float32 pixels in [0, 255] to imwatermark dwtDct encode. Stability's detect.py reads the saved PNG with cv2.imread (uint8), which applies a +128 chroma offset that the float encode path never sees, so about a third of watermarked images fail detection.

This casts to uint8 (round + clip) before encode and restores float32 for the existing torch conversion, matching the uint8 encode path that recovers all 48 watermark bits on the issue repro image.

Test plan

  • pytest tests/pipelines/stable_diffusion_xl/test_stable_diffusion_xl_watermark.py -v (needs invisible-watermark + OpenCV)
  • Manual check: issue repro image goes from 0/48 (float encode) to 48/48 (this change) after PNG round-trip decode

AI assistance was used for implementation and tests; I reviewed the diff and ran the tests above.

Cast images to uint8 before dwtDct encode so chroma matches what
cv2.imread feeds the decoder; Fixes huggingface#15025.

Signed-off-by: GokayAI <60583610+gokay-ai@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 15, 2026 10:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SDXL invisible watermark: apply_watermark encodes float input, and about a third of outputs are not detected by Stability's detect.py

2 participants