7

我想将大量视频与一个好的参考视频进行比较,以便找到质量较差的视频。我想通过调用命令行实用程序以批处理模式执行此操作,我已经以这种方式使用 ffmpeg 来抓取视频帧。

如果我对视频进行转码,ffmpg 会给我一个 PSNR 值来比较输入和输出视频。我的印象是我可以使用这样的东西来比较两个单独的视频,但找不到办法。

我会更好地从每个视频中抓取一个帧并以某种方式进行比较吗?PSNR 可能不是我的最佳选择?

我不是在寻找质量上的微小差异,而是寻找诸如同步问题或大量降雪之类的重大差异。

有什么建议么?提前致谢 :-)

4

6 回答 6

32

这是您在 ffmpeg 中使用psnr过滤器比较两个单独视频的方式:

ffmpeg -i input_video.mp4 -i reference_video.mp4 -filter_complex "psnr" -f null /dev/null

在 Windows 上替换/dev/nullNUL.

文档说input_video它将被原封不动地传递给output_video,并且该psnr值将显示在命令行上。

于 2015-04-08T01:37:47.233 回答
10
.\..\ffmpeg -i [Input] -i [Output] -lavfi  psnr="stats_file=psnr.log" -f null -

我正在查看 ssim 命令(https://ffmpeg.org/ffmpeg-all.html#ssim)并决定尝试使用 psnr 命令来查看是否可以获得任何有用的结果。对我来说似乎很有用。日志文件有一个mse_avg值,我发现它对于检测我生成的视频中的宏块很有用。

http://www.mathworks.com/help/vision/ref/psnr.html帮助我理解了 mse 和 psnr 的含义。

于 2016-03-08T01:16:39.917 回答
6

ffmpeg 有一个 psnr 过滤器:

.. psnr             VV->V      Calculate the PSNR between two video streams.

有关详细信息,请参阅https://trac.ffmpeg.org/wiki/FilteringGuide

于 2013-12-01T23:59:42.743 回答
2

ffmpeg 可以在编码期间计算 PSNR 和 SSIM,但为了比较我使用AVISynth 比较的 2 个视频

于 2013-11-07T22:47:00.000 回答
2

如果您想使用 FFmpeg 计算 PSNR,请使用替代命令

ffmpeg -i [Input1] -i [Input2] -lavfi psnr -f null -

ffmpeg -i [Input1] -i [Input2] -filter_complex psnr -f null -

异常输出

ffmpeg version git-2019-11-22-27c6c92 Copyright (c) 2000-2019 the FFmpeg developers
...
[Parsed_psnr_0 @ 000001e47a2bee40] PSNR y:9.145728 u:22.375364 v:23.917491 average:10.819717 min:9.523630 max:14.456108

如果您使用 Java 的 JAVE2 库来处理视频

function void calculatePSNR(String in1, String in2){
    FFMPEGExecutor ffmpeg = new DefaultFFMPEGLocator().createExecutor()
    ffmpeg.addArgument("-i");
    ffmpeg.addArgument(in1);
    ffmpeg.addArgument("-i");
    ffmpeg.addArgument(in2);
    ffmpeg.addArgument("-lavfi");
    ffmpeg.addArgument("psnr");
    ffmpeg.addArgument("-f");
    ffmpeg.addArgument("null");
    ffmpeg.addArgument("-");
    try {
       ffmpeg.execute();
    } catch (IOException e) {
       e.printStackTrace();
       ffmpeg.destroy();
    }
    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()));
        int lineNR = 0;

        String line;
        while((line = reader.readLine()) != null) {
            if (line.contains("PSNR")){
                System.out.println(line);    
            }
            lineNR++;
        }

    } catch (IOException e) {
        e.printStackTrace();
        ffmpeg.destroy();
    }
    ffmpeg.destroy();
}
于 2019-11-27T01:50:32.913 回答
1

我不确定它有多合适,但我只是通过在输入和输出视频的转码过程中获取 psnr 进行了试验,然后使用 psnr 过滤器比较相同的输入和输出视频。但是,两种情况下的 psnr 值都不同。

我得到了这个用于转码:

PSNR 平均 Y:27.458 U:40.780 V:41.989 Avg:29.130 Global:28.996 kb/s:25.71

转码器 psnr 的文档只是说明:“计算压缩帧的 PSNR”。

这对于过滤器:

PSNR 平均:24.30 分钟:23.09 最大:30.50

对于过滤器,文档指出:“过滤器存储每帧的累积 MSE(均方误差),并在处理结束时对所有帧进行平均,并应用以下公式来获得 PSNR: PSNR = 10*log10(MAX^2/MSE)"

我可能会选择过滤器或转码器来一致地计算我需要比较的所有视频的 psnr,所以绝对值对我来说并不重要。

于 2015-04-09T02:51:46.857 回答