FFmpeg-EQ-Filterkomplex: Kontrast

11572
Jon G

Ich spiele mit dem EQ-Filter in FFmpeg:

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

Verwenden Sie einen Befehl wie:

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 

Die Dokumentation legt nahe, dass der erste Bestandteil des Filters Kontrast ist:

Stellen Sie den Kontrastausdruck ein. Der Wert muss ein Float-Wert im Bereich von -2.0 bis 2.0 sein. Der Standardwert ist "0".

Ich habe jedoch festgestellt, dass der Wert "1" sein sollte, damit sich der Kontrast nicht ändert. Sollte dies nicht die Standardeinstellung sein?

Ich bin jedenfalls verwirrt, wenn dieser erste Wert sogar kontrastiert. Es verhält sich nicht so, wie ich es anders erwartet hätte. Ich vergleiche es mit zB css -webkit-filter: contrast(x). In CSS contrast(0)wird das gesamte Bild grau dargestellt. In FFmpeg scheint das Bild jedoch teilweise gelb und grau zu sein (vermutlich abhängig von meinem Bild:

FFmpeg-EQ-Filterkomplex: Kontrast

CSS contrast(-1)ist ungültig. In FFmpeg ist der Kontrast -1 jedoch fast ein umgekehrter Kontrast. Ich verstehe, dass die beiden Dinge vollständig getrennt implementiert wurden, aber ich hätte eine ungefähre Beziehung erwartet. Verstehe ich den Kontrastwert der EQ-Filter falsch?

4
Vielleicht hilft das? https://github.com/FFmpeg/FFmpeg/blob/master/libavfilter/vf_eq.c#L77 slhck vor 8 Jahren 0

2 Antworten auf die Frage

5
Mr. What

Sie müssen die Optionen im Filter anhand des Namens angeben, sodass die ursprünglichen Filtereinstellungen in ... geändert werden mussten.

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

... wenn Sie alle diese Parameter einstellen wollten. Andernfalls ignoriert der Filter Ihre Einstellungen und wendet die Standardwerte an, oder er kann möglicherweise den Wert einer beabsichtigten Option für einen anderen falsch interpretieren (dies sollte nicht der Fall sein, aber fremde Dinge sind mit den Filtern von FFmpeg passiert).

Was die ausgewählten Werte im Vergleich zu den Endergebnissen angeht, zeigt der angegebene Code slhck, dass der Wert, den eine Option pro Option festlegt, durch eine Reihe interner Berechnungen ausgeführt wird. Anschließend werden die Ergebnisse zur Auswertung und zur Anpassung der Pixelebene verwendet. Es scheint, dass die "Basis" -Berechnung für contrast...

(param->contrast * 256 * 16) 

Der Standardwert von 0würde also 0 ergeben, ein bestimmter Wert von 14096, ein Wert von -0.00275-11.264 usw. und diese Basiswerte werden für weitere Berechnungen verwendet. Mit anderen Worten, es ist am besten, die Handhabung dieser Parameter durch den Filter als einzigartig zu betrachten, also verbringen Sie etwas Zeit damit, mit ihnen herumzuspielen, um zu sehen, wie sie funktionieren. Um eine eqgenaue Vorstellung von den Effekten zu erhalten, können Sie die Ausgabe der Einstellungen mithilfe von FFplay optimieren und überwachen, z.

ffplay -i input.jpg -vf "eq=contrast=1.5:brightness=-0.05:saturation=0.75" 

Was Ihr Originalskript angeht, da Sie nur eine Eingabe (Ihre JPEG-Datei), einen Filter (EQ) und alle Optionen außer contrastStandardwerten verwendet haben, können Sie das Skript auf das Folgende reduzieren, um Ihre 3 Sekunden zu erhalten MP4, vorausgesetzt, dass dies zu eq=contrast=1wünschenswerten Ergebnissen führt:

ffmpeg -y -loop 1 -i input.jpg -vf "eq=contrast=1" -c:v libx264 \ -pix_fmt yuv420p -t 3 out.mp4 

Vollständige Offenlegung: Nachbearbeitet 2016.06.19 für mehr Klarheit und erweiterte Informationen

3
Timothy Gu

Um Ihre ursprüngliche Frage zu Kontrast in FFmpeg vs. CSS zu beantworten, scheint das nachstehende Codefragment darauf contrasthinzudeuten, dass in FFmpeg nur für Luminanz / Luma (Helligkeit) gilt, während es saturationnur für Chrominanz / Chroma (Farben) gilt.

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); } } 

Beachten Sie, wie in set_contrastnur param[0](bezeichnet die erste Farbkomponente, die in YUV ist Y, die Luma) geändert wird, während in set_saturationnur param[1]und param[2](bezeichnet Gelb und Magenta, die Chroma) geändert. Dies sollte die Tatsache berücksichtigt, dass Sie Gelb und Magenta, zwei sehen Chroma - Farbkomponenten, wenn Sie Gegensatz zu 0 in FFmpeg verringern. Wenn Sie die Sättigung ebenfalls auf 0 setzen, sehe ich ein einfaches graues Bild, das dem von CSS erzeugten ähnlich ist.

Die Beziehung zwischen CSS contrastund saturateFFmpeg contrastund saturationkann wie folgt festgelegt werden:

filter: contrast(c) saturate(s);

ist äquivalent zu

eq=contrast=c:saturation=c*s

Obligatorische Screenshots mit c = 0,6 und s = 1,3:

CSS-Filter FFmpeg-Äq

Wow vielen Dank. Das hat mich gerettet. justswim vor 6 Jahren 0
Seltsamerweise ist die graue Farbe, die ich hier bekomme, anders als bei CSS, wenn der Kontrast mit FFMPEG auf 0 gesetzt wird. In CSS bekomme ich # 808080 (rein grau). Aber mit ffmpeg bekomme ich ein Video mit Hintergrund # 898B89, wenn der Kontrast 0 ist. Kann ich mir vorstellen, warum dies der Fall ist? justswim vor 6 Jahren 1
In den obigen Screenshots sind die Bildfarben tatsächlich etwas abgenutzt. Sie können es bemerken, wenn Sie den Himmel und die Wolken betrachten. Anscheinend gibt es hier noch etwas anderes. Haben Sie Ideen, wie Sie dies anpassen können? justswim vor 6 Jahren 0