Utilizzo di un codec video lossless per l'archiviazione di dati video scientifici (monocromatici)


9

Domanda di base: che cos'è un codec adatto per archiviare / archiviare dati video scientifici in modo lossless ?

Sto cercando di aiutare il mio gruppo di ricerca a archiviare / archiviare alcuni video registrati al microscopio. Questi video (in scala di grigi) sono in formato BGR24 non compresso (rawvideo), 660x492 @ 61fps e in genere lunghi circa 1 minuto. I miei compagni di laboratorio stanno impazzendo per le dimensioni di questi file (gigabyte ciascuno). Ho suggerito di comprimerli usando un codec senza perdita di dati. (La necessità di perdita di dati qui è perché i video sono dati scientifici; quindi c'è il pericolo che un codec con perdita di dati possa alterare il contenuto in modi cattivi / imprevisti.)

Ecco cosa ho provato. Innanzitutto, ho acquisito i primi 10 secondi di uno di questi video e convertito in un formato monocromatico (non elaborato) utilizzando FFMpeg.

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

Quindi, ho tentato di utilizzare la modalità lossless di libx264 (impostando -crf 0) per comprimere il file risultante

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

Infine, ho estratto i dati grezzi YUV sia dai file MKV grezzi che h264 e li ho confrontati.

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

Qui, il diffcomando riporta che i file differiscono quando mi aspettavo che fossero uguali. Perchè è questo? È solo un leggero errore di arrotondamento o forse sto perdendo qualcosa dopo aver fatto la compressione H264 (presumibilmente senza perdita)? È in corso una conversione dei formati di pixel ( gray (YUV400) <-> YUV420), ma i canali di colore (UV) dovrebbero essere vuoti perché l'input è monocromatico.

Se sto davvero perdendo qualcosa, c'è qualcosa che posso fare per risolvere questo problema? Esiste un altro codec (lossless) che potrebbe essere più appropriato per i miei dati?


Aggiornamento 1 : ho usato hexdump per confrontare i contenuti dei dati YUV raw-gray.yuvnon compressi da (mai compressi) e x264-decompressed.yuv(compressi e quindi decompressi) in modo più dettagliato. Ecco i primi pochi byte.

[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

I valori del primo file sono da 4 a 5 in meno dei valori nel secondo. Lo stesso si trova scavando un po 'più a fondo nel file.


Aggiornamento 2 : se uso libx264 in modalità RGB, posso ottenere una corrispondenza esatta con l'originale facendo lo stesso come sopra in aggiunta a quanto segue.

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

L'ultimo comando segnala che i due file sono identici . Sfortunatamente, x264-bgr24.mkvè circa 3 volte più grande di x264-yuv420.mkv, quindi la compressione in modalità RGB non è buona.

Ho letto da qualche parte che libx264 comprime i video in scala di grigi in modo efficiente in modalità YUV perché si basa sul fatto che solo il canale Y contiene informazioni reali (i canali U e V sono entrambi zero per i video monocromatici). In modalità RGB, credo che tutti i canali conterrebbero informazioni identiche per l'input monocromatico. Forse libx264rgb non ne approfitta.

Quindi, c'è un modo per utilizzare la modalità YUV senza alterare il video, poiché la compressione è molto più efficiente in questo modo?


Aggiornamento 3 : Sono stato in grado di risolvere il problema con libx264 usando -pix_fmt yuvj420pinvece di -pix_fmt yuv420p -color_range pc. Quindi, riproduco il file originale esattamente dopo la compressione / decompressione. Dalla documentazione di FFmpeg, ho avuto l'impressione che questi due set di bandiere fossero equivalenti, ma evidentemente non è così. L'unico problema è che ho un avviso con la seconda serie di bandiere: [swscaler @ 0x55b56347fe20] deprecated pixel format used, make sure you set the range correctly. Inoltre, ho trovato questa segnalazione di bug che potrebbe essere correlata al mio problema. Non sono sicuro del modo "corretto" di fare le cose senza usare il formato pixel yuvj420p apparentemente deprecato.


1
Dato che i dati sono decompressi, sarebbe meglio trasformarli entrambi in un formato di testo (ad esempio utilizzando hexdump) ed eseguendo il diff su quello. diffdirà semplicemente che i file sono diversi da qualche parte . Un bit, un megabyte, è lo stesso. Ispezionando l'esagono diff è possibile stimare meglio cosa è successo e se c'è qualcosa di cui preoccuparsi. Controlla anche che l'operazione non abbia arrotondato la larghezza o l'altezza del video (mi è successo).
LSerni,

1
Una possibile fonte di disturbo potrebbe essere un diverso bloccaggio del canale Y (secondo CCIR-601). Verifica se per caso sembri perdere valori Y inferiori a 16 e superiori a 240. Vedi anche video.stackexchange.com/questions/16840/…
LSerni

1
Puoi anche usare ffmpeg per ricomporre i tuoi due video in singole immagini e usare imagemagickcompare per confrontarli.
xenoid,

1
Un buon modo per confrontare la perdita di perdita è usare l' hash muxer. Mostra l'output completo di ffmpeg -i RecordedData.avi. libx264rgb supporta bgr24, quindi puoi considerare quell'encoder come un'opzione.
Llogan,

1
Basta codificarli senza perdita di dati utilizzando la modalità RGB di x264 (salta la conversione del formato pixel).
Gyan,

Risposte:


6

Questa non è una risposta diretta al tuo vero problema, ma prenderei in considerazione l'utilizzo del FFV1codec interno FFmpeg :

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

In alternativa, la versione 3 di esso:

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

Poi:

$ 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

Non è efficiente come libx264 in modalità lossless durante l'utilizzo yuv420p, ma è più efficiente dell'uso di libx264 con bgr24(nei miei test, la velocità dei dati era da qualche parte nel mezzo). Alcune istituzioni come la Library of Congress riconoscono anche FFV1 come formato di conservazione adeguato .


Questa è una risposta alla mia domanda di base originale, che ho modificato per rendere più chiaro. Non ho riscontrato alcun problema con FFV1. In effetti, FFV1 ha ottenuto circa lo stesso rapporto di compressione di libx264 (w / -crf 0 -preset medium) per il mio video particolare, ed è stato più veloce. Ancora meglio, supporta direttamente il grayformato pixel. In effetti, questa sembra essere un'ottima soluzione.
Nick C.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.