告别手动打码:这个开源项目用「持久亮度检测」让静态视频水印自动消失

发布时间:2026/10/31 6:59:06
告别手动打码:这个开源项目用「持久亮度检测」让静态视频水印自动消失

告别手动打码:这个开源项目用「持久亮度检测」让静态视频水印自动消失

视频水印大概是内容创作者和素材使用者最熟悉的“眼中钉”——角落里的台标、频道 ID、文字覆盖层,手动一帧帧打码不现实,直接用模糊又毁画面。GitHub 上有一个名为codex-skill-video-watermark的开源项目,项目地址:

https://github.com/xingguangYan/codex-skill-video-watermark/tree/main

它的思路很巧:不让用户去框水印,而是让算法自己把水印“找”出来,再用 FFmpeg 的delogo滤镜原位修复,最后对输出再做一次检测,给出机器可验证的通过或失败结论。

项目本身是一个Codex skill,也可以完全脱离 Codex 作为独立脚本使用。它不依赖云服务,不引入 scipy 之类的重型库,运行时只需要 FFmpeg 和 Python 3.8+,配上 numpy 和 Pillow 两个轻量包,整条流水线在本地几秒内就能跑完检测,剩下只差一次编码。

核心思路:水印是“永远不变亮”的那个东西

检测水印之所以难,是因为水印长什么样、在哪个位置、什么颜色,事先都不知道。这个项目用一个极简但有效的观察把问题拆开了:

背景里的像素,迟早会在某一帧变暗——镜头切换、画面平移、有东西从前面经过。而水印像素不会,因为水印是每一帧都盖在最上面的。

detect_watermark.py的做法是:先探测视频尺寸和时长,然后在全片均匀抽取 N 帧(默认 18 帧),对每个像素取这些帧中的最小亮度,最后用一个阈值(默认亮度 > 120)把“在所有采样帧里都一直亮着”的像素筛出来,作为水印候选区域。

但这个朴素想法直接落地会撞上两个现实问题,项目的应对也恰好体现了工程上的完成度:

第一,孤立噪点会把水印框撑爆。热像素、静态星点、压缩颗粒同样可能“一直亮着”,单个离群亮点就能把 214×48 的水印框撑到 1075×813。解决方式是:对掩码做8 连通域拆分,丢弃面积小于--min-area(默认 12px)的小块,再从最大的连通域出发,按--gap(默认 64px)的邻近距离把相关块聚成一个水印框,其余组件记为ignored_components,不参与后续处理。

第二,画面本身几乎不动的视频会“误杀”整幅画面。录屏、静态幻灯片这类内容,整幅画面都符合“持久亮度”特征,如果照常修复,等于把整个视频糊掉。项目为此加了两道硬保险:掩码覆盖面积超过 20% 直接判定检测失败;生成的delogo矩形超过 25% 直接中止,连编码都不会启动。

检测结果会以 JSON 形式输出,包含bbox(水印原始边界框)、带 margin 的delogo矩形、合并和忽略的组件数量、以及原始掩码占比,方便人或上游 agent 做合理性检查。

安装与使用:两种模式,一张命令就够

项目仓库地址:

https://github.com/xingguangYan/codex-skill-video-watermark/tree/main

作为 Codex skill 使用时,把video-watermark文件夹放进 Codex 的 skills 目录即可,之后用自然语言描述需求就能触发,例如“remove the watermark from the top-left of this video”。

作为独立脚本使用则更直接,先克隆仓库:

gitclone https://github.com/xingguangYan/codex-skill-video-watermark.git

进入scripts/目录后,核心入口只有一个:

python remove_watermark.py INPUT.mp4 OUTPUT.mp4

这一条命令依次完成检测 → 用带 margin 的delogo矩形做修复 → 对输出重新跑检测确认无持久水印残留,最终返回"verified": true时,说明机器检测层面已经通过。

如果自动检测失败,或者你本来就已知水印位置,可以跳过检测手动指定矩形:

python remove_watermark.py INPUT.mp4 OUTPUT.mp4--x33--y37--w230--h63

四个坐标参数必须一起给出。

参数与边界:它适合做什么,不适合做什么

项目的可调参数不算多,但每个都对应一个明确的工程取舍:

参数作用默认值
--frames采样帧数18
--threshold持久亮度阈值(0–255)120
--margin修复矩形向外扩展的边距8
--gap连通域合并距离64px
--min-area丢弃小噪点的面积下限12px
--region限定检测搜索区域不限定
--crf/--presetx264 质量与速度18 / medium
--no-verify跳过输出复检关闭

需要特别注意的是,这个工具只处理“静态水印”。滚动字幕、脉冲闪烁的 logo 这类动态覆盖层不在能力范围内,因为delogo做的是固定矩形内的像素修复,无法跟踪运动水印。暗色或半透明水印可能低于默认亮度阈值,可以把--threshold降到 90–100 再试。很短的片段采样帧对比空间不足,建议直接在全片上跑检测——检测出的水印框是静态的,对任意截取片段同样适用。

编码方面,视频流会重新编码(滤镜处理后的帧必须重新写入),音频流原样复制,不做二次压缩;-crf 18配mediumpreset 在大多数素材上视觉透明,想压体积可以提到 20–23。如果视频上有多个静态水印,分别用--region限定区域跑检测,再把多个delogo矩形串联在同一条 FFmpeg 命令里即可。

去除结果

仔细看左上角的内容

去除前

去除后

适用场景与小结

这个项目最舒服的用法,是处理素材站下载的带角落台标的视频、频道录播中的固定 overlay、以及需要二次剪辑的带来源标识素材。它不试图用 AI 去“理解”水印,也不依赖任何外部服务,而是把问题收敛到一个统计信号上——每一帧都亮着的东西,就是水印——再用连通域聚类压住噪声,用面积守卫防止误伤整帧,最后用输出复检把“感觉干净了”变成“机器验证干净了”。

代码量不大,依赖极轻,MIT 协议,既可以直接当命令行工具用,也可以作为 Codex skill 嵌入更大的视频处理流程。项目链接再放一次,方便直接收藏:

https://github.com/xingguangYan/codex-skill-video-watermark/tree/main

如果你手上恰好有一批“水印位置固定、但数量多到不想手动处理”的视频,这个项目值得放进工具箱。