4

Я играю с фильтром эквалайзера в FFmpeg:

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 изображение выглядит частично желтым, а частично серым (предположительно, в зависимости от моего изображения:

CSS contrast(-1) недопустим. Однако в FFmpeg контраст -1 является почти инвертированным контрастом. Я понимаю, что эти две вещи были реализованы совершенно отдельно, но я бы ожидал приблизительного отношения. Я неправильно понимаю значение контрастности фильтров eq?

2 ответа2

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

... если вы хотите установить все эти параметры. В противном случае фильтр будет игнорировать ваши настройки и применять значения по умолчанию, или он мог бы неправильно интерпретировать значение одной предполагаемой опции для другой (это не должно происходить, но с фильтрами 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/06/19 для большей ясности и расширенной информации

3

Чтобы ответить на ваш первоначальный вопрос о контрасте в 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] (обозначающие желтый и пурпурный цвета, цветность). ) изменены. Это следует учитывать тот факт , что вы видите желтые и пурпурные, два цветовых компонентов цветности, при уменьшении контрастности 0 в FFmpeg. Когда вы также устанавливаете насыщенность на 0, я вижу простое серое изображение, похожее на изображение, созданное в CSS.

Отношения между contrast CSS и saturate против contrast и saturation FFmpeg может быть установлены как:

filter: contrast(c) saturate(s);

эквивалентно

eq=contrast=c:saturation=c*s

Обязательные скриншоты с показом c = 0.6 и s = 1.3:

CSS фильтр FFmpeg eq

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .