SHIROBAKO の15話でモーションブラーが出てきたがそれを ffmpeg でもある程度実現することができるのでその方法の紹介。ポイントは一定周期のフレーム数でブレンドの平均をするところ。

具体的にはモーションブラーとここで紹介するフレームブレンドは異なる。

使うフィルタはblendフィルタ。
YUV RGB を比較計算する blend

atadenoiseフィルタで手軽に前後1フレームのモーションブラーを当てることができる。
手軽にモーションブラー atadenoise

フレームブレンドで過去フレームの加重を調整するのに便利なtmixフィルタがある。
FFmpeg Filters Documentation : tmix

追記 2015年3月7日
tblendフィルタによる「とても軽めのモーションブラー」を追加。

オリジナルの映像

40フレーム目の画像

とても軽めのモーションブラー

この方法は以下の3つの方法とは異なり前後フレームを平均して表示している。

40フレーム目の画像

プレビュー

ffplay -i input.mp4 -vf tblend=c0_mode=average

エンコード

ffmpeg -i input.mp4 -vf tblend=c0_mode=average -acodec copy output.mp4

軽めのモーションブラー

40フレーム目の画像


プレビュー

ffplay -f lavfi 
-i "movie=input.mp4,split[a][b]; 
[b]trim=start_frame=1,setpts=PTS-STARTPTS,smartblur[b1]; 
[a][b1]blend=c0_mode=average[out0]; 
amovie=input.mp4[out1]"

モーションブラーの時間指定する場合(1秒から3秒の間)

ffplay -f lavfi 
-i "movie=input.mp4,split[a][b]; 
[b]trim=start_frame=1,setpts=PTS-STARTPTS,smartblur[b1]; 
[a][b1]blend=c0_mode=average: 
enable='between(t,1,3)'[out0]; 
amovie=input.mp4[out1]"

エンコード

ffmpeg -i input.mp4 -filter_complex "split[a][b]; 
[b]trim=start_frame=1,setpts=PTS-STARTPTS,smartblur[b1]; 
[a][b1]blend=c0_mode=average" -acodec copy output.mp4

ほどほどのモーションブラー

4フレーム平均を行う。

40フレーム目の画像


プレビュー

ffplay -f lavfi -i "movie=input.mp4,split=4[a][b][c0][d]; 
[b]trim=start_frame=1,setpts=PTS-STARTPTS[b1]; 
[c0]trim=start_frame=2,setpts=PTS-STARTPTS[c1]; 
[d]trim=start_frame=3,setpts=PTS-STARTPTS[d1]; 
[a][c1]blend=c0_mode=average[ac]; 
[b1][d1]blend=c0_mode=average[bd]; 
[ac][bd]blend=c0_mode=average[out0]; 
amovie=input.mp4[out1]"

モーションブラーの時間指定する場合(1秒から3秒の間)

ffplay -f lavfi 
-i "movie=nc54833.mp4,split=4[a][b][c0][d]; 
[b]trim=start_frame=1,setpts=PTS-STARTPTS[b1]; 
[c0]trim=start_frame=2,setpts=PTS-STARTPTS[c1]; 
[d]trim=start_frame=3,setpts=PTS-STARTPTS[d1]; 
[a][c1]blend=c0_mode=average:enable='between(t,1,3)'[ac]; 
[b1][d1]blend=c0_mode=average:enable='between(t,1,3)'[bd]; 
[ac][bd]blend=c0_mode=average:enable='between(t,1,3)'[out0]"

エンコード

ffmpeg -i input.mp4 -filter_complex "split=4[a][b][c0][d]; 
[b]trim=start_frame=1,setpts=PTS-STARTPTS[b1]; 
[c0]trim=start_frame=2,setpts=PTS-STARTPTS[c1]; 
[d]trim=start_frame=3,setpts=PTS-STARTPTS[d1]; 
[a][c1]blend=c0_mode=average[ac]; 
[b1][d1]blend=c0_mode=average[bd]; 
[ac][bd]blend=c0_mode=average" -acodec copy output.mp4

