我正在使用 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 生成的纯灰色图像。
contrast
CSS和saturate
与 FFmpeg 的关系contrast
可以saturation
建立如下:
filter: contrast(c) saturate(s);
相当于
eq=contrast=c:saturation=c*s
必须显示截图C= 0.6 和s= 1.3:
答案3
注意:文档中有一个错误https://ffmpeg.org/ffmpeg-filters.html#eq
正确的是:设置对比度表达式,值必须是-1000.0~1000.0范围内的浮点值,默认值为“1”。