用ffmpeg比較壓縮前後PSNR/SSIM


0. ffmpeg壓縮範例

ffmpeg -i movie.mp4 -c:v libx264 -crf 30 -an -sn compressed.mp4

如果用yuv檔當輸入,需要先給定影片長,寬,格式,幀率,建議先用ffplay測試過, 如果正常播放yuv的指令是:
ffplay -s 1280x720 -pix_fmt yuv420p -framerate 30 -i uncompress.yuv

4.4.2之後-s以被設為deprecated, 要改用-video_size

那用ffmpeg壓縮就是改成
ffmpeg -s 1280x720 -pix_fmt yuv420p -framerate 30 -i uncompress.yuv \
-c:v libx264 -crf 30 -an -sn compressed.mp4

其他格式影片轉出yuv檔案可以參考[1][2]

1. 比較影片PSNR

ffmpeg -i  movie.ts  -i compressed.ts  -lavfi psnr="stats_file=psnr.log" -f null -

參考資料[3]有提出與其他工具結果不一致的問題,建議改為[4]提出的指令,改寫如下:
ffmpeg -i movie.mp4 -i compressed.mp4 -lavfi '[0:v]setpts=PTS-STARTPTS[v0];[1:v]setpts=PTS-STARTPTS[v1];[v0][v1]psnr=psnr.log' -f null -

螢幕會輸出整體的比較結果

frame= 1921 fps=254 q=-0.0 Lsize=N/A time=00:01:05.33 bitrate=N/A speed=8.64x 
video:1006kB audio:12108kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_psnr_0 @ 0x2e1b480] PSNR y:17.903124 u:31.221207 v:29.559965 average:19.541083 min:12.362940 max:36.621765

改指令後,平均Y的PSNR變成34.60

輸出檔內有每一張的畫面PSNR

$ head psnr.log
n:1 mse_avg:939.97 mse_y:1365.94 mse_u:75.91 mse_v:100.13 psnr_avg:18.40 psnr_y:16.78 psnr_u:29.33 psnr_v:28.13
n:2 mse_avg:908.50 mse_y:1320.94 mse_u:72.66 mse_v:94.58 psnr_avg:18.55 psnr_y:16.92 psnr_u:29.52 psnr_v:28.37
n:3 mse_avg:875.95 mse_y:1273.75 mse_u:70.67 mse_v:90.04 psnr_avg:18.71 psnr_y:17.08 psnr_u:29.64 psnr_v:28.59
n:4 mse_avg:870.24 mse_y:1266.48 mse_u:68.73 mse_v:86.81 psnr_avg:18.73 psnr_y:17.10 psnr_u:29.76 psnr_v:28.75
...

2. 比較影片SSIM

ffmpeg -i movie.mp4  -i compressed.mp4 -lavfi ssim="stats_file=ssim.log" -f null -

參考資料[3]有提出與其他工具結果不一致的問題,建議改為[4]提出的指令,改寫如下:
ffmpeg -i movie.mp4 -i compressed.mp4 -lavfi '[0:v]setpts=PTS-STARTPTS[v0];[1:v]setpts=PTS-STARTPTS[v1];[v0][v1]ssim=ssim.log' -f null -

螢幕會輸出整體的SSIM比較結果

frame= 1921 fps=233 q=-0.0 Lsize=N/A time=00:01:05.33 bitrate=N/A speed=7.94x 
video:1006kB audio:12108kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_ssim_0 @ 0x4afc800] SSIM Y:0.688927 (5.071380) U:0.930527 (11.581831) V:0.942899 (12.433558) All:0.771522 (6.411565)

輸出檔內有每一張的畫面SSIM

$ head ssim.log
n:1 Y:0.708021 U:0.928664 V:0.945356 All:0.784351 (6.662528)
n:2 Y:0.707851 U:0.926394 V:0.945154 All:0.783826 (6.651960)
n:3 Y:0.699673 U:0.915708 V:0.944736 All:0.776522 (6.507661)
n:4 Y:0.652929 U:0.900382 V:0.930965 All:0.740510 (5.858802)
...
改指令後,平均Y的SSIM變成0.896

參考:
[1] https://codingnote.blogspot.com/2017/06/ffmpegyuv.html
[2] https://codingnote.blogspot.com/2019/12/ffmpeghdr10yuv.html
[3] https://blog.csdn.net/DeliaPu/article/details/75337951
[4] https://magiclen.org/ffmpeg-psnr-ssim/
[5] https://blog.csdn.net/ternence_hsu/article/details/86157371


留言