FFmpeg eq 过滤器复合体:对比

Jon*_*n G 4 ffmpeg colors contrast

我在 FFmpeg 中使用 eq 过滤器:

https://ffmpeg.org/ffmpeg-filters.html#eq

使用如下命令:

ffmpeg -y -loop 1 -i input.jpg -filter_complex "[0:v]eq=1:0:1:1:1:1:1:1[outv]" -map [outv] -c:v libx264 -t 3 -pix_fmt yuv420p out.mp4 # does nothing
Run Code Online (Sandbox Code Playgroud)

文档表明过滤器的第一个组成部分是对比度:

设置对比度表达式。该值必须是 -2.0 到 2.0 范围内的浮点值。默认值为“0”。

但是,我发现为了不发生对比度变化,该值应为“1”。这不应该是默认的吗?

无论如何,如果这个第一个值是对比,我很困惑。它不像我期望的那样表现。我将它与例如 css 进行比较-webkit-filter: contrast(x)。在 CSS 中,contrast(0)使整个图像变灰。然而,在 FFmpeg 中,图像似乎是部分黄色和部分灰色(大概取决于我的图像:

在此处输入图片说明

CSScontrast(-1)无效。但是,在FFmpeg中,对比度-1几乎是倒对比度。我知道这两件事是完全分开实现的,但我本来希望有一个近似的关系。我误解了 eq 过滤器对比度值吗?

Mr.*_*hat 6

您需要按名称指定过滤器中的选项,因此您的原始过滤器设置需要更改为...

-filter_complex "[0:v]eq=contrast=1:brightness=0:saturation=1:gamma=1:
gamma_r=1:gamma_g=1:gamma_b=1:gamma_weight=1[outv]"
Run Code Online (Sandbox Code Playgroud)

...如果你想设置所有这些参数。否则,过滤器将忽略您的设置并应用默认值,或者它可能会将一个预期选项的值误解为另一个(它不应该,但 FFmpeg 的过滤器发生了奇怪的事情)。

就选择值与最终结果而言,slhck 指出的代码表明,每个选项设置的值是通过一系列内部计算运行的,然后将结果用于评估和进行像素级调整。看来,“基础”计算contrast是......

(param->contrast * 256 * 16)
Run Code Online (Sandbox Code Playgroud)

...所以默认值0将导致 0,指定值1将导致 4096,值-0.00275将导致 -11.264 等,并且这些基值将用于进一步计算。换句话说,最好将过滤器对这些参数的处理视为独一无二的,因此花一些时间来研究它们以了解它们是如何工作的。要真正了解效果,您可以eq使用 FFplay调整和调查设置的输出,例如:

ffplay -i input.jpg -vf "eq=contrast=1.5:brightness=-0.05:saturation=0.75"
Run Code Online (Sandbox Code Playgroud)

就您的原始脚本而言,由于您只使用了一个输入(您的 jpeg)、一个过滤器(eq),并且所有选项contrast都带有默认值,因此您可以将脚本减少到以下内容以获得 3 秒MP4,提供eq=contrast=1产生理想结果:

ffmpeg -y -loop 1 -i input.jpg -vf "eq=contrast=1" -c:v libx264 \
-pix_fmt yuv420p -t 3 out.mp4
Run Code Online (Sandbox Code Playgroud)

全面披露:2016 年 6 月 19 日编辑后,以获得更多的澄清和扩展信息


Tim*_* Gu 5

为了回答您关于 FFmpeg 与 CSS 对比度的原始问题,下面的代码片段似乎表明contrast在 FFmpeg 中仅适用于亮度/亮度(亮度),而saturation仅适用于色度/色度(颜色)。

static void set_contrast(EQContext *eq)
{
    eq->contrast = av_clipf(av_expr_eval(eq->contrast_pexpr, eq->var_values, eq), -1000.0, 1000.0);
    eq->param[0].contrast = eq->contrast;
    eq->param[0].lut_clean = 0;
    check_values(&eq->param[0], eq);
}

// ...

static void set_saturation(EQContext *eq)
{
    int i;

    eq->saturation = av_clipf(av_expr_eval(eq->saturation_pexpr, eq->var_values, eq), 0.0, 3.0);

    for (i = 1; i < 3; i++) {
        eq->param[i].contrast = eq->saturation;
        eq->param[i].lut_clean = 0;
        check_values(&eq->param[i], eq);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意 in set_contrast, only param[0](表示第一个颜色分量,在 YUV 中为 Y,亮度)如何更改,而 in set_saturationonlyparam[1]param[2](表示黄色和品红色,色度)如何更改。这应该考虑到当您在 FFmpeg 中将对比度降低到 0 时,您会看到黄色和洋红色这两种色度颜色分量。当您将饱和度也设置为 0 时,我会看到与 CSS 生成的图像类似的纯灰色图像。

contrastCSS 的和saturate与 FFmpeg 的contrast和 之间的关系saturation可以建立为:

filter: contrast(c) saturate(s);

相当于

eq=contrast=c:saturation=c*s

显示c = 0.6 和s = 1.3 的强制屏幕截图:

CSS过滤器 FFmpeg 均衡器