mirror of
https://github.com/wiltodelta/remove-ai-watermarks.git
synced 2026-10-14 13:30:55 +02:00
- Lock OpenCV 5 and cap NumPy below 2.4 through uv constraint-dependencies so PaddleX 3.7 keeps resolving; Dependabot ignores mirror the cap. - OpenCV 5 draws Hershey putText glyphs differently, so the Dola and Kling video templates ship as committed OpenCV 4 renders with a recipe script, and the OpenArt alpha recipe now refuses any OpenCV but 4.x. - Break Sora/Veo cross-matches in favor of Veo under valid Google AI-video provenance, and require the full Sora mascot shape for mascot-only matches. - Let the Doubao engine detect marks tinted by saturated backgrounds. - Share C2PA claim-generator, credential-level and vendor-platform helpers, JPEG suffixes and the DCT basis instead of per-module copies. - Log model download failures, document the optional GITHUB_TOKEN, mark the photo and source classifier model cards archived, and refresh the lock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
79 lines
3.0 KiB
Python
79 lines
3.0 KiB
Python
"""Render the frozen OpenCV Hershey-font video templates for Dola and Kling.
|
|
|
|
The video detectors were calibrated against these ``cv2.putText`` silhouettes as
|
|
OpenCV 4.x draws them (byte-identical from 4.8 through 4.14). OpenCV 5 reworked
|
|
text rendering, so the same call yields smaller, heavier glyphs, and the Dola
|
|
gallery clip was then selected as Kling. The package therefore loads committed
|
|
PNGs instead of rendering at import time; this script is the recipe that produced
|
|
them. It refuses to run on any OpenCV other than 4.x.
|
|
|
|
It also renders the independent Dola test fixture: the same text in the other
|
|
Hershey face at a smaller scale, which tests/test_video.py stamps onto a frame to
|
|
check that the detector is not keyed to its own template's exact pixels.
|
|
|
|
Regenerate with:
|
|
uv run --no-project --with 'opencv-python-headless>=4.8,<5' --with numpy \
|
|
python scripts/render_video_hershey_templates.py
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
import cv2
|
|
import numpy as np
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
_ROOT = Path(__file__).resolve().parents[1]
|
|
_ASSETS = _ROOT / "src" / "remove_ai_watermarks" / "assets"
|
|
_FIXTURES = _ROOT / "data" / "fixtures" / "synthetic"
|
|
|
|
# Asset name -> (text, font, canvas width). Every template is drawn at scale 2.2,
|
|
# thickness 3, anti-aliased, with the baseline origin at (2, 72) on a 100 px canvas.
|
|
TEMPLATES = {
|
|
"video_dola_hershey_duplex.png": ("Dola AI", cv2.FONT_HERSHEY_DUPLEX, 400),
|
|
"video_kling_ai_hershey_simplex.png": ("KLING AI", cv2.FONT_HERSHEY_SIMPLEX, 500),
|
|
"video_kling_ai_hershey_duplex.png": ("KLING AI", cv2.FONT_HERSHEY_DUPLEX, 500),
|
|
"video_klingai_hershey_simplex.png": ("KlingAI", cv2.FONT_HERSHEY_SIMPLEX, 500),
|
|
"video_klingai_hershey_duplex.png": ("KlingAI", cv2.FONT_HERSHEY_DUPLEX, 500),
|
|
}
|
|
|
|
|
|
def render(
|
|
text: str,
|
|
font: int,
|
|
width: int,
|
|
*,
|
|
height: int = 100,
|
|
origin: tuple[int, int] = (2, 72),
|
|
scale: float = 2.2,
|
|
thickness: int = 3,
|
|
) -> np.ndarray:
|
|
canvas = np.zeros((height, width), dtype=np.uint8)
|
|
cv2.putText(canvas, text, origin, font, scale, 255, thickness, cv2.LINE_AA)
|
|
ys, xs = np.nonzero(canvas)
|
|
return canvas[ys.min() : ys.max() + 1, xs.min() : xs.max() + 1]
|
|
|
|
|
|
def _write(path: Path, image: np.ndarray) -> None:
|
|
if not cv2.imwrite(str(path), image):
|
|
raise SystemExit(f"failed to write {path}")
|
|
log.info("%s: %dx%d", path.relative_to(_ROOT), image.shape[1], image.shape[0])
|
|
|
|
|
|
def main() -> None:
|
|
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
|
if not cv2.__version__.startswith("4."):
|
|
raise SystemExit(f"OpenCV {cv2.__version__} draws different glyphs; run with OpenCV 4.x")
|
|
for name, (text, font, width) in TEMPLATES.items():
|
|
_write(_ASSETS / name, render(text, font, width))
|
|
fixture = render("Dola AI", cv2.FONT_HERSHEY_SIMPLEX, 150, height=40, origin=(2, 28), scale=0.9, thickness=2)
|
|
_FIXTURES.mkdir(parents=True, exist_ok=True)
|
|
_write(_FIXTURES / "dola_hershey_simplex.png", fixture)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|