mirror of
https://github.com/wiltodelta/remove-ai-watermarks.git
synced 2026-08-07 06:28:36 +02:00
style: drop dead Candidate fields, simplify resolve_backend, US spelling
- Candidate carries only the fields the arbiter reads (key, label, detected_strict, detected_relaxed, features); location/region/confidence were vestigial from the removed best_auto_mark max-by-confidence path. - resolve_backend returns preferred_inpaint_backend() directly (typed Literal) instead of an identity ternary. - colour/normalise/behaviour -> US spelling across code comments and docs. No behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
178fed69a7
commit
9756189eaf
@@ -699,7 +699,7 @@ def cmd_erase(
|
||||
"""Erase arbitrary region(s) from an image via inpainting.
|
||||
|
||||
Universal and position-agnostic: removes any logo / watermark / object inside
|
||||
the boxes you pass, regardless of colour or location. Runs on CPU. Use this
|
||||
the boxes you pass, regardless of color or location. Runs on CPU. Use this
|
||||
for marks the dedicated ``visible`` engines (Gemini, Doubao) do not cover.
|
||||
"""
|
||||
from remove_ai_watermarks.region_eraser import erase
|
||||
|
||||
@@ -81,7 +81,7 @@ def feather_weights(width: int, height: int, overlap: int) -> NDArray[Any]:
|
||||
|
||||
Separable linear taper over ``overlap`` pixels from every edge (capped at
|
||||
half the tile so short tiles still taper symmetrically). Strictly positive
|
||||
everywhere, so the normalised blend is well-defined even at an image corner
|
||||
everywhere, so the normalized blend is well-defined even at an image corner
|
||||
that only one tile covers.
|
||||
"""
|
||||
import numpy as np
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Position- and content-agnostic. You supply the rectangle(s); the eraser inpaints
|
||||
whatever is inside, so it removes any visible logo / watermark / object regardless
|
||||
of colour, style, or location. Localisation is the user's responsibility (pass the
|
||||
of color, style, or location. Localization is the user's responsibility (pass the
|
||||
box); restoration runs on CPU. This is the universal fallback for marks the
|
||||
deterministic per-generator engines (Gemini sparkle, Doubao) do not cover.
|
||||
|
||||
@@ -151,7 +151,7 @@ def erase_lama(image_bgr: NDArray[Any], mask: NDArray[Any]) -> NDArray[Any]:
|
||||
crop_mask = mask[cy0:cy1, cx0:cx1]
|
||||
ch, cw = crop.shape[:2]
|
||||
|
||||
# Resize crop + mask to the model size, normalise to [0,1] RGB CHW.
|
||||
# Resize crop + mask to the model size, normalize to [0,1] RGB CHW.
|
||||
crop_rs = cv2.resize(crop, (size, size), interpolation=cv2.INTER_AREA)
|
||||
mask_rs = cv2.resize(crop_mask, (size, size), interpolation=cv2.INTER_NEAREST)
|
||||
img_in = cv2.cvtColor(crop_rs, cv2.COLOR_BGR2RGB).astype(np.float32) / 255.0
|
||||
|
||||
@@ -11,7 +11,7 @@ that mask to ONE shared, swappable fill backend (``region_eraser``: cv2 Telea/NS
|
||||
MI-GAN, or big-LaMa). No mark carries a reverse-alpha step any more: the old
|
||||
``original = (wm - a*logo)/(1-a)`` recovery depended on a fixed captured alpha map
|
||||
at a fixed position, broke whenever a vendor re-rendered or moved its mark, and was
|
||||
not colour-lossless even with the right map (it amplifies quantization/JPEG-chroma
|
||||
not color-lossless even with the right map (it amplifies quantization/JPEG-chroma
|
||||
error by ``1/(1-a)`` -- the "the color just changed, not removed" reports). The
|
||||
localizer stays cheap (cv2/numpy, CPU) so a memory-tight caller can run it on a
|
||||
small worker; the heavy fill (MI-GAN / LaMa) is opt-in and chosen by the caller.
|
||||
@@ -123,11 +123,8 @@ class Candidate:
|
||||
|
||||
key: str
|
||||
label: str
|
||||
location: str
|
||||
region: Region
|
||||
detected_strict: bool
|
||||
detected_relaxed: bool
|
||||
confidence: float
|
||||
features: dict[str, float] # generic; both construction sites always supply it (empty when none)
|
||||
|
||||
|
||||
@@ -279,7 +276,7 @@ def inpaint_model_available() -> bool:
|
||||
return region_eraser.migan_available() or region_eraser.lama_available()
|
||||
|
||||
|
||||
def preferred_inpaint_backend() -> str:
|
||||
def preferred_inpaint_backend() -> Literal["migan", "cv2"]:
|
||||
"""Backend used by the ``auto`` fill: MI-GAN (light, droplet-friendly, the
|
||||
default) when its ONNX runtime is available, else cv2. big-LaMa is NOT auto-
|
||||
selected -- it is a heavier explicit opt-in via ``--backend lama`` (both models
|
||||
@@ -293,7 +290,7 @@ def preferred_inpaint_backend() -> str:
|
||||
def resolve_backend(backend: Backend) -> Literal["cv2", "migan", "lama"]:
|
||||
"""Resolve ``auto`` to the preferred installed backend; pass the rest through."""
|
||||
if backend == "auto":
|
||||
return "migan" if preferred_inpaint_backend() == "migan" else "cv2"
|
||||
return preferred_inpaint_backend()
|
||||
return backend
|
||||
|
||||
|
||||
@@ -494,11 +491,7 @@ def _build_candidates(image: NDArray[Any]) -> list[Candidate]:
|
||||
strict = m.detect(image, provenance=False)
|
||||
relaxed = m.detect(image, provenance=True)
|
||||
feats = m.features(image) if (strict.detected or relaxed.detected) else {}
|
||||
cands.append(
|
||||
Candidate(
|
||||
m.key, m.label, m.location, strict.region, strict.detected, relaxed.detected, strict.confidence, feats
|
||||
)
|
||||
)
|
||||
cands.append(Candidate(m.key, m.label, strict.detected, relaxed.detected, feats))
|
||||
return cands
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user