FFmpeg eq 滤镜复合体:对比

FFmpeg eq 滤镜复合体:对比

我正在使用 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

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

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

但是我发现,要使对比度不发生变化,该值应该是“1”。这难道不应该是默认值吗?

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

在此处输入图片描述

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

答案1

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

-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]"

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

至于所选值与最终结果,slhck 指出的代码显示,每个选项设置的值会经过一系列内部计算,然后使用结果进行评估和像素级调整。看来“基本”计算是contrast...

(param->contrast * 256 * 16)

...因此,的默认值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"

就您的原始脚本而言,由于您仅使用一个输入(您的 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

全面披露:帖子于 2016 年 6 月 19 日编辑,以提供更清晰的说明和更多信息

答案2

为了回答你关于 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);
    }
}

请注意,在 中set_contrast,只有param[0](表示第一个颜色分量,在 YUV 中为 Y,即亮度)发生了变化,而在 中set_saturation只有param[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 方程

答案3

注意:文档中有一个错误https://ffmpeg.org/ffmpeg-filters.html#eq

正确的是:设置对比度表达式,值必须是-1000.0~1000.0范围内的浮点值,默认值为“1”。

相关内容