Verwendung eines verlustfreien Videocodecs zum Archivieren (monochromer) wissenschaftlicher Videodaten

9

Grundlegende Frage: Was ist ein geeigneter Codec zum verlustfreien Speichern / Archivieren wissenschaftlicher Videodaten ?

Ich versuche meiner Forschungsgruppe beim Speichern / Archivieren einiger mit einem Mikroskop aufgenommener Videos zu helfen. Diese (Graustufen-) Videos haben das unkomprimierte (Rohvideo) BGR24-Format, 660 x 492 @ 61 fps und sind normalerweise etwa 1 Minute lang. Meine Laborkollegen sind verrückt nach der Größe dieser Dateien (jeweils Gigabyte). Ich schlug vor, sie mit einem verlustfreien Codec zu komprimieren. (Die Notwendigkeit für verlustfrei ist hier, weil die Videos wissenschaftliche Daten sind; daher besteht die Gefahr, dass ein verlustbehafteter Codec den Inhalt auf schlechte / unerwartete Weise verändert.)

Folgendes habe ich versucht. Zuerst habe ich die ersten 10 Sekunden eines dieser Videos aufgenommen und mit FFMpeg in ein monochromes (Roh-) Format konvertiert.

ffmpeg -t 10 -i RecordedData.avi -c:v rawvideo -pix_fmt gray raw_gray.mkv

Dann habe ich versucht, den verlustfreien Modus von libx264 (durch Einstellen -crf 0) zu verwenden, um die resultierende Datei zu komprimieren

ffmpeg -i raw-gray.mkv -c:v libx264 -crf 0 -pix_fmt yuv420p -color_range pc x264-yuv420p.mkv

Schließlich habe ich die YUV-Rohdaten sowohl aus den Roh- als auch aus den h264-MKV-Dateien extrahiert und verglichen.

ffmpeg -i raw-gray.mkv -c:v rawvideo -pix_fmt gray raw-gray.yuv
ffmpeg -i x264-yuv420p.mkv -c:v rawvideo -pix_fmt gray x264-decompressed.yuv
diff -sq raw-gray.yuv x264-decompressed.yuv

Hier diffmeldet der Befehl, dass sich die Dateien unterscheiden, wenn ich erwartet habe, dass sie gleich sind. Warum ist das? Ist dies nur ein kleiner Rundungsfehler oder verliere ich möglicherweise etwas, nachdem ich die H264-Komprimierung (angeblich verlustfrei) durchgeführt habe? Es gibt einige Konvertierungen von Pixelformaten ( gray (YUV400) <-> YUV420), aber die Farbkanäle (UV) sollten nur leer sein, da die Eingabe monochrom ist.

Wenn ich tatsächlich etwas verliere, kann ich irgendetwas tun, um dies zu beheben? Gibt es einen anderen (verlustfreien) Codec, der für meine Daten besser geeignet ist?


Update 1 : Ich habe hexdump verwendet, um den Inhalt der unkomprimierten YUV-Daten von raw-gray.yuv(nie komprimiert) und x264-decompressed.yuv(komprimiert und dann dekomprimiert) genauer zu vergleichen. Hier sind die ersten paar Bytes.

[raw-gray.yuv]

00000000  4e 50 51 53 53 52 51 50  51 51 50 4f 50 50 50 50
00000010  51 51 50 51 52 53 51 51  52 52 53 53 52 51 51 53
00000020  51 53 54 55 53 51 52 54  53 53 52 50 51 50 52 52
00000030  51 52 51 51 51 52 54 52  52 52 51 51 51 53 57 58
00000040  57 57 55 54 54 52 53 51  51 52 53 55 55 54 53 53
00000050  51 51 52 52 53 52 51 50  50 50 50 51 51 4f 4f 4e
00000060  4c 4d 4e 4d 4f 50 4f 50  51 51 51 52 52 52 52 50
00000070  50 50 52 52 53 55 55 55  57 52 53 53 53 54 56 56

[x264-decompressed.yuv]

00000000  53 55 56 57 57 56 56 55  56 56 55 54 55 55 55 55
00000010  56 56 55 56 56 57 56 56  56 56 57 57 56 56 56 57
00000020  56 57 58 59 57 56 56 58  57 57 56 55 56 55 56 56
00000030  56 56 56 56 56 56 58 56  56 56 56 56 56 57 5b 5c
00000040  5b 5b 59 58 58 56 57 56  56 56 57 59 59 58 57 57
00000050  56 56 56 56 57 56 56 55  55 55 55 56 56 54 54 53
00000060  51 52 53 52 54 55 54 55  56 56 56 56 56 56 56 55
00000070  55 55 56 56 57 59 59 59  5b 56 57 57 57 58 5a 5a

Die Werte aus der ersteren Datei sind 4 bis 5 niedriger als die Werte in der letzteren. Das gleiche wird gefunden, wenn man etwas tiefer in die Datei gräbt.


Update 2 : Wenn ich libx264 im RGB-Modus verwende, kann ich eine exakte Übereinstimmung mit dem Original erzielen, indem ich zusätzlich zu den folgenden Schritten wie oben beschrieben vorgehe.

