トップに戻る

ナイキスト定理から理解する動画解析の物理的限界

「30fpsのスマホ動画から、ギター弦の振動を可視化できないか?」—— 結論から言うと、これは物理的に不可能です。 このページでは、実際にこの失敗を経験した事例を起点に、 動画から周波数を検出するときに誰もがぶつかる「ナイキスト制約」を、 数式最小限・図とコードで解説します。

免責事項 本ページおよび本サイトのデモ・コード例は、技術的可能性を示す教育目的の実装です。 医療診断・健康上の意思決定には使用しないでください。 本コンテンツは薬機法に基づく医療機器ではありません。

このページの結論

動画から検出できる最大周波数は フレームレート(fps)÷ 2(ナイキスト周波数)。 これはカメラの性能でも画像処理の工夫でも超えられない、サンプリングという行為そのものの限界です。

1 失敗事例: 30fpsでギター弦を撮る

EVM(Eulerian Video Magnification)で「振動の可視化」を試していたときの実話です。 ギターの弦を弾いた様子を30fpsで撮影し、EVM処理で弦の振動を増幅しようとしました。 ところが、増幅率やフィルタの周波数帯をどう調整しても、弦の振動らしき動きは一向に現れません。

原因は処理パラメータではなく、そもそも入力動画に弦の振動が記録されていなかったことでした。 ギターの最も低い弦(6弦・E2音)の基本振動数は約82Hzです。 一方、30fpsの動画が記録できる周波数の上限は、後述するナイキスト定理により15Hzしかありません。

ギター6弦(E2): 約82 Hz / 30fps動画の検出上限: 30 ÷ 2 = 15 Hz → 82 Hz ≫ 15 Hz で記録不可能

82Hzの振動を捉えるには、その2倍を超える165fps以上——実用上の余裕を見ると180fps以上での撮影が必要です。 どんなに高度な後処理をしても、撮影の時点で失われた情報は取り戻せません。 「何fpsで撮ったか」を確認せずに動画解析を始めると、この種の失敗は簡単に再現できてしまいます。

ちなみに: 高速撮影なら可能 スマートフォンのスローモーションモード(240fps)なら検出上限は120Hzになり、 82Hzのギター弦も原理上は捉えられます。対象の周波数が先、撮影設定が後——この順序がすべてです。

2 サンプリング定理の直感的な理解

動画は「連続的な現実を、1秒あたりfps回だけパラパラ漫画として切り取ったもの」です。 この「切り取り」をサンプリングと呼びます。 サンプリング定理(ナイキスト=シャノンの定理)が教えてくれるのは、次の一点です。

元の変化を正しく記録するには、その周波数の2倍を超える頻度でサンプリングしなければならない
⇔ 検出可能な最大周波数(ナイキスト周波数) = サンプリング周波数(fps) ÷ 2

直感的には「1回の振動につき、山と谷の最低2点を押さえる必要がある」と考えると分かりやすいです。 1秒に7回振動するものを1秒に6回しか見なければ、山と谷を取り違え、 実際とは別の「ゆっくりした振動」に見えてしまいます。

この「別のゆっくりした振動に化ける」現象をエイリアシング(折り返し)と呼びます。 映画で車のホイールが逆回転して見える「ワゴンホイール効果」や、 テレビでヘリコプターのローターが止まって見える映像は、日常で観察できるエイリアシングの実例です。

実信号(7Hz) サンプル点(6fps) 見かけの信号(1Hz)

図1: 7Hzの振動(青)を6fpsでサンプリング(赤丸)すると、データ上は1Hzの振動(赤破線)と区別がつかない

3 fpsと検出可能周波数の早見表

実務ではナイキスト周波数ぎりぎりを狙わず、ナイキスト周波数の90%以下を 実用上限とするのが安全です(フィルタの切れ味やfpsの揺らぎに対する余裕)。

フレームレート ナイキスト周波数 実用上限(×0.9) 撮れる対象の例
30 fps 15 Hz 13.5 Hz 心拍(1〜2Hz)、呼吸(0.2〜0.5Hz)、建物の揺れ(数Hz)
60 fps 30 Hz 27 Hz 上記 + 低速な機械振動
120 fps 60 Hz 54 Hz 上記 + モーター・ポンプ等の機械振動の一部
240 fps 120 Hz 108 Hz 上記 + ギター弦の低音域(82Hz〜)

