mcpField
S
scikit-video

scikit-video

github.com/tondevrelデータ・データベース2445 回インストール38 週間前に更新
リポジトリ

scikit-video について

scikit-videoは、科学計算や動画研究向けのPythonツールキットで、NumPyインターフェースを通じて動画を扱い、入出力にはFFmpegを利用します。動き推定、動画品質評価、フレーム単位の読み込みを備え、分析やデータセット作成に使えます。

主な機能

  1. 01FFmpegによる動画の読み書き
  2. 02動画フレームをNumPy配列で表現
  3. 03大容量動画のフレーム単位読み込み
  4. 04動きと動画品質の指標を計算
  5. 05生のYUVデータを処理

活用シーン

  1. 01長い動画から指定区間を抽出
  2. 02原版と圧縮動画の品質を比較
  3. 03機械学習向け動画データセットを作成
  4. 04科学映像の時間変化を分析

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/tondevrel/scientific-agent-skills --skill scikit-video

インストール後、Claude Code で/scikit-videoを入力して読み込まれたか確認します。

詳細

scikit-video - 科学的な動画処理

scikit-video は、一貫性のある NumPy ベースのインターフェースを提供することで、動画コーデックやコンテナの複雑な仕組みを簡単に扱えるようにします。モーションベクトルの計算、動画品質評価(VQA)、科学的な Python エコシステムとのシームレスな統合が可能です。

使用する場面

  • FFmpeg を使用して、さまざまな形式(MP4、AVI、MKV)の動画ファイルを読み書きする場合。
  • 動画全体をメモリに読み込まずに、長い動画から特定のフレームや区間を抽出する場合。
  • 動きの推定(ブロックマッチング、オプティカルフロー)を計算する場合。
  • 動画品質(PSNR、SSIM、VIF、NIQE)を測定する場合。
  • 機械学習用の動画データセットを生成する場合。
  • ピクセルデータの時間的な変化(科学的な記録など)を可視化する場合。
  • 生の YUV データストリームを処理する場合。

リファレンスドキュメント

公式ドキュメント: http://www.scikit-video.org/
GitHub: https://github.com/scikit-video/scikit-video
検索パターン: skvideo.io.vread、skvideo.io.FFmpegReader、skvideo.motion、skvideo.measure

基本原則

4 次元配列としての動画

動画は、形状が (T, H, W, C) の NumPy 配列として表現されます。

  • T:時間(フレーム数)
  • H:高さ
  • W:幅
  • C:チャンネル数(通常、RGB の場合は 3)
FFmpeg バックエンド

Scikit-video は独自のコーデックを含まず、FFmpeg へのブリッジとして機能します。skvideo.io を動作させるには、システムに FFmpeg をインストールする必要があります。

大容量データにはジェネレーターを使用

長い動画の場合、scikit-video はジェネレーターベースのリーダー(vreader)を提供し、フレームを 1 つずつ処理して RAM の枯渇を防ぎます。

クイックリファレンス

インストール
pip install scikit-video
# Note: Ensure ffmpeg is in your system PATH
標準的なインポート
import skvideo.io
import skvideo.motion
import skvideo.measure
import numpy as np
基本パターン - 読み込みと確認
import skvideo.io

# 1. Read the whole video into a NumPy array
# Shape: (frames, height, width, 3)
video_data = skvideo.io.vread("experiment.mp4")

# 2. Get basic info
n_frames, height, width, channels = video_data.shape
print(f"FPS: {n_frames / 10}, Resolution: {width}x{height}")

# 3. Access a specific frame
frame_10 = video_data[10]

重要なルール

✅ 推奨事項
  • 大きなファイルには vreader を使用する - 高解像度または長時間の動画には、必ずジェネレーターベースの読み込みを使用してください。
  • num_frames を設定する - 必要なフレーム数が分かっている場合は、不要なスキャンを避けるために指定してください。
  • FFmpeg のパスを確認する - FFmpeg が標準以外の場所にインストールされている場合は、skvideo.setFFmpegPath() を使用してください。
  • メトリクス用に正規化する - ピクセル値が skvideo.measure で想定される範囲(通常、uint8 では [0, 255])になっていることを確認してください。
  • 単純な出力には vwrite を使用する - 複雑な FFmpeg コマンドライン引数を処理してくれます。
  • YUV を検討する - 生の伝送データを扱う場合は、専用の YUV 読み込み機能を使用してください。
❌ 非推奨事項
  • 4K 動画を vread で読み込む - 1 分間の 4K 動画は、ほとんどの RAM 容量を超えます。
  • inputdict と outputdict を無視する - これらを使うと、ビットレート、ピクセル形式、コーデックなどの特定のフラグを FFmpeg に渡せます。
  • RGB の順序だと思い込む - 特に外部コーデックを使用している場合は、読み込み後にチャンネルの順序を必ず確認してください。
  • ノイズ除去をせずに動画を処理する - 動画ノイズは動きの推定を損なう可能性があります。先に空間フィルターまたは時間フィルターを適用してください。

アンチパターン(絶対に避ける)

import skvideo.io

# ❌ BAD: Loading a massive file at once
# video = skvideo.io.vread("huge_4k_recording.mp4") # CRASH!

# ✅ GOOD: Processing frame by frame
reader = skvideo.io.vreader("huge_4k_recording.mp4")
for frame in reader:
    # Process frame
    pass

