0
0

More than 1 year has passed since last update.

ffmpeg で動画の傾き修正 (perspective フィルタ)

Posted at

やりたいこと

例えば、以下のように画面を直撮りしたとして、

img-0-1.jpg

それを以下のように修正します。

img-0-2.jpg

これは ffmpeg に標準で搭載されているビデオフィルタ perspective scale で実現できます。

これから紹介する方法は、カメラと被写体の角度がずっと固定であることが前提となります。映像が激しく動いている場合には対応できません。

用意するもの

  • ffmpeg
    • ここでは GUI でなく CUI で解説
  • 動画のスナップショット (静止画) を保存できるもの
    • ここでは VLC メディアプレーヤーを使用
  • ペイントソフト
    • Windows Paint と同等かそれ以上の水準で十分

手順

解像度 1600x1200 (4:3) の動画から、被写体のディスプレイの映像を切り取る、というのを例とします。

1. 動画のスナップショットを撮る

  1. VLC メディアプレーヤーで動画を再生
  2. 画面上部のメニューバーの「ビデオ > スナップショットを撮る」を選択

img-1-1.jpg

取得されたスナップショットは、(Linux Mint の場合) デフォルトでホームディレクトリのピクチャディレクトリに保存されます。

動画プレイヤーのスクリーンショットでは、正確な解像度にならない可能性があるので注意

2. 被写体の座標を取得する

  1. 得られたスナップショットを任意のペイントソフトで開く
  2. まっすぐ正面にしたい被写体の角 4点の座標を調べる

img-2-1.jpg

4点について、それぞれ上画像に示されているように x1 y1 x2 y2 ... と呼ぶことにします。

ペイントソフトに限らず、静止画上の任意の点の座標を取得できるのであれば、何のソフトでも OK。ただ、最も身近で手軽なのはペイントソフトでしょう。

3. 出力解像度を決める

元動画が 1600x1200 (4:3) に対し、被写体は 16:9 のディスプレイです。傾き修正として使う後述の persipective フィルタだけでは、ディスプレイ映像が 1600x1200 に引き伸ばされ、以下のように縦に延びてしまいます。

img-3-1.jpg

今回は、よく知られている 16:9 の解像度の 1つである 1280x720 (HD) を最終的な出力解像度とします。これはパラメータ sx sy と呼ぶことにします。

被写体のサイズによっては、これより低い解像度にしてしまっても良いです。逆に、無駄に高い解像度にしても、ファイルサイズが圧迫されてしまいますので注意。

直撮りしている時点で画質はあまり期待できない点を踏まえても、高い解像度は必要にならないでしょう。

4. 動画を処理する

必要なパラメータは揃ったので、あとは ffmpeg にかけるだけです。コマンドは以下のようになります。

ffmpeg -i input.mp4 -vf "perspective=x1:y1:x2:y2:x3:y3:x4:y4:1,scale=sx:sy" output.mp4

上の手順で得られたパラメータを当てはめると、以下のようになります。

ffmpeg -i input.mp4 -vf "perspective=274:289:1239:159:327:1054:1250:771:1,scale=1280:720" output.mp4

各パラメータが正しいかどうか確かめたいときは、数秒だけ処理して出力動画を確認すると良いでしょう。ffmpeg は、処理中に Q キーが押されると処理を中断し、途中までで出力ファイルを保存します。

「動画の初めと終わりの部分はブレているので不要」というようなときは、-ss <開始時間> -to <終了時間> オプションを ffmpeg -i の間に入れることで、前後部分をカットできます。

ffmpeg のオプション 補足

ffmpeg-vf オプションにより、動画にかけるフィルタを設定できます。今回の場合、傾き修正 perspective をした後に、サイズ変更 scale をする、というようなフィルタを組んでいます。

perspective について、座標に加えてもう 1つ引数があることに気がつくと思います。これは補間方法の指定で、以下のパラメータを指定できます。

  • 0 - linear (既定値)
  • 1 - cubic

非常〜にザックリ説明すると、liner は折れ線グラフ的に補間する方法で、cubic は滑らかに補間する方法です。滑らかな方が良いんじゃないかと、ここでは何となくで 1 (cubic) を指定しています。

linear は非常に単純なアルゴリズムで、計算量も少ない (処理が軽い) という特徴もあります。

シチュエーションによって結果が変わってくるため、一概にどちらが良いとは言えません。ただ、(繰り返しになりますが) 直撮り画質だったとしたら、いずれでも大して気にならないんじゃないかと思います。

画像元

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0