视频字幕自动定位的算法迭代之路:从 30% 到 83% 的六版演进

最近在做短剧视频翻译的 PoC,遇到一个看起来简单实际很烦的问题——字幕擦除。你要先知道字幕在画面里的具体位置,才能擦掉原文贴上译文。

这篇文章记录我在两周内迭代六版算法的完整过程,从纯传统 CV 到纯视觉大模型再到混合方案,每一版的思路、代码和测试数据都在。

完整代码已开源:aws-samples/sample-for-video-subtitle-detection-via-nova-2-lite

问题定义

短剧视频帧里的文字至少有四类:

  • 对白字幕:白色/黄色,画面 55%~85% 位置(这是我们要定位的)
  • 底部推广条:品牌 logo + 彩色文字,85%~97%
  • 顶部标题:片名、章节号
  • APP UI 截图帧:满屏文字

目标很明确:精确定位对白字幕的上下边界,偏差 ≤5% 视为准确。测试集 30 个短剧视频。

第一版:传统 CV 流水线(准确率 30%)

思路很直接:在画面 55%~85% 的 ROI 区域做颜色阈值检测。

roi = img[int(h * 0.50):int(h * 0.88), :]
# 白色文字检测:灰度二值化
_, bright = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)
# 黄色文字检测:HSV 空间过滤
yellow = cv2.inRange(hsv, (10, 80, 180), (45, 255, 255))
# 形态学膨胀连接相邻字符 → 轮廓检测 → 过滤条件:宽度>25%画面且居中

流水线:二值化 → 膨胀 → 轮廓检测 → 宽高比+位置过滤。

失败分析:上边界经常偏低——衣服花边、地板反光这种亮色区域被误检成字幕行。下边界偏高——推广条的白色文字和字幕颜色一样,传统 CV 分不开。7 个视频直接漏检(无字幕帧被跳过)。

传统 CV 的上限就在这里:它只看像素,不理解语义。

第二版:纯视觉大模型(准确率 30%)

换 Amazon Nova 2 Lite 试试。踩了个大坑:一开始让模型直接返回百分比("字幕在画面的百分之多少"),结果很不稳定。

后来发现 Nova 支持物体检测的 bounding box 格式(0-1000 坐标空间),切换后效果大幅改善:

Detect all [dialogue subtitle (white or yellow text showing what characters
are speaking, located in the lower half of the video frame)] in this image.
For each detected object, output the class label and bounding box coordinates
in the format [x1, y1, x2, y2], scaled between 0 and 1000.
Output as JSON: [{"label": "class", "bbox": [x1, y1, x2, y2]}]

这里有个重要发现:Nova 的上边界很准(偏差 ≤3%),但下边界经常到 0.90 以上,推广条也被框进去了。

模型的问题跟传统 CV 正好相反:语义理解强但空间定位的边界不够精确。

第三、四版:互补取交集(准确率 53%)

既然 OpenCV 下边界紧、Nova 上边界准,取交集就行:

top = max(ocv_top, nova_top)
bot = min(ocv_bot, nova_bot)

准确率从 30% 跳到 53%。方向验证了——传统 CV 和视觉大模型的误差模式互补

但 53% 还是不够,问题出在两方面:(1) 固定抽帧策略命中率低,(2) 推广条干扰仍然存在。

第五版:智能抽帧 + 边界约束(准确率 80%)

三个优化同时加:

优化 1:智能抽帧。之前固定在 10%/30%/50%/70%/90% 位置各抽一帧,但很多帧是过场画面根本没字幕。改成从 5% 开始每隔 5% 扫描,用 OpenCV 快速判断有没有字幕,收集到 5 帧有效帧才停:

for pct in range(5, 96, 5):
    if len(good_frames) >= 5:
        break
    img = cv2.imread(str(frame_path))
    if img is not None and ocv_detect(img):
        good_frames.append(frame_path)

OpenCV 这里变成了预筛选器而非定位器,发挥了它速度快的优势。

优化 2:下边界封顶 0.85。统计 30 个视频的人工标注数据,对白字幕几乎不会出现在画面 85% 以下。85% 以下基本都是推广条。这条硬规则消除了一大类误检。

