从视频的固定区域提取字幕,本文通过**ffmpeg**精准截静态帧 + Python 指定区域 OCR 识别,一种硬字幕的提取方案。

一、硬字幕与软字幕的本质区别

在开始操作前,我们需要明确两类字幕的差异:

  • 软字幕:以独立流的形式嵌入视频文件(如 SRT、ASS 格式),可通过ffmpeg直接提取(命令:ffmpeg -i 视频.mp4 -map 0:s:0 字幕.srt)。
  • 硬字幕:直接绘制在视频画面上,属于画面像素的一部分,无法直接提取,可以通过 “帧提取 + OCR 识别” 的方式间接获取。

二、需求与工具

需求场景:硬字幕提取

  • 视频每 5 秒截取一帧,提取帧中固定区域(如红框区)的英文文字;
  • 每张帧的提取结果作为一行存入文本文件,排除无关内容干扰。

工具清单

  1. 帧提取工具: ffmpeg(程序员们爱用的音视频处理工具);
  2. OCR 识别工具: Tesseract OCR(需安装英文语言包);
  3. 脚本工具: Python(安装pytesseractPillow库)。

快速安装

  • ffmpeg: Windows 下载后配置环境变量,Linux/Mac 直接通过包管理器安装。

  • Tesseract OCR: Windows 从UB-Mannheim/tesseract下载(勾选英文语言包),可以配置环境变量,或者在后面的python脚本中指定这个OCR工具的路径。Linux 执行sudo apt install tesseract-ocr tesseract-ocr-eng;Tesseract OCR核心引擎,负责实际的文字识别工作(OCR)。

  • Python 依赖

    1
    pip install pytesseract pillow

pytesseract的作用是在 Python 代码和 Tesseract OCR 引擎之间建立一个桥梁, 是Python 接口,让你能在 Python 代码中方便地调用 Tesseract;Pillow图像处理库,用于打开和预处理图片,提供给 pytesseract 使用。

三、实现步骤:从视频帧到文本提取

第一步:用 ffmpeg 批量截取视频静态帧

执行以下命令,每 5 秒截取一帧并保存到frames文件夹(需提前创建):

1
ffmpeg -i input.mp4 -vf "fps=1/5" frames/frame_%04d.png
  • 参数说明:fps=1/5表示每 5 秒 1 帧,frame_%04d.png按顺序命名帧文件(如frame_0001.png);

  • 若需提取关键帧(画质更优),可替换为:

    1
    ffmpeg -i input.mp4 -vf "fps=1/5,select='eq(pict_type,PICT_TYPE_I)'" -vsync vfr frames/frame_%04d.png

第二步:确定目标区域坐标

需提取帧中固定区域的文字,需先获取该区域的像素坐标:

  • 用 Windows 画图工具打开任意帧图片,鼠标移至该区域左上角,记录(left, top)(如200, 300);
  • 移至右下角,记录(right, bottom)(如800, 500);
  • 最终裁剪坐标为(left,top,right,bottom),即(200, 300, 800, 500)

第三步: Python 脚本批量提取文字

创建extract.py脚本,实现裁剪指定区域→OCR 识别→结果写入文件;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import os
import pytesseract
from PIL import Image

# 1. 配置路径
frame_dir = "frames"
output_file = "extracted_text.txt"

# 2. 遍历所有帧图片
with open(output_file, "w", encoding="utf-8") as f:
for img_name in os.listdir(frame_dir):
if img_name.endswith((".png", ".jpg", ".jpeg")):
img_path = os.path.join(frame_dir, img_name)
img = Image.open(img_path)

# 3. 裁剪目标区域
cropped = img.crop((200, 300, 800, 500)) # left, top, right, bottom

# 4. OCR识别
text = pytesseract.image_to_string(cropped, lang="eng", config="--psm 6")
# --psm 6: 强制按单行识别

# 5.写入文件(一帧写入一行)
cleaned_text = text.strip().replace("\n", " ")
f.write(cleaned_text + "\n")

print(f"提取完成!结果保存在 {output_file}")

四、细节说明

核心参数说明

  • crop((200, 300, 800, 500)):裁剪目标区域,避免识别到 URL、按钮等无关文字;
  • config="--psm 6": Tesseract 的页面分割模式,强制将裁剪区域视为单行文字,保证识别结果连贯;
  • strip().replace("\n", " "):去除多余空格和换行,确保每张帧的结果为一行纯文本。

五、拓展场景与优化

批量处理多个视频

可在脚本中增加视频遍历逻辑,自动处理文件夹下所有视频:

1
2
3
4
5
import glob
video_dir = "videos"
for video in glob.glob(f"{video_dir}/*.mp4"):
# 调用ffmpeg提取帧(需动态生成帧文件夹)
# 再执行上述识别逻辑

提升识别准确率

若文字模糊,可在裁剪后增加预处理:

1
2
3
cropped = cropped.convert("L")  # 灰度化
enhancer = ImageEnhance.Contrast(cropped)
cropped = enhancer.enhance(2) # 增强对比度