# ❌ BAD: Manual frame writing in a loop with manual codec setup
# (Fragile and complex)

# ✅ GOOD: Use FFmpegWriter
writer = skvideo.io.FFmpegWriter("output.mp4")
for frame in processed_frames:
    writer.writeFrame(frame)
writer.close()

# ❌ BAD: Relying on system default FFmpeg without checking
# ✅ GOOD: Verify backend
# print(skvideo._HAS_FFMPEG)

読み込みと書き込み(skvideo.io)

高度な動画入出力
import skvideo.io

# 1. Reading with specific FFmpeg options
input_parameters = {
    "-ss": "00:00:10", # Start at 10 seconds
    "-t": "5"          # Duration 5 seconds
}
video = skvideo.io.vread("video.mp4", inputdict=input_parameters)

# 2. Writing with specific bitrate and codec
output_parameters = {
    "-vcodec": "libx264",
    "-b:v": "5000k", # 5 Mbps bitrate
    "-pix_fmt": "yuv420p"
}
skvideo.io.vwrite("output.mp4", video, outputdict=output_parameters)

動きの推定(skvideo.motion)

動きの計算
from skvideo.motion import blockMotion
from skvideo.io import vread

# Load two consecutive frames
video = vread("video.mp4")
frame1 = video[0]
frame2 = video[1]

# Block matching algorithm
# Returns motion vectors for each block
motion_vectors = blockMotion(frame1, frame2, method='DS', mbSize=16)

# motion_vectors shape: (H/mbSize, W/mbSize, 2)
# The last dimension contains (dy, dx) offsets

動画品質評価(skvideo.measure)

劣化の測定
from skvideo.measure import psnr, ssim, mse

# Compare original and compressed video
original = vread("original.mp4")
distorted = vread("compressed.mp4")

# Calculate metrics frame by frame
psnr_scores = psnr(original, distorted)
ssim_scores = ssim(original, distorted)

print(f"Average PSNR: {np.mean(psnr_scores)}")

データセットとユーティリティ

内蔵データセットの使用
import skvideo.datasets

# Load a built-in sample video (useful for testing)
path = skvideo.datasets.bigbuckbunny()
reader = skvideo.io.vreader(path)

実践的なワークフロー

1. シンプルな背景差分パイプライン
def extract_background(video_path):
    """Calculates the static background of a video using the median."""
    reader = skvideo.io.vreader(video_path)
    frames = []
    # Sample every 10th frame to save memory
    for i, frame in enumerate(reader):
        if i % 10 == 0:
            frames.append(frame)
        if len(frames) > 50: break
            
    # Background is the median of frames
    background = np.median(np.array(frames), axis=0).astype(np.uint8)
    return background

# Usage
# bg = extract_background("security_cam.mp4")
2. 動画の手ブレ補正(フレームの位置合わせ)
def stabilize_frames(video_array):
    """Very basic stabilization using motion vectors."""
    stabilized = [video_array[0]]
    for i in range(1, len(video_array)):
        motion = skvideo.motion.blockMotion(video_array[i-1], video_array[i])
        avg_motion = np.mean(motion, axis=(0, 1)) # Global drift
        # Translate frame back (Simplified logic)
        # Use scipy.ndimage.shift for actual translation
        ...
3. 動画品質レポートの自動生成
def generate_vqa_report(ref_path, test_path):
    ref = skvideo.io.vread(ref_path)
    test = skvideo.io.vread(test_path)
    
    report = {
        "MSE": np.mean(skvideo.measure.mse(ref, test)),
        "PSNR": np.mean(skvideo.measure.psnr(ref, test)),
        "SSIM": np.mean(skvideo.measure.ssim(ref, test))
    }
    return report

パフォーマンスの最適化

マルチスレッドで vreader を使用する

各フレームに対して負荷の高い処理を行う場合は、キューベースのマルチスレッド方式を使用して、FFmpeg パイプが常にデータを受け取れる状態を保ってください。

効率的なスライス

vread で読み込んでからスライスする代わりに、inputdict を介して FFmpeg のシークおよび再生時間のフラグを指定し、ディスクから必要なデータだけを読み込んでください。

よくある問題と解決策

FFmpeg が見つからない

Scikit-video は ffmpeg 実行ファイルに依存します。

# ✅ Solution: Manually set the path if it's not in environment
import skvideo
skvideo.setFFmpegPath("C:/ffmpeg/bin")
色空間の不一致

動画によっては YUV422 または YUV444 で保存されています。Scikit-video はデフォルトでこれらを RGB に変換します。

# ❌ Problem: Colors look washed out or incorrect
# ✅ Solution: Specify the pixel format in inputdict
reader = skvideo.io.vreader("video.mp4", inputdict={"-pix_fmt": "yuv420p"})
メモリ不足(OOM)エラー

vreader を使っていても、すべてのフレームをリストに保存すると、メモリが不足します。

# ❌ Problem: frames.append(frame) in a loop
# ✅ Solution: Process and save to disk, or clear the list periodically.

scikit-video は、FFmpeg の機能を NumPy の世界にもたらします。動画コンテナの複雑さを抽象化し、動きの推定や品質指標などの科学的な分析ツールを提供するため、時間的な画像データを扱う研究者にとって欠かせないツールです。

コメント