重めのモーションブラー

8フレーム平均を行う。

40フレーム目の画像


プレビュー

ffplay -f lavfi -i 
"movie=input.mp4,split=8[a][b][c0][d][e][f][g][h]; 
[b]trim=start_frame=1,setpts=PTS-STARTPTS[b1]; 
[c0]trim=start_frame=2,setpts=PTS-STARTPTS[c1]; 
[d]trim=start_frame=3,setpts=PTS-STARTPTS[d1]; 
[e]trim=start_frame=4,setpts=PTS-STARTPTS[e1]; 
[f]trim=start_frame=5,setpts=PTS-STARTPTS[f1]; 
[g]trim=start_frame=6,setpts=PTS-STARTPTS[g1]; 
[h]trim=start_frame=7,setpts=PTS-STARTPTS[h1]; 
[a][e1]blend=c0_mode=average[ae]; 
[b1][f1]blend=c0_mode=average[bf]; 
[c1][g1]blend=c0_mode=average[cg]; 
[d1][h1]blend=c0_mode=average[dh]; 
[ae][bf]blend=c0_mode=average[aebf]; 
[cg][dh]blend=c0_mode=average[cgdh]; 
[aebf][cgdh]blend=c0_mode=average[out0]; 
amovie=input.mp4[out1]"

モーションブラーの時間指定する場合(1秒から3秒の間)

ffplay -f lavfi -i 
"movie=input.mp4,split=8[a][b][c0][d][e][f][g][h]; 
[b]trim=start_frame=1,setpts=PTS-STARTPTS[b1]; 
[c0]trim=start_frame=2,setpts=PTS-STARTPTS[c1]; 
[d]trim=start_frame=3,setpts=PTS-STARTPTS[d1]; 
[e]trim=start_frame=4,setpts=PTS-STARTPTS[e1]; 
[f]trim=start_frame=5,setpts=PTS-STARTPTS[f1]; 
[g]trim=start_frame=6,setpts=PTS-STARTPTS[g1]; 
[h]trim=start_frame=7,setpts=PTS-STARTPTS[h1]; 
[a][e1]blend=c0_mode=average:
enable='between(t,1,3)'[ae]; 
[b1][f1]blend=c0_mode=average:
enable='between(t,1,3)'[bf]; 
[c1][g1]blend=c0_mode=average:
enable='between(t,1,3)'[cg]; 
[d1][h1]blend=c0_mode=average:
enable='between(t,1,3)'[dh]; 
[ae][bf]blend=c0_mode=average: 
enable='between(t,1,3)'[aebf]; 
[cg][dh]blend=c0_mode=average: 
enable='between(t,1,3)'[cgdh]; 
[aebf][cgdh]blend=c0_mode=average: 
enable='between(t,1,3)'[out0]"

エンコード

ffmpeg -i input.mp4 -filter_complex 
"split=8[a][b][c0][d][e][f][g][h]; 
[b]trim=start_frame=1,setpts=PTS-STARTPTS[b1]; 
[c0]trim=start_frame=2,setpts=PTS-STARTPTS[c1]; 
[d]trim=start_frame=3,setpts=PTS-STARTPTS[d1]; 
[e]trim=start_frame=4,setpts=PTS-STARTPTS[e1]; 
[f]trim=start_frame=5,setpts=PTS-STARTPTS[f1]; 
[g]trim=start_frame=6,setpts=PTS-STARTPTS[g1]; 
[h]trim=start_frame=7,setpts=PTS-STARTPTS[h1]; 
[a][e1]blend=c0_mode=average[ae]; 
[b1][f1]blend=c0_mode=average[bf]; 
[c1][g1]blend=c0_mode=average[cg]; 
[d1][h1]blend=c0_mode=average[dh]; 
[ae][bf]blend=c0_mode=average[aebf]; 
[cg][dh]blend=c0_mode=average[cgdh]; 
[aebf][cgdh]blend=c0_mode=average" 
-acodec copy output.mp4

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)