Фильтрующий комплекс FFmpeg eq: Контраст

11450
Jon G

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

enter image description here

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

4
Может это поможет? https://github.com/FFmpeg/FFmpeg/blob/master/libavfilter/vf_eq.c#L77 slhck 8 лет назад 0

2 ответа на вопрос

5
Mr. What

Вам необходимо указать параметры в фильтре по имени, поэтому ваши первоначальные настройки фильтра необходимо изменить на ...

-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
Timothy Gu

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

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

filter: contrast(c) saturate(s);

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

eq=contrast=c:saturation=c*s

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

CSS filter FFmpeg eq

Вау, спасибо большое. Это спасло меня. justswim 6 лет назад 0
Как ни странно, после игры с этим дольше, когда контрастность установлена ​​на 0 с FFMPEG, серый цвет, который я получаю, отличается от серого, который я получаю с CSS. В CSS я получаю # 808080 (чистый серый). Но с ffmpeg я получаю видео с фоном # 898B89, когда контраст равен 0. Есть идеи, почему это так? justswim 6 лет назад 1
На ваших скриншотах выше, цвета изображения на самом деле немного отличаются. Вы можете заметить это, если вы посмотрите на небо и облака. Кажется, что здесь что-то еще играет ... у вас есть идеи, как это отрегулировать? justswim 6 лет назад 0

Похожие вопросы