2つ入力した映像の輝度、コントラスト、構造などを軸にピクセル単位の比較だけではなく周囲のピクセルとの相関をみて比較してオリジナルにどれだけ忠実であるか SSIM の値を計算する。主な用途はエンコード前後を比較してどれだけ劣化したのか、特定のフレームを抽出してエンコードを見直したりする。比較する動画は同じ解像度とfps、ピクセルフォーマットである必要がある。libx264 エンコードでリアルタイムで計測する場合はオプションの-tune ssim -ssim 1を使う。

最終結果だけを表示。1入力がオリジナルの動画で、2入力が SSIM を計算する動画
ffmpeg -i input1 -i input2 -filter_complex ssim -an -f null -

1入力と2入力の解像度が異なるときはscale2refフィルタで解像度指定しなくても揃えられる。
ffmpeg -i input1 -i input2 -filter_complex [1:v][0:v]scale2ref[1v][0v];[0v][1v]ssim -an -f null -

ログファイルを出力する。
ffmpeg -i input1 -i input2 -filter_complex [1:v][0:v]scale2ref[1v][0v];[0v][1v]ssim=f=ssim.txt -an -f null -

metadataフィルタでフレーム単位でコンソールに表示する方法。ここではunsharpフィルタの Y の ssim を表示している。
ffplay -i input -vf split[a][b];[b]unsharp[B];[a][B]ssim,metadata=print:key=lavfi.ssim.Y

drawtextフィルタで映像に焼き付けて再生する。
ffplay -f lavfi -i movie=input1.mp4[a];movie=input2.mp4[b];[a][b]ssim,drawtext=fontfile=C\\://Windows/Fonts/arial.ttf:fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"SSIM="%{metadata\:lavfi.ssim.ALL}'

lavfi.ssim.X形式でXに代入できるのは、Y, U, V, R, G, B, All, dBで小文字でも可能。

コンテナフォーマットが異なる、例えばMP4とMKVなどを比較する。
ffmpeg -i input1.mp4 -i input2.mkv -filter_complex "[0:v]settb=1/AVTB,setpts=PTS-STARTPTS[0v];[1:v]settb=1/AVTB,setpts=PTS-STARTPTS[1v];[1v][0v]scale2ref[1v][0v];[0v][1v]ssim" -an -f null -

framesync の設定にも対応している。
2ファイル入力するフィルタの挙動設定 framesync

動画の短い時間の方で終了するにはeof_action=1:shortest=1:repeatlast=0を追加する。
ffmpeg -i input1.mp4 -i input2.mkv -filter_complex "[0:v]settb=1/AVTB,setpts=PTS-STARTPTS[0v];[1:v]settb=1/AVTB,setpts=PTS-STARTPTS[1v];[1v][0v]scale2ref[1v][0v];[0v][1v]ssim=eof_action=1:shortest=1:repeatlast=0" -an -f null -

オプション

stats_file, f[string]
ログファイルの出力名。小数点以下は6桁まで書き込む。で標準出力する。

ログファイルの見方

  • n
    フレーム番号
  • Y, U, V, R, G, B
    コンポーネント別の SSIM。1 に近いほど忠実
  • All
    全体の平均 SSIM。各チャンネル平均
  • dB
    全体の平均 SSIM(dB)。大きいほど高画質

評価方法

似た指標に PSNR もあるが主観的な画質の比較なら SSIM のほうがよい。

ssimフィルタ、psnrフィルタを併用しログをテキストで出力する。
ffmpeg -i input1 -i input2 -filter_complex "ssim=f=ssim.txt;[0:v][1:v]psnr=f=psnr.txt" -an -f null -

TB、PTSも揃えてssimフィルタ、psnrフィルタを併用する。
ffmpeg -i input1 -i input2 -filter_complex "[0:v]settb=1/AVTB,setpts=PTS-STARTPTS,split[0va][0vb];[1:v]settb=1/AVTB,setpts=PTS-STARTPTS[1v];[1v][0va]scale2ref[1va][0va];[1va]split[1va][1vb];[0va][1va]ssim=eof_action=1:shortest=1:repeatlast=0;[0vb][1vb]psnr=eof_action=1:shortest=1:repeatlast=0" -an -f null -

http://www.jiima.or.jp/pdf/5_JIIMA_guideline.pdf より

PSNR SSIM 主観評価
40~∞[dB] 0.98以上 元の画像と圧縮画像の区別がつかない
30~40[dB] 0.90~0.98 拡大すれば劣化がわかるレベル
30以下[dB] 0.90以下 明らかに劣化がわかる

x264におけるSSIMの目安
http://www.wikihouse.com/htumenc/index.php?SSIM より

SSIM値 qp設定値(例)
0.98 以上 20 オリジナルと区別がつかない。
0.95 30 見るに耐えない。(*または辛うじて、そこそこ見られる*)
0.9 40 非常に醜い。
0.8 51 これ以上は圧縮できない
0.7 以下 素材に大量のノイズを加え、さらにそのノイズを量子化工程で消し去るほどqpを高くしない限り、達成困難。

公式ドキュメント
FFmpeg Filters Documentation : ssim
FFmpeg Filters Documentation : psnr

コメントを残す

メールアドレスが公開されることはありません。

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