対象別の「撮れる/撮れない」マトリクス

対象(代表的な周波数) 30fps 60fps 120fps 240fps
呼吸(0.2〜0.5 Hz)
心拍による皮膚の色変化(1〜2 Hz)
構造物の固有振動(0.5〜10 Hz)
機械振動(20〜50 Hz) ××〜△
ギター6弦 E2(約82 Hz) ×××
電源系の振動(100/120 Hz) ×××△(108Hz以下のみ)
○ = ナイキスト×0.9 以下で検出可能 / △ = 余裕なし・条件付き / × = 物理的に不可能。 ここでの「検出」は周波数成分として記録されるという意味であり、実際の見え方は照明・ブレ・ノイズ等にも左右されます。

4 エイリアシングをPythonで再現する

まず、解析したい動画のfpsを確認する習慣をつけましょう。OpenCVなら3行で確認できます。

import cv2 cap = cv2.VideoCapture("video.mp4") fps = cap.get(cv2.CAP_PROP_FPS) print(f"fps={fps:.1f}, 検出上限={fps / 2:.1f} Hz")

次に、冒頭の失敗事例——「82Hzのギター弦を30fpsで撮るとどう見えるか」をNumPyで再現します。 82Hzの正弦波を1/30秒間隔でサンプリングし、FFTでスペクトルのピークを調べます。

import numpy as np f_signal = 82.0 # ギター6弦 E2(Hz) fps = 30.0 # カメラのフレームレート t = np.arange(0, 1, 1 / fps) # 30fpsのサンプリング時刻 samples = np.sin(2 * np.pi * f_signal * t) freqs = np.fft.rfftfreq(len(t), 1 / fps) spectrum = np.abs(np.fft.rfft(samples)) print(f"最も強い周波数: {freqs[np.argmax(spectrum)]:.1f} Hz") # 出力: 最も強い周波数: 8.0 Hz

実行すると、82Hzの信号がデータ上は8Hzとして現れます。 これは 82Hz が 30fps の整数倍から折り返された結果です(|82 − 30×3| = 8)。 「8Hz付近に何かある」というもっともらしい偽の信号が出てしまう—— 信号が消えるのではなく化けることが、エイリアシングの厄介な点です。

偽信号は検出できない 折り返しで生まれた8Hzと、本当に8Hzで振動している対象とは、データ上区別できません。 だからこそ「解析の前に、対象の周波数とfpsの関係を確認する」以外に防ぐ方法がありません。

5 「撮れる/撮れない」判定フローチャート

動画から周波数的な変化(振動・脈動・明滅)を捉えたいときは、撮影・解析の前に次の手順で判定します。

1. 対象の周波数 f を見積もる 例: 心拍 1〜2Hz / ギター弦 82Hz〜 2. カメラの fps を確認する cv2.CAP_PROP_FPS / 撮影設定 f < (fps ÷ 2) × 0.9 を満たすか? はい いいえ 記録できる可能性あり 照明・ブレ・ノイズなど 他の条件も確認して撮影へ そのfpsでは記録不可能 スローモーション撮影等で fpsを上げて再判定する

図2: 撮影・解析前の判定フロー。「対象の周波数が先、撮影設定が後」

まとめ

  1. 動画から検出できる最大周波数は fps ÷ 2(ナイキスト周波数)。後処理では超えられない
  2. 上限を超えた信号は消えるのではなく、偽の低周波に化ける(エイリアシング)
  3. 実務ではナイキスト周波数の 90%以下 を実用上限とする
  4. 解析の前に「対象の周波数の見積もり → fpsの確認 → 判定」の順で確認する

次のステップ

EVM全体の考え方をまだ押さえていない場合は、シリーズの入口であるEVM入門から読むのがおすすめです。 ナイキスト制約以外の制約(ノイズ・照明・撮影条件)は限界と制約で、 周波数帯域の設定方法はパラメータの意味で解説しています。 実際に撮影して試す場合は自分の動画で試すの撮影ガイドを参照してください。

免責事項 本ページおよび本サイトのデモ・コード例は、技術的可能性を示す教育目的の実装です。 医療診断・健康上の意思決定には使用しないでください。 本コンテンツは薬機法に基づく医療機器ではありません。