🎞️
動画の類似フレームをすっ飛ばしながら画像を書き出そう
動画から画像を取り出したいこと、あると思います
でも愚直に取り出すと画像が30枚も60枚も出てくることになります そんなにいらない!
一定間隔で切り出す? 動きがないフレームがダブったりしてサイアク!
なので「視覚的によく似たフレームはスキップしながら画像を書き出すツール」ツールを作りました
ここに置いておきます
事前準備
あらかじめ以下をインストールしておいてください
pip3 install opencv-python scikit-image
使い方
今すぐに使えます
コマンド
curl -s https://gist.githubusercontent.com/pal4de/567944e979e7c4492262b9e2e1973e20/raw/96642042c1ff2e053c07713bbe0c2946f3f3a452/extract_unique_frames.py \
| python3 -
--help
usage: - [-h] [-t THRESHOLD] [-k] video_path output_dir
Extract unique frames from a video based on SSIM.
positional arguments:
video_path Path to the input video file or URL.
output_dir Directory to save the output frames.
options:
-h, --help show this help message and exit
-t, --threshold THRESHOLD
SSIM threshold for similarity detection (default: 0.85).
Frames with SSIM >= threshold are considered similar.
-k, --keep-similar If set, similar frames are saved with '_similar' suffix
instead of being skipped.
実行すると、 video_path の動画のフレームが output_dir に吐き出されます
実行例
例として、ロケットを打ち上げてる動画 (Rocket Launch Free Public Domain Video(1080P HD)を借ります

動画の場所と出力先ディレクトリを指定して実行します
URLでの指定にも対応しています 気が利いてると思いませんか
--threshold で閾値を変更できます
| 閾値例 | イメージ |
|---|---|
| 0.00 | ほぼ何も出力しない |
| 0.75 | 少なめに出力 |
| 0.85 | そこそこ出力 (デフォルト) |
| 0.95 | 多めに出力 |
| 1.00 | ほぼ全てのフレームを出力 |
実行例
$ curl -s https://gist.githubusercontent.com/pal4de/567944e979e7c4492262b9e2e1973e20/raw/96642042c1ff2e053c07713bbe0c2946f3f3a452/extract_unique_frames.py \
| python3 - https://ia801408.us.archive.org/27/items/public-domain-archive/Rocket%20Launch%20_%20Free%20Public%20Domain%20Video%281080P_HD%29.mp4 rocket_frames
Loading video from URL: https://media.xiph.org/video/derf/y4m/bowing_cif.y4m
Processing frame 1...
Saving the first frame.
Saved frame 1 as frame_00001.png
Processing frame 2...
SSIM with previous frame: 1.0000
Skipping frame 2 due to similarity.
...
Processing frame 891...
SSIM with previous frame: 0.9890
Skipping frame 891 due to similarity.
Processing frame 892...
SSIM with previous frame: 0.9838
Skipping frame 892 due to similarity.
Processing finished.
Total frames processed: 892
Total frames saved: 14
Total similar frames skipped: 878

概ねシーンごとに画像が一枚切り出されています 画面の一部分だけがゆっくり変化すると類似フレームと判定されるみたいです
892フレームが14フレームに減ったのは、いいですね
類似度指標 SSIM について
正直マルチメディア分野にはあまり明るくないのでこの辺りのはChatGPTに選定を委ねました
SSIMは次の流れで評価する指標のようです
- 画像を小領域に分けて、輝度・コントラスト・構造の3点で 似てる度 を測る。
- 各領域のスコアを平均して全体のSSIMを出す。
SSIMにも得意不得意があるみたいです
下の表ももらったので、出力に納得がいかない場合はお手元のコーディングアシスタントAIにこれを使って再実装するように頼んでみてください
| シチュエーション | 推奨される指標 |
|---|---|
| GAN生成画像などの主観評価と一致しない | LPIPS, DISTS, FID |
| 圧縮・ぼかしに強いが微細な違いを見逃したくない | FSIM, FSIMc, VIF |
| 処理が重すぎる(特にバッチ処理) | MSE, PSNR(ざっくり比較用) |
| ズレ・回転・幾何変形がある | CW-SSIM, LPIPS, 手動アライメント + SSIM |
| 色情報(色ずれ)が気になる | FSIMc, Lab空間 + SSIM, 色差(CIEDE2000) |
| 評価時間を秒単位まで削減したい | PSNR, 簡易勾配ベースの類似度 |
| 非自然画像・特殊用途(工業・UI等) | タスクベースのメトリクス(例:OCR精度、線の検出率) |
終わりに
全然本筋の話じゃないんですけどGistでスクリプト配って即時実行するの面白いです
これ流行んないかな
Discussion