Metadata-Version: 2.4
Name: demark
Version: 0.0.1
Summary: Automatic image watermark detection and removal toolkit (CV + DL methods)
Author-email: akino <6130092+cycleuser@users.noreply.github.com>
License-Expression: GPL-3.0-or-later
Project-URL: Homepage, https://github.com/cycleuser/demark
Project-URL: Repository, https://github.com/cycleuser/demark
Project-URL: Documentation, https://github.com/cycleuser/demark#readme
Project-URL: Changelog, https://github.com/cycleuser/demark/releases
Keywords: watermark,watermark-removal,inpainting,image-processing,opencv,lama,alpha-matting,line-art
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia :: Graphics :: Editors
Classifier: Topic :: Scientific/Engineering :: Image Processing
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.24
Requires-Dist: opencv-python>=4.8
Requires-Dist: scipy>=1.10
Requires-Dist: scikit-image>=0.20
Requires-Dist: Pillow>=10.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Provides-Extra: deep
Requires-Dist: torch>=2.0; extra == "deep"
Requires-Dist: simple-lama-inpainting; extra == "deep"
Provides-Extra: sd
Requires-Dist: torch>=2.0; extra == "sd"
Requires-Dist: diffusers>=0.20; extra == "sd"
Requires-Dist: transformers>=4.30; extra == "sd"

# DeMark

Automatic image watermark detection and removal toolkit. Multiple methods from classic CV to deep learning, pick what fits your watermark type.

## What it does

Detects watermark regions in images and removes them while preserving underlying content. Ten methods are implemented:

| Method | Type | Best for | Lossless? |
|--------|------|----------|-----------|
| `auto` | — | Auto-selects best method | — |
| `cv_telea` | CV inpaint [6] | Small/thin watermarks | No |
| `cv_ns` | CV inpaint [7] | Smooth gradients around watermark | No |
| `fft_notch` | Frequency | Repeating/tiled periodic watermarks | Partial |
| `color_mask` | CV segmentation | Solid-color text (white on photo) | No |
| `edge_inpaint` | Edge + inpaint [5] | Text/logos with sharp edges | No |
| `template` | Template match | Known watermark logo | No |
| `alpha_invert` | Alpha matting [8] | Known watermark + transparency | **Yes** |
| `lama` | Deep learning [1] | Large masked regions | No |
| `sd_inpaint` | Diffusion [2] | Generative content fill | No |
| `precise` | Alpha inversion + line protection | Semi-transparent text on line art | Partial |
| `harmonic` | Multi-scale + auto-optimisation | Any scale, self-tuning | Partial |

## What it does NOT do

- No batch GUI — CLI and Python API only. For a GUI, use IOPaint (23k stars) which wraps LaMa.
- No video watermark removal — for video use ProPainter (sczhou/ProPainter).
- No invisible/digital watermark removal — those require diffusion-based attacks (see [10]).
- `alpha_invert` is the only truly lossless method, and it requires the watermark pattern and alpha to be known.

## Requirements

- Python 3.9+
- OpenCV, NumPy, SciPy, scikit-image, Pillow
- For deep learning methods: `pip install demark[deep]` (LaMa) or `pip install demark[sd]` (Stable Diffusion)

## Installation

```bash
# From PyPI
pip install demark

# Optional deep learning extras (LaMa / Stable Diffusion)
pip install "demark[deep]"      # LaMa inpainting
pip install "demark[sd]"        # Stable Diffusion inpainting

# From source
git clone https://github.com/cycleuser/demark.git
cd demark
pip install -e .
```

## Quick Start

```bash
# Auto-detect and remove
demark remove watermarked.jpg clean.jpg

# Use specific method
demark remove watermarked.jpg clean.jpg --method fft_notch

# Known watermark logo — template matching
demark remove watermarked.jpg clean.jpg --method template --template logo.png

# Known watermark overlay + alpha — lossless removal
demark remove watermarked.jpg clean.jpg --method alpha_invert --watermark wm_overlay.png --alpha 0.4

# Scale-adaptive multi-scale + auto-optimisation (works at any scale)
demark remove watermarked.jpg clean.jpg --method harmonic --bbox 1056 1249 1304 1305

# Just detect the mask
demark detect watermarked.jpg mask.png

# JSON output
demark --json remove watermarked.jpg clean.jpg
```

## Usage

### CLI

```
demark [-V] [-v] [-o OUTPUT] [--json] [-q] <command> ...

Commands:
  remove   <input> <output> [--method M] [--mask M.png] [--template T.png]
                         [--watermark W.png] [--alpha 0.4] [--radius 5]
  detect   <input> <output> [--method auto|edge|color|otsu]
  list-methods
```

### Python API

```python
from demark import remove_watermark, detect_watermark

# Auto remove
r = remove_watermark(input_path="wm.jpg", output_path="clean.jpg")
print(r.success)        # True
print(r.data["method"]) # "edge_inpaint"
print(r.data["elapsed"])# 0.123

# Specific method
r = remove_watermark(
    input_path="wm.jpg",
    output_path="clean.jpg",
    method="fft_notch"
)

# Detect only
r = detect_watermark(input_path="wm.jpg", output_path="mask.png")
print(r.data["coverage"])  # 0.0523
```

### Agent Integration (OpenAI Function Calling)

```python
from demark.tools import TOOLS, dispatch

# Pass TOOLS to your LLM's function-calling API
result = dispatch("demark_remove_watermark", {
    "input_path": "/data/wm.jpg",
    "output_path": "/data/clean.jpg",
    "method": "auto"
})
print(result["success"])  # True
```

## References

| # | Paper | Year | Venue |
|---|-------|------|-------|
| [1] | Suvorov et al., "Resolution-robust Large Mask Inpainting with Fourier Convolutions" | 2021 | WACV 2022 |
| [2] | Rombach et al., "High-Resolution Image Synthesis with Latent Diffusion Models" | 2022 | CVPR |
| [3] | Liu et al., "WDNet: Watermark-Decomposition Network for Visible Watermark Removal" | 2020 | WACV 2021 |
| [4] | Cun & Pun, "Split then Refine: Stacked Attention-guided ResUNets for Blind Watermark Removal" | 2020 | AAAI 2021 |
| [5] | Robinette & Johnson, "Blind Visible Watermark Removal with Morphological Dilation" | 2025 | arXiv:2502.02676 |
| [6] | Telea, "An Image Inpainting Technique Based on the Fast Marching Method" | 2004 | J. Graphics Tools |
| [7] | Bertalmio et al., "Navier-Stokes, Fluid Dynamics, and Image and Video Inpainting" | 2001 | CVPR |
| [8] | Levin et al., "A Closed-Form Solution to Natural Image Matting" | 2006 | IEEE TPAMI |
| [9] | Huo et al., "WMFormer++: Nested Transformer for Visible Watermark Removal" | 2023 | arXiv:2308.10195 |
| [10] | "Vanishing Watermarks: Diffusion-Based Image Editing Undermines Robust Invisible Watermarking" | 2026 | arXiv:2602.20680 |

## Development

```bash
pip install -e ".[dev]"
pytest tests/test_unified_api.py -v
ruff check demark/
```

## License

GPL-3.0