优化 3:多帧聚合。上边界取所有帧最小值 -2%(留余量),下边界取最大值 +2% 但不超过 0.85。

准确率直接从 53% 到 80%。

第六版:裁剪后再检测(准确率 83%)

这是整个迭代中收益最高的一步改进。

第五版的残余问题:Nova 在全帧检测时,画面底部的推广条仍然会干扰下边界。我想了个办法——把画面裁剪到只剩 50%~85% 的区域再送进 Nova

CROP_TOP, CROP_BOT = 0.50, 0.85
crop = img[int(h * CROP_TOP):int(h * CROP_BOT), :]

# 调用 Amazon Bedrock
bedrock = boto3.client("bedrock-runtime", region_name="us-east-1")
resp = bedrock.invoke_model(modelId="us.amazon.nova-2-lite-v1:0", ...)

# 坐标映射回全帧
span = CROP_BOT - CROP_TOP  # 0.35
full_top = CROP_TOP + (crop_y1 / 1000) * span
full_bot = CROP_TOP + (crop_y2 / 1000) * span

裁剪做了两件事:(1) 去掉了推广条和顶部标题的视觉干扰,(2) 放大了字幕区域,提高了模型的定位精度。

数据验证:Nova 单独准确率从 63%(全帧)→ 80%(裁剪后),结合 OpenCV 到 83%。

完整对比数据

方法 ≤5% 准确率 偏差大 漏检
OpenCV 单独 12/30 (40%) 18 0
Nova 全帧 bbox 19/30 (63%) 11 0
裁剪 bbox 单独 24/30 (80%) 6 0
OCV + Nova 全帧 24/30 (80%) 6 0
OCV + 裁剪 bbox 25/30 (83%) 5 0

额外对比了 Claude Sonnet 4.6 做视觉检测,9/30(30%)。Claude 下边界几乎都超过 85%,不支持 bbox 格式,在精确定位任务上不如 Nova 2 Lite。

失败案例分析

5 个偏差 >5% 的视频分三类:

  1. 下边界偏大(2 个):推广条紧贴字幕区域(间隔 <6%),裁剪后仍有残留。影响是多擦一点,不会漏擦。
  2. 上边界偏高(2 个):OpenCV 把白色花边装饰误检成字幕行。
  3. 字幕位置特殊(1 个):泰语某集字幕位于 0.78(非常靠下且范围极窄),被其他帧的聚合结果拉偏了。

成本数据

项目 费用
EC2(m8g.large Graviton4) ~$0.077/小时,单视频约 10 秒
Nova 2 Lite 调用 ~$0.0003/帧
单视频(5 帧) ~$0.002
100 个视频 ~$0.20

环境搭建

pip install opencv-python boto3
sudo apt install ffmpeg

IAM 角色最小权限:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "bedrock:InvokeModel",
    "Resource": "arn:aws:bedrock:*::foundation-model/amazon.nova-*"
  }]
}

Amazon Bedrock 控制台 开通 Nova 2 Lite 访问权限。

算法设计的几点反思

  1. 传统 CV 和大模型的误差模式互补——这是整个方案的核心洞察。两者单独都不够好,但错误方向不一样,交集自然能提高精度。
  2. 裁剪是信噪比优化——不是让模型更聪明,而是让输入更干净。这个思路在很多视觉任务上都适用。
  3. Prompt 工程对视觉模型同样重要——bbox 格式 vs 百分比格式,同一个模型效果差很多。
  4. 硬规则兜底——下边界 0.85 封顶这种基于领域知识的简单规则,消除了整类误检。
  5. 快速预筛选——用成本低的方法(OpenCV)做预筛选,再用成本高的方法(大模型)做精确定位。

两周,六版,从 30% 到 83%。每一版都是观察数据 → 找到瓶颈 → 针对性优化的过程。

本文参考亚马逊云科技官方博客:短剧视频字幕位置自动识别:OpenCV + Amazon Nova 2 Lite 混合方案
完整代码:aws-samples/sample-for-video-subtitle-detection-via-nova-2-lite

posted @ 2026-04-27 05:33  亚马逊云开发者  阅读(5)  评论(0)    收藏  举报