【视频】解析关键帧/抽取语义帧
背景
视频分析的第二步是基于结构化文本段落,从视频画面中找到与文本内容语义相关的关键帧。
该步骤依赖上一阶段生成的结构化文本:
videos/{video_id}/transcript/transcript_tree.json
本功能只负责解析关键帧和抽取语义帧,不负责生成线框图,也不负责生成最终 Markdown。
目标
实现视频关键帧解析和语义帧抽取功能,包括:
- 使用 FFmpeg 对视频进行 2 秒密集抽帧。
- 对抽帧结果进行图像质量过滤。
- 使用 HSV 色彩直方图 + pHash + 10 秒窗口进行短时间重复帧去重。
- 使用
qwen3-vl-embedding 生成文本段落 embedding 和图片 embedding。
- 计算每个文本段落和每张候选帧之间的 cosine similarity。
- 输出每个文本段落下的原始 2 秒关键帧、语义帧和相似度分数。
前置条件
执行该步骤前,必须已经完成“转写文本(包括结构化文本)”。
需要读取:
videos/{video_id}/transcript/transcript_tree.json
如果结构化文本不存在,则不继续执行语义帧抽取。
实现步骤
1. FFmpeg 2 秒密集抽帧
使用技术:
抽帧规则:
抽帧图片保存路径:
videos/{video_id}/frames/{timestamp_ms}.jpg
文件名示例:
000000000.jpg
000002000.jpg
000004000.jpg
000006000.jpg
这些图片是原始 2 秒关键帧,不是最终语义帧。
2. 图像质量过滤
对 2 秒抽帧后的图片进行基础图像质量过滤。
使用技术:
过滤指标:
使用方法:
Laplacian 方差:判断清晰度
灰度均值:判断亮度
暗像素比例:判断黑屏/过暗
亮像素比例:判断过曝
质量过滤报告保存为:
frame_quality_report.json
存储路径:
videos/{video_id}/frames/frame_quality_report.json
3. HSV + pHash + 10 秒窗口去重
对通过质量过滤的图片进行短时间重复帧去重。
使用技术:
HSV 色彩直方图
pHash 感知哈希
10 秒时间窗口
重复判断规则:
两张图片时间差 <= 10 秒
HSV 色彩直方图相似度 >= 0.92
pHash 汉明距离 <= 6
处理方式:
1. 满足重复条件的帧归入同一个 dedup group。
2. 每个 dedup group 保留质量分最高的一张。
3. 其他重复帧只标记为 duplicate_rejected,不物理删除原始图片。
去重报告保存为:
存储路径:
videos/{video_id}/frames/frame_dedup_report.json
去重后保留下来的代表帧称为:
4. 生成文本段落 embedding
读取结构化文本:
videos/{video_id}/transcript/transcript_tree.json
第一版本只做段落级 embedding,不做句子级 embedding。
文本输入格式:
使用模型:
输出内容:
每个文本段落对应一个 text embedding
5. 生成候选帧图片 embedding
图片侧只处理去重后保留下来的 candidate frames。
图片输入:
使用模型:
输出内容:
每张 candidate frame 对应一个 image embedding
说明:
图片直接使用 FFmpeg 抽帧得到的图片。
默认不裁剪、不增强、不额外做尺寸标准化。
如果没有配置 qwen3-vl-embedding 所需的 API Key,则直接报错,不输出无效的相似度结果。
6. 计算段落和图片的语义相似度
对每个文本段落 embedding 和每张 candidate frame image embedding 计算:
计算范围:
每个文本段落 vs 所有 candidate frames
相似度越高,表示该图片越可能与该文本段落相关。
第一版本不限制每个段落最终选几张图,只输出全部语义匹配结果和相似度分数。
7. 保存语义帧匹配结果
语义帧匹配结果保存为:
semantic_frame_matches.json
存储路径:
videos/{video_id}/frames/semantic_frame_matches.json
该 JSON 中需要包含:
视频 ID
embedding 模型名称
原始 2 秒关键帧数量
candidate frames 数量
文本段落数量
每个文本段落下的原始 2 秒关键帧
每个文本段落下的语义帧
每张语义帧的 similarity 分数
每个文本段落下至少包含:
段落序号
段落标题
段落正文
段落开始时间
段落结束时间
raw_frames
semantic_frames
每张 semantic frame 至少包含:
frame_id
timestamp_seconds
图片路径
similarity
rank
产物汇总
该步骤最终需要生成以下产物:
videos/{video_id}/frames/{timestamp_ms}.jpg
videos/{video_id}/frames/frame_quality_report.json
videos/{video_id}/frames/frame_dedup_report.json
videos/{video_id}/frames/semantic_frame_matches.json
验收标准
- 可以基于视频文件按 2 秒间隔抽取关键帧。
- 可以生成并保存原始 2 秒关键帧图片。
- 可以完成图像质量过滤,并生成:
videos/{video_id}/frames/frame_quality_report.json
- 可以完成 HSV + pHash + 10 秒窗口去重,并生成:
videos/{video_id}/frames/frame_dedup_report.json
- 可以调用
qwen3-vl-embedding 为文本段落和 candidate frames 生成 embedding。
- 可以计算每个文本段落和每张 candidate frame 的 cosine similarity。
- 可以生成并保存:
videos/{video_id}/frames/semantic_frame_matches.json
semantic_frame_matches.json 中能按文本段落看到:
原始 2 秒关键帧
语义帧
similarity 分数
- 第一版本不做线框图生成。
- 第一版本不做最终 Markdown 生成。
- 第一版本不限制每个段落最终选几张语义帧,只输出相似度匹配结果。
【视频】解析关键帧/抽取语义帧
背景
视频分析的第二步是基于结构化文本段落,从视频画面中找到与文本内容语义相关的关键帧。
该步骤依赖上一阶段生成的结构化文本:
本功能只负责解析关键帧和抽取语义帧,不负责生成线框图,也不负责生成最终 Markdown。
目标
实现视频关键帧解析和语义帧抽取功能,包括:
qwen3-vl-embedding生成文本段落 embedding 和图片 embedding。前置条件
执行该步骤前,必须已经完成“转写文本(包括结构化文本)”。
需要读取:
如果结构化文本不存在,则不继续执行语义帧抽取。
实现步骤
1. FFmpeg 2 秒密集抽帧
使用技术:
抽帧规则:
抽帧图片保存路径:
文件名示例:
这些图片是原始 2 秒关键帧,不是最终语义帧。
2. 图像质量过滤
对 2 秒抽帧后的图片进行基础图像质量过滤。
使用技术:
过滤指标:
使用方法:
质量过滤报告保存为:
存储路径:
3. HSV + pHash + 10 秒窗口去重
对通过质量过滤的图片进行短时间重复帧去重。
使用技术:
重复判断规则:
处理方式:
去重报告保存为:
存储路径:
去重后保留下来的代表帧称为:
4. 生成文本段落 embedding
读取结构化文本:
第一版本只做段落级 embedding,不做句子级 embedding。
文本输入格式:
使用模型:
输出内容:
5. 生成候选帧图片 embedding
图片侧只处理去重后保留下来的 candidate frames。
图片输入:
使用模型:
输出内容:
说明:
如果没有配置
qwen3-vl-embedding所需的 API Key,则直接报错,不输出无效的相似度结果。6. 计算段落和图片的语义相似度
对每个文本段落 embedding 和每张 candidate frame image embedding 计算:
计算范围:
相似度越高,表示该图片越可能与该文本段落相关。
第一版本不限制每个段落最终选几张图,只输出全部语义匹配结果和相似度分数。
7. 保存语义帧匹配结果
语义帧匹配结果保存为:
存储路径:
该 JSON 中需要包含:
每个文本段落下至少包含:
每张 semantic frame 至少包含:
产物汇总
该步骤最终需要生成以下产物:
验收标准
qwen3-vl-embedding为文本段落和 candidate frames 生成 embedding。semantic_frame_matches.json中能按文本段落看到: