【フレーム補間】撮った映像をAIでスローモーションにして遊ぼう【Python】

# はじめに

唐突ですが、
- 「映像撮ったはいいけど、カクカクしてて見づらい...」
- 「動きが速すぎてスローモーションで撮りたかった...」
- 「そもそもスローモーションで動画撮る機材とかないし」

と思ったことはありませんか？

**それ、AIで解決できます。** 

フレーム補間に特化したAIを使って、好きな動画をスローモーションにして遊ぶ方法をご紹介します！

---

## 動作確認環境

以下の環境で動作することを確認しました。

| 項目 |  |
|:-:|:--|
| OS  | Windows 10 ver 22H2 |
| CPU  | intel Core i7-7700  |
| GPU  | NVIDIA GeForce RTX 2080 Ti (VRAM 11GB) |
| メインメモリ | 16GB  |
| CUDA | 11.0 |
| Python  | WinPython 3.8.7  |
| PyTorch  | 1.12.1+cu113 |

---

# 1. そもそも「フレーム補間」タスクとは

動画は、**静止画を高速にコマ送りすることで動く映像になっています**。そのため、コマの時間間隔が広いとそれだけ動きがカクカクします。1秒間のコマ数（よくフレームレート、○○fps(frames per second)と言います）は、通常30fpsです。最近動画編集ソフトやYouTubeでは60fpsがデフォルト化してきています。
ダンス動画のMVなどでは、あえてフレームレートを通常より下げて(24フレーム程度)ダンスの臨場感や激しさを表現することも多いです。

| 用途 | 一般的なフレームレート |
|:-:|:-:|
| 地上波放送、ビデオカメラ |  30fps (インターレース方式$^{*注}$により視覚的には60fpsに見える) |
| アニメ  | 24fps  |
|  映画 | 23.976fps  |
| YouTubeなどの配信動画  | 30/60fps  |
| 音楽・ダンスなどのMV  | ～24fps  |
| スマホで撮る動画  | 30/60fps  |

*注：インターレース／プログレッシブ方式についての説明は割愛します。

---

「フレーム補間」とは、動画を構成する大量のフレームについて、文字通り「フレーム間を補間する」タスクのことです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/87aab765-efad-d1f8-14dc-e47eea5c2ad5.png)


---

動画を構成するすべてのフレームの間を前後フレームから推測し、元の動画に組み込めば、**通常よりも２倍フレームが多い動画ができあがることになります**。（元動画の総フレーム数を$n$とすると正確には$2n-1$フレーム）
補間後の動画のフレームレートを、元動画のフレームレートに揃えれば「疑似的な2xスローモーション動画」になり、2倍のフレームレートにすれば「なめらか動画」を作ることができます。


:::note info
**ポイント**
よくフレームレート、フレーム補間の業界では「なめらかに動く」ことを **「ぬるぬる」** と表現します。「動画 ぬるぬる化」などで検索すると最先端のフレーム補間技術、アプリがたくさん出てきますので調べてみてください。
:::

---

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/1b85965d-ef35-ceb1-ef71-4c7c340a1fe9.png)



この記事では、Pythonを用いて **動画をスローモーション化** したいと思います。

---

# 2. 利用する技術の簡単な解説

この記事では以下のGitHubリポジトリを利用させていただきました。

https://github.com/avinashpaliwal/Super-SloMo

このリポジトリは、以下の論文が主にベースになっています。以下、引用している図はこの論文が出典です。


Huaizu Jiang, Deqing Sun, Varun Jampani, Ming-Hsuan Yang, Erik Learned-Miller, Jan Kautz. Super SloMo: High Quality Estimation of Multiple Intermediate Frames for Video Interpolation. CVPR, 2018.

https://arxiv.org/abs/1712.00080

---

## ネットワーク構造

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/98094d1e-71b5-22a4-1e41-5d1023f2ae8f.png)

詳しくは解説しませんが、この技術もU-Netをベースにした画像処理ネットワークになっています。**U-Net万能**。

:::note warn
**ポイント**
U-Netは単純な畳み込み構造で視覚的にもわかりやすいですが、研究が進むにつれ近年は複雑で高精度なモデルが主流になっています。
:::

