Menggunakan codec video lossless untuk pengarsipan (monokrom) data video ilmiah

9

Pertanyaan dasar: apa codec yang cocok untuk menyimpan / mengarsipkan data video ilmiah dengan cara lossless ?

Saya mencoba untuk membantu kelompok riset saya dengan menyimpan / mengarsipkan beberapa video yang direkam dengan mikroskop. Video (skala abu-abu) ini dalam format BGR24 (mentah video) terkompresi, 660x492 @ 61fps, dan biasanya berdurasi sekitar 1 menit. Teman-teman lab saya menjadi gila dengan ukuran file-file ini (masing-masing gigabytes). Saya menyarankan untuk mengompres mereka menggunakan codec lossless. (Kebutuhan untuk lossless di sini adalah karena video adalah data ilmiah; karenanya ada beberapa bahaya bahwa codec yang hilang dapat mengubah konten dengan cara yang buruk / tidak terduga.)

Inilah yang saya coba. Pertama, saya mengambil 10 detik pertama dari salah satu video ini dan dikonversi ke format monokrom (mentah) menggunakan FFMpeg.

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

Kemudian, saya mencoba menggunakan mode lossless libx264 (dengan mengatur -crf 0) untuk mengkompres file yang dihasilkan

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

Akhirnya, saya mengekstrak data YUV mentah dari file MKV mentah dan h264 dan membandingkannya.

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

Di sini, diffperintah melaporkan bahwa file berbeda ketika saya berharap mereka akan sama. Kenapa ini? Apakah ini hanya sedikit kesalahan pembulatan, atau apakah saya mungkin kehilangan sesuatu setelah melakukan kompresi H264 (seharusnya lossless)? Ada beberapa konversi format piksel yang terjadi ( gray (YUV400) <-> YUV420), tetapi saluran warna (UV) seharusnya kosong karena inputnya adalah monokrom.

Jika saya memang kehilangan sesuatu, adakah yang bisa saya lakukan untuk memperbaikinya? Apakah ada codec (lossless) lain yang mungkin lebih sesuai untuk data saya?


Pembaruan 1 : Saya menggunakan hexdump untuk membandingkan konten data YUV yang tidak terkompresi dari raw-gray.yuv(tidak pernah dikompresi) dan x264-decompressed.yuv(dikompresi dan kemudian didekompresi) secara lebih rinci. Berikut adalah beberapa byte pertama.

[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

Nilai-nilai dari file sebelumnya adalah 4 sampai 5 kurang dari nilai-nilai di yang terakhir. Hal yang sama ditemukan menggali sedikit lebih dalam ke dalam file.


Pembaruan 2 : Jika saya menggunakan libx264 dalam mode RGB, saya bisa mendapatkan kecocokan persis dengan aslinya dengan melakukan hal yang sama seperti di atas selain yang berikut ini.

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

Perintah terakhir melaporkan bahwa kedua file itu identik . Sayangnya, x264-bgr24.mkvsekitar 3 kali lebih besar dari itu x264-yuv420.mkv, jadi kompresi dalam mode RGB tidak sebaik.

Saya membaca di suatu tempat bahwa libx264 memampatkan video skala abu-abu secara efisien dalam mode YUV karena mengambil fakta bahwa hanya saluran Y yang berisi informasi nyata (saluran U dan V sama-sama nol untuk video monokrom). Dalam mode RGB, saya yakin semua saluran akan berisi info identik untuk input monokrom. Mungkin libx264rgb tidak memanfaatkan itu.

Jadi, apakah ada cara bagi saya untuk menggunakan mode YUV tanpa mengubah video, karena kompresi jauh lebih efisien dengan cara ini?


Pembaruan 3 : Saya bisa menyelesaikan masalah dengan libx264 dengan menggunakan -pix_fmt yuvj420palih-alih -pix_fmt yuv420p -color_range pc. Kemudian, saya mereproduksi file asli tepat setelah kompresi / dekompresi. Dari dokumentasi FFmpeg, saya mendapat kesan bahwa dua set bendera ini setara, tetapi ini ternyata tidak terjadi. Satu-satunya masalah adalah bahwa saya mendapatkan peringatan dengan set kedua bendera: [swscaler @ 0x55b56347fe20] deprecated pixel format used, make sure you set the range correctly. Juga, saya menemukan laporan bug ini yang mungkin terkait dengan masalah saya. Saya tidak yakin tentang cara yang "tepat" untuk melakukan sesuatu tanpa menggunakan format piksel yuvj420p yang tampaknya sudah usang.

Nick C.
sumber
1
Karena data tersebut didekompresi, Anda akan lebih baik dengan mengubah keduanya menjadi format teks (misalnya menggunakan hexdump) dan menjalankan diffnya. diffhanya akan mengatakan bahwa file-file tersebut di suatu tempat berbeda. Satu bit, satu megabyte, semuanya sama saja. Dengan memeriksa hex diff, Anda dapat memperkirakan dengan lebih baik apa yang terjadi dan apakah perlu khawatir. Juga periksa apakah operasi tidak membulatkan lebar atau tinggi video (saya punya itu terjadi pada saya).
LSerni
1
Salah satu sumber gangguan yang mungkin terjadi adalah penjepit saluran Y yang berbeda (sesuai CCIR-601). Periksa apakah ada kemungkinan Anda kehilangan nilai-Y di bawah 16 dan di atas 240. Lihat juga video.stackexchange.com/questions/16840/…
LSerni
1
Anda juga dapat menggunakan ffmpeg untuk menguraikan kembali dua video Anda menjadi gambar individual dan menggunakan imagemagick'scompare untuk membandingkannya.
xenoid
1
Cara yang baik untuk membandingkan losslessness adalah menggunakan hash muxer. Tampilkan hasil lengkap dari ffmpeg -i RecordedData.avi. libx264rgb mendukung bgr24, jadi Anda dapat menganggap encoder sebagai opsi.
llogan
1
Cukup enkode mereka tanpa kehilangan menggunakan mode RGB x264 (lewati konversi format piksel).
Gyan

Jawaban:

6

Ini bukan jawaban langsung untuk masalah Anda yang sebenarnya, tetapi saya akan mempertimbangkan untuk menggunakan FFV1codec FFmpeg-internal :

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

Atau, versi 3-nya:

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

Kemudian:

$ 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

Ini tidak seefisien libx264 dalam mode lossless saat menggunakan yuv420p, tetapi lebih efisien daripada menggunakan libx264 dengan bgr24(dalam pengujian saya, data rate berada di antara keduanya). Beberapa lembaga seperti Library of Congress juga mengakui FFV1 sebagai format pelestarian yang cocok .

slhck
sumber
Ini adalah jawaban untuk pertanyaan dasar asli saya, yang telah saya edit untuk membuatnya lebih jelas. Saya tidak menemukan masalah dengan FFV1. Bahkan, FFV1 mencapai rasio kompresi yang sama dengan libx264 (w / -crf 0 -preset medium) untuk video khusus saya, dan itu lebih cepat. Bahkan lebih baik, secara langsung mendukung grayformat piksel. Memang, ini tampaknya menjadi solusi yang sangat baik.
Nick C.