Skip to content

Commit 604cc97

Browse files
MatrixAclaude
andauthored
Add visible watermark detection & upgrade invisible watermark confidence (#17)
* Add visible watermark detection and upgrade invisible watermark confidence Implement two key improvements: 1. Visible watermark detection: New detector analyzes image corners for bright text overlays characteristic of Chinese AI disclosure badges (e.g., "AI生成" on Dreamina images). Uses luminance clustering and text-run analysis to identify watermarks with MEDIUM confidence for known AI positions. 2. Invisible watermark confidence upgrade: Invisible watermark signals now report MEDIUM confidence when indicators are exceptionally strong (bit agreement > 0.90, energy spread > 1.0) or when all 3 indicators fire, instead of always reporting LOW confidence. Changes: - New module: src/detector/visible_watermark.rs (bottom-up text detection via corner region analysis) - Enhanced: src/detector/watermark.rs (confidence escalation logic, video frame confidence passthrough) - Enhanced: src/detector/mod.rs (integration of visible watermark detection) - Enhanced: src/known_tools.rs (added "dreamina" pattern) - Added: i18n strings in all 7 locale files - Added: 3 integration tests for visible watermark detection - Added: test fixture (Dreamina image with visible watermarks) Results: - Dreamina image: LOW → MEDIUM (now detects both invisible + visible watermarks) - Sora video: LOW → MEDIUM (exceptionally strong invisible watermark signals) - No false positives on clean images All 67 tests passing. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Fix CI: resolve rustfmt and clippy lint errors Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent 4c1857e commit 604cc97

File tree

13 files changed

+719
-3
lines changed

13 files changed

+719
-3
lines changed

locales/de.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,5 @@ signal_audio_flatness: "Spektrale Flachheit %{value} deutet auf synthetisches Au
6666
signal_wav_info_tool: "WAV INFO %{key} stimmt mit KI-Tool überein: %{value}"
6767
signal_wav_tts_heuristic: "Audioeigenschaften deuten auf TTS hin: Mono %{rate}Hz %{bits}bit"
6868
signal_video_frame_watermark: "Wasserzeichen-Indikatoren in Videobild erkannt (bei %{frame}): %{indicators}"
69+
signal_visible_watermark_badge: "Sichtbares KI-Wasserzeichen-Badge in %{corner} Ecke erkannt (%{indicators})"
70+
signal_visible_watermark_generic: "Sichtbare Textüberlagerung in %{corner} Ecke erkannt (möglicherweise Wasserzeichen)"

locales/en.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,5 @@ signal_audio_flatness: "Spectral flatness %{value} suggests synthetic audio (nat
6666
signal_wav_info_tool: "WAV INFO %{key} matches AI tool: %{value}"
6767
signal_wav_tts_heuristic: "Audio characteristics suggest TTS: mono %{rate}Hz %{bits}bit"
6868
signal_video_frame_watermark: "Video frame watermark indicators detected (at %{frame}): %{indicators}"
69+
signal_visible_watermark_badge: "Visible AI watermark badge detected in %{corner} corner (%{indicators})"
70+
signal_visible_watermark_generic: "Visible text overlay detected in %{corner} corner (possible watermark)"

locales/es.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,5 @@ signal_audio_flatness: "Planitud espectral %{value} sugiere audio sintético (el
6666
signal_wav_info_tool: "WAV INFO %{key} coincide con herramienta de IA: %{value}"
6767
signal_wav_tts_heuristic: "Características de audio sugieren TTS: mono %{rate}Hz %{bits}bit"
6868
signal_video_frame_watermark: "Indicadores de marca de agua detectados en fotograma de video (en %{frame}): %{indicators}"
69+
signal_visible_watermark_badge: "Insignia de marca de agua de IA visible detectada en esquina %{corner} (%{indicators})"
70+
signal_visible_watermark_generic: "Superposición de texto visible detectada en esquina %{corner} (posible marca de agua)"

locales/hi.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,5 @@ signal_audio_flatness: "स्पेक्ट्रल समतलता %{valu
6666
signal_wav_info_tool: "WAV INFO %{key} AI टूल से मेल खाता है: %{value}"
6767
signal_wav_tts_heuristic: "ऑडियो विशेषताएँ TTS का संकेत देती हैं: मोनो %{rate}Hz %{bits}bit"
6868
signal_video_frame_watermark: "वीडियो फ़्रेम वॉटरमार्क संकेतक पाए गए (%{frame} पर): %{indicators}"
69+
signal_visible_watermark_badge: "%{corner} कोने में दृश्य AI वॉटरमार्क बैज पाया गया (%{indicators})"
70+
signal_visible_watermark_generic: "%{corner} कोने में दृश्य टेक्स्ट ओवरले पाया गया (वॉटरमार्क हो सकता है)"

locales/ja.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,5 @@ signal_audio_flatness: "スペクトル平坦度 %{value} は合成音声を示
6666
signal_wav_info_tool: "WAV INFO %{key} がAIツールに一致:%{value}"
6767
signal_wav_tts_heuristic: "音声特性がTTSを示唆:モノラル %{rate}Hz %{bits}bit"
6868
signal_video_frame_watermark: "動画フレームの電子透かし指標を検出(%{frame}時点):%{indicators}"
69+
signal_visible_watermark_badge: "%{corner}コーナーに可視AIウォーターマークバッジを検出(%{indicators})"
70+
signal_visible_watermark_generic: "%{corner}コーナーに可視テキストオーバーレイを検出(ウォーターマークの可能性)"

locales/ko.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,5 @@ signal_audio_flatness: "스펙트럼 평탄도 %{value}는 합성 오디오를
6666
signal_wav_info_tool: "WAV INFO %{key}이(가) AI 도구와 일치: %{value}"
6767
signal_wav_tts_heuristic: "오디오 특성이 TTS를 시사: 모노 %{rate}Hz %{bits}bit"
6868
signal_video_frame_watermark: "비디오 프레임 워터마크 지표 감지 (%{frame} 위치): %{indicators}"
69+
signal_visible_watermark_badge: "%{corner} 모서리에서 가시적 AI 워터마크 배지 감지 (%{indicators})"
70+
signal_visible_watermark_generic: "%{corner} 모서리에서 가시적 텍스트 오버레이 감지 (워터마크 가능성)"

locales/zh-CN.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,5 @@ signal_audio_flatness: "频谱平坦度 %{value} 表明为合成音频(自然
6666
signal_wav_info_tool: "WAV INFO %{key} 匹配 AI 工具:%{value}"
6767
signal_wav_tts_heuristic: "音频特征表明为 TTS:单声道 %{rate}Hz %{bits}bit"
6868
signal_video_frame_watermark: "视频帧水印指标检测到(位于 %{frame}):%{indicators}"
69+
signal_visible_watermark_badge: "在%{corner}角检测到可见AI水印标识(%{indicators})"
70+
signal_visible_watermark_generic: "在%{corner}角检测到可见文字覆盖层(可能为水印)"

src/detector/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub mod filename;
55
pub mod id3_metadata;
66
pub mod mp4_metadata;
77
pub mod png_text;
8+
pub mod visible_watermark;
89
pub mod watermark;
910
pub mod wav_metadata;
1011
pub mod xmp;
@@ -351,6 +352,15 @@ pub fn run_all_detectors(path: &Path, deep: bool) -> FileReport {
351352
}
352353
}
353354
}
355+
// Visible watermark detection (corner badge analysis)
356+
match visible_watermark::detect(path) {
357+
Ok(sigs) => signals.extend(sigs),
358+
Err(e) => {
359+
if std::env::var("AIC_DEBUG").is_ok() {
360+
eprintln!(" [debug] Visible watermark: {}", e);
361+
}
362+
}
363+
}
354364
}
355365
}
356366

0 commit comments

Comments
 (0)