---

前後の２フレームを入力とし、その前後間の動きの差分をAIで推測することで間のフレームを導きだします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/3ea02d31-6685-fcff-62ac-f19bd24e3a7e.png)

フレーム補間向けに適したデータセットを使って学習したモデルが配布されています。今回はこれを用いて実際に動画をスローモーション化してみたいと思います。

---

# 3. 実行準備

## 3.1 Python実行環境の準備
- GitHubリポジトリから最新版をダウンロードし、任意のフォルダに配置します。

https://github.com/avinashpaliwal/Super-SloMo

---

- 学習済みモデルのダウンロード

GitHubリポジトリにある説明から、モデルをダウンロード、任意の場所に配置してください。

> Pretrained model
> You can download the pretrained model trained on adobe240fps dataset here.

---

- インストールしていないライブラリがあればインストールしてください。

```powershell
pip install torch torchvision
```

:::note warn
**ポイント**
GPUで動作させる場合、PyTorchの公式サイトをご覧ください。
:::

---

## 3.2 動画変換ライブラリffmpegの準備

動画からフレームを抜き出したり、フレームから動画を再構成するなどのタスクで「ffmpeg」を利用します。

https://www.gyan.dev/ffmpeg/builds/

こちらのサイトからffmpegをダウンロードし、中身のexeファイルを任意のフォルダに格納してください。

:::note info
**ポイント**
ffmpegは動画変換などで大変重宝するツールです。このフォルダを環境変数に登録しておくと、他のアプリやツールの実行時にアクセスが簡単になりおすすめです。
:::

---

## 3.3 変換する動画の用意

変換したい動画を任意のフォルダに用意してください。

今回は以下のような動画を用意しました。

**卵を割る動画**
![1-egg-セグメント 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/336d2890-1689-736e-7d0f-99f2a47079dd.gif)

**ランニング動画**
![2-run-セグメント 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/160f6af1-7bb5-cfca-3ccc-02d58be4b800.gif)

**水面に泡が出る動画**
![3-water-セグメント 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/f5ce6bae-5af4-2f42-bdcf-6e6afe96944f.gif)

---

# 4. スローモーションにしてみよう

以下の起動パラメータでコマンドを実行するだけで、スローモーション動画ができあがります。CPUやGPU環境に応じて時間がかかるので少し待ちましょう。

```powershell
python video_to_slomo.py --ffmpeg D:\foge\ffmpeg --video foge.mp4 --sf 3 --checkpoint model/SuperSloMo.ckpt --fps 24 --output output.mkv
```

---

## 4.1 起動パラメータの意味

| パラメータ | 意味 |
|:-:|:-:|
| --ffmpeg  | ffmpegの実行ファイルがあるフォルダを指定  |
|  --video |  変換したい動画ファイル |
| --sf  | フレーム補間のファクター（元動画の総フレームの何倍にするか）  |
|  --checkpoint | 学習済みモデルファイルの指定  |
| --fps  |  補間後の動画のフレームレート（元動画と同じフレームレートを指定すればスローモーションに、元動画×sfにすれば元の再生速度を維持しなめらか動画になります） |
| --output  | 補間後の動画の保存先 |

---

## 4.2 実行結果
![out_1-egg-セグメント 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/02816e07-8743-1b07-f735-4f5c49896f7d.gif)

GIFだとわかりにくいですが、黄身の激しい動きが滑らかになっています。白身の粘り気も伝わってきます。

---

![out_2-セグメント 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/33ab5679-b2a6-e8c8-df1f-60191a42144e.gif)

特に動きが激しい手の動きはぶれてしまっていますが、スローモーションにすると体の動きがなめらかになっていることがわかります。

---

![out_3-セグメント 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/466f4146-464f-d36a-eb67-0a7636ac054a.gif)

動きの推測が難しいためか不自然に動いている場所もありますが、細かい泡を見るとなめらかに動いているのが分かります。

---

# 5. さいごに

今回はAIで動画をスローモーションにする方法をご紹介しました。こちらのリポジトリも手元の動画で学習できるプログラムが用意されていますので、ご興味がありましたらぜひお試しください。