Skip to the content.

自动视频水印检测与修复

VideoWatermarkRemover.RemoveAsync(inputPath, newOutputDirectory, cancellationToken) 在没有手动请求时执行自动检测。显式 VideoWatermarkRemovalRequest 重载继续按静态二值 PNG 或矩形关键帧处理,不调用检测器。使用方式与部署配置见 Inference README;视频时间线、光流、PCM 音频和整包发布合同见视频区域修复设计。

共享模型协议

自动模式使用已固定版本的 repeated-text UNet++ / EfficientNet-b4 分割权重。watermark_model.py 由图片和视频 worker 共同调用:先按 manifest 的固定长度读取权重快照并校验 SHA-256,再从同一 bytes 通过 torch.load(weights_only=True) 加载,严格映射到 encoder_weights=None 的网络;路径之后被替换也不能改变已验证的模型。没有下载、远程代码、后台服务或请求期间安装包。

图片与视频的检测预处理保持相同:显示校正后的 RGB 画面以 PIL bilinear 缩放至 512×512,默认通道除以 255;ImageNet 配置另用固定均值和标准差。模型 logits 经 sigmoid 后,将概率图以 bilinear 恢复到本帧显示尺寸,按默认 0.5 阈值取二值蒙版。共享协议及模型来源见图片自动检测设计。

权重发布者未明确记录训练时的归一化;RGB/255 是本项目实际执行的 profile,ImageNet 是显式备选。两者没有经过通用准确率校准,不能据一组短样本将任一种描述为作者认证的最佳设置。

每个视频推理进程只建立一个检测网络和一个 MI-GAN session,逐帧复用。前帧、当前帧、后帧仍构成唯一帧状态环;没有将全部画面或蒙版堆积成数组。每帧的实际模型蒙版直接送入已验证的 MI-GAN 与光流链,最终只提交该二值蒙版内像素。没有按示例文本、位置、颜色或字幕类别增加后过滤,也没有把独立图片模型称为学习型视频时序模型。

分数与可复核结果

frame-metadata.json 为每帧记录 maximumProbability、meanProbability、检测 forward 的 inferenceSeconds 和 selectedPixelCount。摘要中的最大值取所有帧的最大值,平均值为帧均值的平均值;固定画面尺寸下也等于所有帧像素概率的均值。inferenceSeconds 只累计 forward,不含 Python 冷启动、模型加载、缩放、修复或编码。

这些是未校准模型分数,不是水印准确率、漏检率或修复质量。普通文字、字幕和场景 Logo 可能被选中;低透明度或训练分布外水印也可能漏选。ReviewRecommended 始终为 true,结果包含原视频引用、完整蒙版预览、首帧原图/蒙版/结果和逐帧记录,方便检查后改用手动请求。

自动与手动模式复用相同源快照、资源限额、方向规则、PTS 量化、音频样本校验和同父目录原子发布。没有配置 Detector 时在读取源视频或建立暂存目录前报配置错误;错误权重、运行库缺失、错误 hash、超时、取消和输出校验失败均阻止发布,不改成模糊、裁剪或虚构蒙版。

重载兼容性

增加第三个参数为 CancellationToken 的重载时,旧的 RemoveAsync(input, output, new() { StaticMaskPath = ... }) 会因 target-typed new 的重载解析规则被错误绑定到取消令牌。自动重载使用 .NET 的 [OverloadResolutionPriority(-1)],在本项目 net10 / C#14 范围内优先保留旧手动重载;两参调用与明确的 CancellationToken 仍选择自动模式。该机制来自 C#13 重载优先级规则,没有加入伪参数或按异常重试另一个模式。

验证边界

固定 RGB/0.5 协议在 512×384 重复文字样本上选中 25,057 个像素,蒙版像素 SHA-256 为 90c6cd861be4c68b89c7c0a2400292a161424c6cb6b247462581945aa1a2710a,与既有图片检测基准逐像素一致。固定权重替换测试从已验证快照加载真实网络,并在多次 forward 中只加载一次模型;相同长度但修改过的文件和截断文件都在反序列化前拒绝。

实际视频验证使用固定与移动文字、无水印场景及正常字幕,覆盖不等间隔 PTS、带偏移且长于视频的音轨、90° 显示矩阵、显式 ImageNet profile、错误权重、超时和取消。字幕是需要保留的负样本:只要模型误选,就会如实产生相应蒙版和修复,测试验证警告与可复核输出,不将它解释为正确去水印。

独立 NuGet PackageReference 消费者发布后,按默认 RGB/0.5 协议实际处理四组 512×384、各 4 帧视频,得到以下记录:

场景 四帧选中 / 修改像素 可见墨迹覆盖或负样本表现 含冷启动与完整校验
移动文字 6,652 / 6,601 每帧覆盖 87.7%–91.5%,仍漏 138–199 个可见墨迹像素 23.38 s
固定重复文字 100,228 / 100,044 覆盖 94.6%,每帧仍漏 1,087 个可见墨迹像素 22.50 s
无水印场景 0 / 0 输出规范化身份画面 16.53 s
正常字幕 6,880 / 6,880 已知误选,选区平均 RGB 变化 98.05 22.35 s

可见墨迹按合成原片相对无水印参考的实际像素差计算,不能推广为真实照片的准确率。移动/固定样本的墨迹区域 MAE 分别从 63.41→5.47、29.62→4.08,但仍有漏选,不能称为完全去除。四组编码后蒙版外 RGB 变化均为零,PTS 为 0,40,140,300 ms;各 24,000 个解码音频样本及 25 ms 起始偏移完整保留。

该次运行每 worker 配置 4 线程,consumer 与其子进程树 RSS 每 20 ms 采样的峰值合计为 1,875,972,096 B,约 1.75 GiB。计时是一次实际运行观测,未要求宿主静默,不能用它承诺吞吐量。线程设置分别约束模型/运行库的并行度,附加线程池仍可能存在;宿主应以共享队列控制跨功能的重任务并发,并按逻辑 CPU 数、总线程预算和模型工作集分配资源。在 6 逻辑 CPU 的机器上同时运行多个 4 线程 worker 会明显争用,不能将各模块的单实例串行等同于全局并发限制。

这些短样本只证明固定后端真实执行和数据合同,不证明通用水印准确率或视频质量。更长视频、快速运动、遮挡、纹理重复和不同编解码器仍需在目标环境验证;现有光流门限也不保证普遍改善闪烁。