mirror of
https://github.com/wiltodelta/remove-ai-watermarks.git
synced 2026-08-06 22:18:36 +02:00
docs: note content-based strip routing + SDXL watermarker fixes
Document both fixes in CLAUDE.md (the metadata.py and watermark_remover.py bullets). Also add a --backend flag to the visible-removal audit script so a realistic quality pass can run the production MI-GAN fill instead of cv2 (removal SUCCESS is backend-independent, but only migan/lama reflect the recovered-region quality a user actually gets). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
183793fbf2
commit
9fe12c3997
@@ -10,6 +10,11 @@ NOT sufficient (their NCC detector is fooled by a thin residual outline -- see
|
||||
CLAUDE.md). Treat a detector-clean Doubao/Jimeng as "detector passes"; visual
|
||||
residual is a separate check.
|
||||
|
||||
Backend: for a REALISTIC quality audit pass ``--backend migan`` (the production
|
||||
fill), not ``cv2``. Removal SUCCESS (detector-clean) is backend-independent, so cv2
|
||||
is fine for a fast pass/fail sweep, but only migan/lama reflect the recovered-region
|
||||
quality a user actually gets. Run migan when validating the visible pipeline for real.
|
||||
|
||||
Operates on gitignored data only (data/spaces/...); writes nothing tracked.
|
||||
|
||||
uv run python scripts/visible_removal_audit.py \
|
||||
@@ -54,7 +59,14 @@ def _rel(p: Path, corpus: Path) -> str:
|
||||
help="Audit only these paths (one per line), skipping the full rglob.",
|
||||
)
|
||||
@click.option("--limit", type=int, default=0, help="Scan at most N files (0 = all).")
|
||||
def main(corpus: Path, out: Path, dataset_root: Path, paths_file: Path | None, limit: int) -> None:
|
||||
@click.option(
|
||||
"--backend",
|
||||
type=click.Choice(["auto", "cv2", "migan", "lama"]),
|
||||
default="auto",
|
||||
help="Fill backend for removal. Removal SUCCESS (detector-clean) is backend-independent; "
|
||||
"cv2 is fastest for a bulk audit, migan/lama only change recovered-region quality.",
|
||||
)
|
||||
def main(corpus: Path, out: Path, dataset_root: Path, paths_file: Path | None, limit: int, backend: str) -> None:
|
||||
logging.basicConfig(level=logging.WARNING, format="%(message)s")
|
||||
if paths_file is not None:
|
||||
files = [Path(s) for line in paths_file.read_text().splitlines() if (s := line.strip()) and Path(s).is_file()]
|
||||
@@ -86,7 +98,7 @@ def main(corpus: Path, out: Path, dataset_root: Path, paths_file: Path | None, l
|
||||
shutil.copy2(p, ddir / p.name)
|
||||
# Remove, then re-detect with the SAME mark's detector.
|
||||
try:
|
||||
cleaned, _ = mark.remove(img)
|
||||
cleaned, _ = mark.remove(img, backend=backend)
|
||||
after = mark.detect(cleaned)
|
||||
except Exception as exc:
|
||||
log.warning("remove failed on %s (%s): %s", p.name, det.key, exc)
|
||||
|
||||
Reference in New Issue
Block a user