Skip to main content

Invisible & visible watermarking SDK for AI-generated images and video

Project description

clawID

Invisible & visible watermarking SDK for AI-generated images and video.

PyPI Python CI License: MIT

A research project by hawky.ai — the AI content provenance platform.

clawID embeds a UUID-based watermark into images and video frames — invisible to the human eye but detectable by the SDK. Inspired by Google SynthID. Built for AI-generated asset provenance tracking.

Links: PyPI · GitHub · Hugging Face Space · hawky.ai


Features

  • Invisible watermarking via DWT-QIM (Discrete Wavelet Transform + Quantization Index Modulation)
  • Resize-robust mode (algorithm='fm') — survives ±35% resize, JPEG compression, and minor edits
  • Visible watermarking — overlay text/logo with configurable opacity and position
  • Video support — watermark every Nth frame; detect from any single watermarked frame
  • REST API — FastAPI server with /embed and /detect endpoints
  • Storage backends — SQLite, PostgreSQL, MongoDB, Redis
  • CLIclawid embed, clawid detect, clawid embed-video, clawid detect-video

Installation

# Core (images only)
pip install clawid

# With video support
pip install "clawid[video]"

# With REST API
pip install "clawid[api]"

# Everything
pip install "clawid[all]"

Quick Start

Images

from clawid import embed, detect

# Embed invisible watermark
meta = embed(
    source='photo.jpg',
    output_path='photo_wm.png',
    metadata={'uid': 'creator123', 'platform': 'hawky.ai'},
)
print(meta['clawid'])  # e.g. "3f2a1b4c-..."

# Detect
result = detect('photo_wm.png')
print(result['uid'])       # creator123
print(result['platform'])  # hawky.ai

Resize-robust mode

meta = embed(
    source='photo.jpg',
    output_path='photo_wm.png',
    metadata={'uid': 'creator123'},
    algorithm='fm',   # survives ±35% resize
)

Video

from clawid import embed_video, detect_video

meta = embed_video(
    'input.mp4',
    'output_wm.mp4',
    metadata={'uid': 'creator123', 'platform': 'hawky.ai'},
    frame_stride=5,   # watermark every 5th frame
)

result = detect_video('output_wm.mp4')
print(result['uid'])  # creator123

Visible watermark

meta = embed(
    source='photo.jpg',
    output_path='photo_wm.png',
    metadata={'uid': 'creator123'},
    mode='visible',     # or 'both' for invisible + visible
    opacity=0.6,
    position='bottom-right',
)

CLI

# Embed
clawid embed -i photo.jpg -o photo_wm.png --uid creator123 --platform hawky.ai

# Embed (resize-robust)
clawid embed -i photo.jpg -o photo_wm.png --uid creator123 --algorithm fm

# Detect
clawid detect -i photo_wm.png

# Video
clawid embed-video -i input.mp4 -o output_wm.mp4 --uid creator123
clawid detect-video -i output_wm.mp4

# Save to SQLite store on embed, enrich on detect
clawid embed -i photo.jpg -o wm.png --uid creator123 --store sqlite:///clawid.db
clawid detect -i wm.png --store sqlite:///clawid.db

REST API

pip install "clawid[api]"
clawid serve --store sqlite:///clawid.db --port 8000

Endpoints:

Method Path Description
POST /embed Upload image, get back watermarked image + metadata
POST /detect Upload image, get back detected metadata
GET /docs Interactive Swagger UI
# Embed via API
curl -X POST http://localhost:8000/embed \
  -F "file=@photo.jpg" \
  -F "uid=creator123" \
  -F "platform=hawky.ai" \
  --output photo_wm.png

# Detect via API
curl -X POST http://localhost:8000/detect \
  -F "file=@photo_wm.png"

Storage Backends

from clawid.storage import from_uri

# SQLite (local)
with from_uri('sqlite:///clawid.db') as store:
    store.save(meta['clawid'], meta)
    record = store.get(meta['clawid'])

# PostgreSQL
with from_uri('postgresql://user:pass@localhost/mydb') as store:
    store.save(meta['clawid'], meta)

# MongoDB
with from_uri('mongodb://localhost:27017/mydb') as store:
    store.save(meta['clawid'], meta)

# Redis
with from_uri('redis://localhost:6379/0') as store:
    store.save(meta['clawid'], meta)

How It Works

Invisible watermark (DWT-QIM)

The payload (UUID + metadata, CBOR-encoded + CRC-checked) is serialised to bits, then each bit is embedded by quantizing a coefficient in the Haar wavelet LL2 sub-band. Each LL2 coefficient represents a 4×4 pixel block, so a change of delta/16 ≈ 2+ pixels per block — above the uint8 quantization step — making the watermark survive JPEG compression and format round-trips.

Mode Delta PSNR Survives
qim (default) 32 ~51 dB PNG/JPEG q≥75, minor edits
fm (resize-robust) 192 ~36 dB ±35% resize, PNG/JPEG q≥75

Video watermarking

Each video is processed frame by frame. Every Nth frame (frame_stride, default 5) receives the same DWT-QIM watermark with the same clawid UUID. Detection samples up to 10 frames and uses majority vote — detection succeeds as long as at least one watermarked frame survives.


Docker

docker compose up
# API available at http://localhost:8000

Development

git clone https://github.com/Hawky-ai/clawID
cd clawid
pip install -e ".[dev,api,video]"
pytest

Links

PyPI https://pypi.org/project/clawid/
GitHub https://github.com/Hawky-ai/clawID
Hugging Face https://huggingface.co/spaces/Hawky-ai/clawID
hawky.ai https://hawky.ai

License

MIT — Copyright © 2024 hawky.ai

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clawid-0.2.3.tar.gz (39.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

clawid-0.2.3-py3-none-any.whl (35.9 kB view details)

Uploaded Python 3

File details

Details for the file clawid-0.2.3.tar.gz.

File metadata

  • Download URL: clawid-0.2.3.tar.gz
  • Upload date:
  • Size: 39.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.2

File hashes

Hashes for clawid-0.2.3.tar.gz
Algorithm Hash digest
SHA256 ec934a0635c494d08702c9e1f11552ad97bdfda90c9aec2a4d96693fe39961bb
MD5 808df4c854f1c2bf844c839036aa1308
BLAKE2b-256 2912641f5e3e00407ad0cbf773ffe842d84d4acd72426463a4f73a631e2a6466

See more details on using hashes here.

File details

Details for the file clawid-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: clawid-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 35.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.2

File hashes

Hashes for clawid-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 dbb0124627de80d3d000007c52917c8661af7d5fbf15399562cc737927479f48
MD5 460ba158e85d7cb9e2ea95eaef51f244
BLAKE2b-256 1b31dd29d73468cbf6a1d399eaf233a8e4c6e74727b481f14cbdbaea439240ce

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page