ホーム技術ブログ › 05
2026-09-07 #05

焼き込み字幕をOCRで答え合わせする。fps=1にしないと19件中9件を取りこぼす

該当区間だけ切り出してタイル画像にまとめ、テロップを正解データとして使う。フレーム間隔の落とし穴。

ffmpegOCR検証

前提: 正解が画面に書いてある

テキストだけでは確定できない箇所が、どうしても残ります。 固有名詞や番組の造語は、前後を読んでも「たぶんこうだろう」までしか行きません。

幸い、この番組は要点を映像に焼き込んだテロップで出してくれます。 つまり正解は画面にあります。以下は、その画面を機械的に読みに行く手順です。

STEP 1: 該当する区間だけを切り出す

ffmpeg -ss 00:12:02 -to 00:12:16 -i src.mp4 -c copy w.mp4

窓は前方に重みを置きます(該当箇所の10秒前から数秒後まで)。 10秒前に出たテロップの言葉をそのまま喋っていて、 その時点ではもう字幕が消えている、というパターンが多かったためです。

STEP 2: 1秒刻みで抜いて、1枚のタイルにまとめる

ffmpeg -i w.mp4 -vf "fps=1,scale=620:-1,tile=4x4" -frames:v 1 t.jpg

🚨 fps=1 より粗くしないでください。ここが最大の落とし穴です(後述)。

STEP 3: 同じ絵を間引く

テロップは数秒出続けるので、そのままだと同じ絵が並びます。

import hashlib
prev = None
for f in frames:
    h = hashlib.md5(Image.open(f).resize((64, 16)).tobytes()).hexdigest()
    if h == prev:
        continue
    prev = h
    yield f

STEP 4: 読んで、画面にある表記どおりに直す

ここで直すのは、テロップにそのまま映っている表記だけです。 画面に出ていない語を文脈から補うと、この工程を入れた意味がなくなります。

つまずいたところ1: fps=0.5 にして19件中9件を取りこぼした

枚数を減らそうとして2秒刻みにしたことがあります。 結果、19件を「テロップは出ていませんでした」として要確認に送りました。 あとで fps=1 で取り直したら、9件は普通に出ていました。

# テロップの表示時間は 1〜2秒
# fps=0.5 → 2秒に1枚 → まるごと1枚飛ぶ

厄介だったのは、報告としては正しい形をしていたことです。 「確認したが無かった」と書いてあるので、読む側は再確認しません。 検証工程の手抜きが、手抜きに見えない形で出力されていました。

つまずいたところ2: 別のモデルの出力を根拠に、正しい値を壊した

別のモデルで起こし直して、既存と食い違った箇所を、 新しい出力だけを根拠に書き換えたことがあります。

書き換えた結果テロップの実際
素敵堀元くん素敵

新しいモデルに名前が無かったので「音にない名前を足していたのだろう」と判断しました。 実際は逆で、新しいモデルのほうが画面に出ている情報を落としていただけでした。

食い違いは「どちらが正しいか」ではなく「見に行く合図」。 とくに新しい出力のほうが短く素直なときが危ない。

まとめ

  • 焼き込み字幕は正解データとして使える。テキストだけで確定させない
  • fps=1 より粗くしない。表示が1〜2秒なら1枚飛ぶ
  • 「確認したが無かった」は、形が正しいぶん再確認されない。いちばん危ない報告だった

← LLMに校正させるとき、精度より効いたのは「作文の禁… 「要確認」を付けて確認する仕組みにした。ただし漏れが… → 目次へ

ゆる言語学ラジオ・ゆるコンピュータ科学ラジオ 公認/株式会社pedantic の了承と、運営者・安東暁史との合意に基づく協力体制で運営しています。ドメイン yururadio.jp は株式会社pedanticが保有。開発・保守: 安東暁史·このサイトについて·お問い合わせ