ffmpeg -i raw-gray.mkv -c:v libx264rgb -crf 0 -pix_fmt bgr24 x264-bgr24.mkv
ffmpeg -i x264-bgr24.mkv -c:v rawvideo -pix_fmt gray x264-bgr24-decomp.yuv
diff -sq raw-gray.yuv x264-bgr24-decomp.yuv

Der letzte Befehl meldet, dass die beiden Dateien identisch sind . Leider x264-bgr24.mkvist etwa dreimal größer als x264-yuv420.mkv, so dass die Komprimierung im RGB-Modus nicht so gut ist.

Ich habe irgendwo gelesen, dass libx264 Graustufenvideos im YUV-Modus effizient komprimiert, weil es die Tatsache aufgreift, dass nur der Y-Kanal echte Informationen enthält (U- und V-Kanäle sind für monochrome Videos beide Null). Im RGB-Modus würden meiner Meinung nach alle Kanäle identische Informationen für die Monochrom-Eingabe enthalten. Vielleicht nutzt libx264rgb das nicht aus.

Gibt es für mich eine Möglichkeit, den YUV-Modus zu verwenden, ohne das Video zu ändern, da die Komprimierung auf diese Weise viel effizienter ist?


Update 3 : Ich konnte das Problem mit libx264 lösen, indem ich -pix_fmt yuvj420panstelle von -pix_fmt yuv420p -color_range pc. Dann reproduziere ich die Originaldatei genau nach der Komprimierung / Dekomprimierung. Aus der FFmpeg-Dokumentation hatte ich den Eindruck, dass diese beiden Flaggensätze gleichwertig waren, aber dies ist offensichtlich nicht der Fall. Das einzige Problem ist, dass ich mit den letzteren Flags eine Warnung erhalte : [swscaler @ 0x55b56347fe20] deprecated pixel format used, make sure you set the range correctly. Außerdem habe ich diesen Fehlerbericht gefunden, der mit meinem Problem zusammenhängen könnte. Ich bin mir nicht sicher, wie ich Dinge "richtig" machen soll, ohne das anscheinend veraltete Pixelformat yuvj420p zu verwenden.

Nick C.
quelle
1
Da die Daten dekomprimiert sind, sollten Sie sie besser in ein Textformat umwandeln (z. B. mit hexdump) und das Diff darauf ausführen. diffIch werde einfach sagen, dass die Dateien irgendwo anders sind. Ein Bit, ein Megabyte, es ist alles das Gleiche. Wenn Sie den Hex-Diff untersuchen, können Sie besser abschätzen, was passiert ist und ob Sie sich Sorgen machen müssen. Überprüfen Sie auch, ob der Vorgang die Breite oder Höhe des Videos nicht abgerundet hat (mir ist das passiert).
LSerni
1
Eine mögliche Störquelle könnte eine andere Y-Kanal-Klemmung sein (gemäß CCIR-601). Überprüfen Sie, ob Sie zufällig Y-Werte unter 16 und über 240 verlieren. Siehe auch video.stackexchange.com/questions/16840/…
LSerni
1
Sie können auch ffmpeg verwenden, um Ihre beiden Videos in einzelne Bilder zu zerlegencompare und sie mit Imagemagicks zu vergleichen.
Xenoid
1
Ein guter Weg, um Verlustfreiheit zu vergleichen, ist die Verwendung des Hash- Muxers. Zeigen Sie die vollständige Ausgabe von ffmpeg -i RecordedData.avi. libx264rgb unterstützt bgr24, daher können Sie diesen Encoder als Option betrachten.
Llogan
1
Codieren Sie sie einfach verlustfrei im RGB-Modus von x264 (Pixelformatkonvertierung überspringen).
Gyan

Antworten:

6

Dies ist keine eindeutige Antwort auf Ihr eigentliches Problem, aber ich würde in Betracht ziehen, den FFmpeg-internen FFV1Codec zu verwenden:

$ ffmpeg -i raw-gray.mkv -c:v ffv1 ffv1.mkv

Alternativ Version 3 davon:

$ ffmpeg -i raw-gray.mkv -c:v ffv1 -level 3 ffv1.mkv

Dann:

$ ffmpeg -i ffv1.mkv -c:v rawvideo -pix_fmt gray raw-gray.yuv
$ diff -sq raw-ffv1.yuv raw-gray.yuv
Files raw-ffv1.yuv and raw-gray.yuv are identical

Es ist nicht so effizient wie libx264 im verlustfreien Modus yuv420p, aber es ist effizienter als die Verwendung von libx264 mit bgr24(in meinen Tests lag die Datenrate irgendwo dazwischen). Einige Institutionen wie die Library of Congress erkennen FFV1 auch als geeignetes Aufbewahrungsformat an .

slhck
quelle
Dies ist jedoch eine Antwort auf meine ursprüngliche Grundfrage, die ich bearbeitet habe, um sie klarer zu machen. Ich habe keine Probleme mit FFV1 festgestellt. Tatsächlich erreichte FFV1 -crf 0 -preset mediumfür mein spezielles Video ungefähr das gleiche Komprimierungsverhältnis wie libx264 (w / ) und es war schneller. Noch besser ist, dass es das grayPixelformat direkt unterstützt . In der Tat scheint dies eine ausgezeichnete Lösung zu sein.
Nick C.