小目标、小字不再丢失:claude-real-video 三重通道去重算法深度剖析,每一帧都有据可查
【免费下载链接】claude-real-videoLet Claude (or any LLM) actually watch a video — scene-aware, deduplicated frames + transcript, from a URL or local file. Runs locally, MIT.项目地址: https://gitcode.com/gh_mirrors/cl/claude-real-video
大多数 LLM 其实从没真正"看"过视频——它读的只是字幕。开源工具claude-real-video(命令行名crv)用场景感知抽帧 + 三重通道去重,让小目标、小字不再丢失,把每一帧都变成有时间戳、可引用、有据可查的证据。本文带你拆穿这套"三道关卡"背后的设计思路,不需要读一行源码也能看懂。
为什么"抽帧 + 去重"是 LLM 看懂视频的关键
把视频直接丢给大模型,几乎行不通。主流做法是固定间隔抽帧——比如每秒抓 1 帧。这个办法有个致命矛盾:
- 画面几乎不动的录屏、幻灯片:抽出一堆几乎一模一样的帧,白白塞爆上下文;
- 快速剪辑的短视频:两帧之间一闪而过的关键画面,被直接漏掉。
claude-real-video换了思路:只保留"真正发生了变化"的帧,再把近似重复的帧剔除。于是同一个 58 秒片段,固定 1fps 要喂 58 帧,它只留 26 帧"真正不同"的画面——花更少的 token,却不漏内容。
而"只留真正变化的帧"这件事里,最难的恰恰是去重:既要挡掉重复,又别把"变化很小但很重要"的画面误删。这正是下面三重通道要解决的问题。
claude-real-video 三重通道去重算法:三道关卡逐层放行
算法的全部逻辑集中在 core.py 的dedup_frames函数(core.py#L581-L786)。它不是用一把尺子量所有帧,而是设了三道由粗到细的关卡:一帧先过全局关,不过再试局部关,再不过再看动作关。任何一关放行,这帧就被保留。
它还有个贯穿始终的细节——滑动窗口:每帧不是只跟"上一帧"比,而是跟最近 4 个已保留帧一起比(--dedup-window可调)。这样"镜头 A→B→A"的来回剪辑,也不会把 A 重复发一遍。
第一关 · 全局通道:抓大变化,挡掉重复帧
这是最初的比较器。它把每帧缩成一张16×16 的彩色小签名,逐格数"有多少格颜色变了",超过阈值(默认 8%,--dedup-threshold)就算"新画面"。
它擅长抓大动作:场景切换、镜头移动、人物走动。代价是"以全幅算平均"——只要变化集中在很小一块,摊到 256 格上就趋近 0%,于是被当成重复删掉。
一个容易被忽略的坚持:签名用彩色 RGB而不是灰度。因为"红→绿"这种亮度几乎不变、只有色相变的剪辑,灰度会直接"看不见"。
第二关 · 稳定局部通道:小字、细笔画不再丢失
全局关的"结构性盲区"在 v0.7.4 被补齐:新增稳定局部(settled-local)通道(参数见 core.py#L636-L643)。它换用一张192px 的高清签名专门盯"局部小块",专治细笔触、字幕卡切换、界面小更新这类全局关测出来 0.0% 的变化。
为避免误报,它给自己加了三层护栏:
- ±1 像素位移容差——胶片颗粒、画面抖动这种"整帧微微挪动"不会触发;
- 软 + 硬双重对比——先用宽松阈值(80)找候选,再用严格阈值(105)复核,让"烟雾消散、云影漂移"这类软变化被滤掉,只留下笔画、文字这种硬核心;
- "已稳定"判定 + 冷却——只保留"已经不再继续变"的新状态(而非运动到一半),并且每次放行后短暂抬高门槛再衰减,防止"每停一秒就抢一帧"的持续运动。
修复前,一段缓慢手写动画会被压成 3 帧(只有空白页和完成页,中间的书写过程整段消失);修复后能完整浮现"空白→四分之一→半页→四分之三→写满"的推进——这是"小字不再丢失"最直观的体现。
第三关 · 动作通道:小目标快速运动不再被吞掉
前两关都还带个"比例视角",对帧里占比极小的目标天然不敏感。一个只占画面 0.4% 的小主体,就算它飞一样地动,也永远凑不够"8% 的像素变化"。
v0.7.16 加入动作(action)通道(参数见 core.py#L645-L651):不再看比例,改看"有没有一小撮格子发生了强烈变化"(32×32 签名下 ≥3 格变化 >45/255)。只要有,无论占比多小,直接判为新帧。
合成复现实测:一个 40×90 像素的小主体只在 65 帧的最后 10 帧里快速移动——旧版 10 帧只活 1 帧,加动作通道后10 帧全部保留,完整轨迹不再丢失。
实测对比:修复前后,帧数与"没丢什么"
作者没有只讲故事,benchmark.md 用 7 段不同类型视频做了可复现的对照实验。下面是 v0.7.4 稳定局部通道上线前后的关键数据:
| 测试视频 | 类型 | 修复前保留 | 修复后保留 | 找回了什么 |
|---|---|---|---|---|
| magic-diary-writing | 缓慢手写动画 | 3 | 9 | 中间书写推进过程 |
| jensen-reel-zh | 快剪文字卡 | 3 | 8 | 全部 5 张字幕卡 |
| screen-demo-zh | 屏幕录制 | 6 | 15 | 图表页 + 最终五点总结 |
| jfk-rice | 1962 老胶片 | 53 | 77 | 姿态、旗帜的真实定格 |
| nasa-launch | 火箭发射 | 20 | 28 | 点火/起飞序列更密 |
代价也很坦诚:对颗粒噪点多的老胶片,局部敏感会多保留一些帧(JFK +45%)。作者的原话是"这是修复的代价,用冷却机制压住了"。完整跑分脚本见 run_benchmark.sh,版本演进见 CHANGELOG.md。
每一帧都有据可查:时间戳如何贯穿全流程
标题里的"有据可查"不是口号。每一帧从抽出、去重、限流到改名,源视频时间码全程不丢,最终写进frames.json,每帧带四个字段:
file:文件名(frame_012.jpg)timestamp/timestamp_sec:来自源视频的精确时刻selection_reason:是被哪一关放行的(global/settled/action/scene)
这意味着模型(或你)可以引用frame_012 @ 00:03:41这样的证据,还能对齐transcript.json里的口述时间段,甚至喂给 video-RAG。加--viewer会生成一个本地viewer.html,点任意关键帧即可"从这一刻播放"。
快速上手:一行命令让 LLM 看懂视频
pip install "claude-real-video[whisper]" # 抽帧 + 去重 + 本地语音转文字再给一条视频链接或本地文件路径:
crv "https://www.youtube.com/watch?v=..." --viewer几秒后得到一个干净文件夹:关键帧 + 带时间戳的transcript.txt+MANIFEST.txt。把它丢进 Claude / ChatGPT / Gemini 就能提问。想只分析长视频的一段,加--from 28:00 --to 43:00;想让慢变化动画被捕捉,加--adaptive。想把它交给 Claude Code 自动调用,技能说明见 SKILL.md。
小结
claude-real-video的三重通道去重,本质是给"什么才算新画面"装了三双由粗到细的眼睛:
- 全局关管大变化、挡重复,省 token;
- 稳定局部关管小字、细笔画,治"平均成 0%"的盲区;
- 动作关管小目标快动作,治"占比太小看不见"的盲区。
三道关卡加上贯穿全程的时间戳,让小目标、小字不再丢失,也让每一帧都成为可引用的证据——这才是"让 LLM 真正看懂视频"的地基。
【免费下载链接】claude-real-videoLet Claude (or any LLM) actually watch a video — scene-aware, deduplicated frames + transcript, from a URL or local file. Runs locally, MIT.项目地址: https://gitcode.com/gh_mirrors/cl/claude-real-video
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考