Official implementation of SafeMark, a framework for watermark-preserving text-guided image manipulation across diverse diffusion-based editing pipelines.
Diffusion-based image editing enables flexible semantic manipulation but often destroys embedded watermarks, undermining image provenance and attribution.
SafeMark integrates watermark preservation directly into the editing process, enabling semantic image manipulation while maintaining watermark integrity across heterogeneous editors.
SafeMark is editing-agnostic and can be integrated into multiple diffusion-based editing frameworks.
- Editing-agnostic watermark preservation
- Plug-and-play with diffusion-based editors
- No watermark fabrication or transfer
- Supports multiple datasets and editing pipelines
/
├── Asyrp/
├── DIffusionCLIP/
├── eff-diff-edit/
├── data/
├── requirements.txt
└── README.md
conda create -n safemark python=3.8
conda activate safemark
pip install -r requirements.txtThe environment was tested with CUDA 11.8. PyTorch is included in requirements.txt; if you need a different CUDA version, install PyTorch manually before running pip install -r requirements.txt:
# Example for CUDA 11.8 (matches requirements.txt)
pip install torch==2.4.1+cu118 torchvision==0.19.1+cu118 --index-url https://download.pytorch.org/whl/cu118Experiments use four datasets: CelebA-HQ, AFHQ-Dog, LSUN-Church, and LSUN-Bedroom.
Watermarked versions (via HiDDeN, Stable Signature, VINE, and SleeperMark) are provided directly under data/. The directory naming convention is:
{dataset}_{method}— images watermarked by the specified method (e.g.,celeba_hid,church_vine,SleepMark/afhq_sleep){dataset}_orig— unwatermarked originals
To obtain the original datasets independently:
- CelebA-HQ: https://github.com/tkarras/progressive_growing_of_gans
- AFHQ-Dog: https://github.com/clovaai/stargan-v2
- LSUN-Church / LSUN-Bedroom: https://github.com/fyu/lsun
All pretrained weights are provided via GitHub Releases. Each release contains three zip archives:
| Archive | Contents | Extract to |
|---|---|---|
pretrained_*.zip |
Base diffusion model weights (per dataset) + watermark decoders | pretrained/ |
checkpoint_*.zip |
Editor weights fine-tuned for example attributes | checkpoint/ |
precomputed_*.zip |
Precomputed DDIM inversion latents for example attributes | precomputed/ |
- DiffusionCLIP: https://github.com/xxxcuss/xvzbdfgs/releases/tag/dclip
- Asyrp: https://github.com/xxxcuss/xvzbdfgs/releases/tag/asyrp
- Eff-Diff: https://github.com/xxxcuss/xvzbdfgs/releases/tag/eff
Download and extract the corresponding archives into each editor's folder:
DIffusionCLIP/
├── pretrained/ ← extract pretrained_diffusionclip.zip here
├── checkpoint/ ← extract checkpoint_diffusionclip.zip here (or train your own)
├── precomputed/ ← extract precomputed_diffusionclip.zip here
├── out/
├── main.py
└── ...
If you use the provided checkpoint_*.zip, you can skip Step 1 below and run SafeMark directly.
Skip this step if using the provided checkpoint weights. To train for a new editing attribute:
cd DIffusionCLIP
python main.py --config celeba.yml --attack False --edit_attr [attribute]Replace celeba.yml with afhq.yml, church.yml, or bedroom.yml as needed. Available attributes are defined in utils/text_dic.py.
cd DIffusionCLIP
python main.py --config celeba.yml --attack True --decoder hid \
--wm_data_path ../data/celeba_hid --edit_attr [attribute]For StableSignature on AFHQ-Dog (example):
cd Asyrp
# Step 1: precompute LPIPS features
python main.py --config custom_sig_afhq.yml --lpips \
--custom_train_dataset_dir ../data/StableSignature/afhq_sig \
--custom_test_dataset_dir ../data/StableSignature/afhq_sig
# Step 2: run SafeMark
python main.py --config custom_sig_afhq.yml --decoder sig \
--wm_data_path ../data/StableSignature/afhq_sig --edit_attr [attribute]cd eff-diff-edit
python main.py --config afhq.yml --attack True --decoder hid \
--wm_data_path ../data/afhq_hid --edit_attr [attribute]Edit the following variables at the bottom of eval365.py, then run:
decoder = 'hid' # hid, sig, sleep, vine
attr = '[edit_attr]' # attribute used during editing
data_path = '[path to watermarked images]'python eval365.pyMetrics include:
- Watermark bit accuracy
- CLIP similarity
- FID
- IS
VINE on LSUN-Church / LSUN-Bedroom:
cd DIffusionCLIP
python main.py --config church.yml --attack False --decoder vine \
--wm_data_path ../data/VINE/church_vine --edit_attr [attribute]
# replace church.yml / church_vine with bedroom.yml / bedroom_vine for BedroomSleeperMark on LSUN-Church / LSUN-Bedroom:
cd DIffusionCLIP
python main.py --config church.yml --attack False --decoder sleep \
--wm_data_path ../data/SleepMark/church_sleep --edit_attr [attribute]Repeat the equivalent commands in the Asyrp/ and eff-diff-edit/ folders for the other editors.
cd DIffusionCLIP
python main.py --config church.yml --attack True --decoder vine \
--wm_data_path ../data/VINE/church_vine --edit_attr [attribute]
# replace church.yml / church_vine with bedroom.yml / bedroom_vine for BedroomRepeat in Asyrp/ and eff-diff-edit/ for the other editors.
Table 3 (SafeMark on HiDDeN, CelebA / AFHQ-Dog)
CelebA:
cd DIffusionCLIP
python main.py --config celeba.yml --attack True --decoder hid \
--wm_data_path ../data/celeba_hid --edit_attr [attribute]AFHQ-Dog:
cd DIffusionCLIP
python main.py --config afhq.yml --attack True --decoder hid \
--wm_data_path ../data/afhq_hid --edit_attr [attribute]Repeat in Asyrp/ and eff-diff-edit/ for the other editors.
LSUN-Church:
cd DIffusionCLIP
python main.py --config church.yml --attack True --decoder sleep \
--wm_data_path ../data/SleepMark/church_sleep --edit_attr [attribute]LSUN-Bedroom:
cd DIffusionCLIP
python main.py --config bedroom.yml --attack True --decoder sleep \
--wm_data_path ../data/SleepMark/bedroom_sleep --edit_attr [attribute]Human (CelebA):
cd DIffusionCLIP
python main.py --config celeba.yml --attack True --decoder sig \
--wm_data_path ../data/StableSignature/celeba_sig --edit_attr [attribute]Dog (AFHQ):
cd DIffusionCLIP
python main.py --config afhq.yml --attack True --decoder sig \
--wm_data_path ../data/StableSignature/afhq_sig --edit_attr [attribute]cd DIffusionCLIP
python main.py --config celeba.yml --attack True --decoder hid \
--wm_data_path ../data/celeba_hid --edit_attr [attribute] \
--p_crop 1.0 # or --p_blur 1.0 / --p_rot 1.0 / --p_res 1.0