Використання відеокодека без втрат для архівування (монохромних) наукових відеоданих


9

Основне питання: який підходить кодек для зберігання / архівування наукових відеоданих без втрат ?

Я намагаюся допомогти моїй дослідницькій групі зі збереженням / архівуванням деяких відеозаписів, записаних мікроскопом. Ці відеоролики в градаціях сірого мають нестиснений (rawvideo) формат BGR24, 660x492 при 61 кадрів в секунду, і зазвичай триває близько 1 хвилини. Мої товариші з лабораторії божеволіють від розміру цих файлів (кожен гігабайт). Я запропонував стиснути їх за допомогою кодека без втрат. (Необхідність тут без втрат полягає в тому, що відео - це наукові дані; отже, існує певна небезпека, що втрачений кодек може змінити вміст погано / несподівано.)

Ось що я спробував. По-перше, я схопив перші 10 секунд одного з цих відео та перетворив у монохромний (необроблений) формат за допомогою FFMpeg.

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

Потім я спробував використовувати режим без втрат libx264 (встановивши -crf 0) для стиснення отриманого файлу

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

Нарешті, я витяг неперероблені YUV дані з файлів raw та h264 MKV та порівняв їх.

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

Тут diffкоманда повідомляє, що файли відрізняються, коли я очікував, що вони будуть однаковими. Чому це? Це лише незначна помилка округлення, чи я, можливо, щось втрачаю після виконання стиснення H264 (нібито без втрат)? Здійснюється певна конверсія піксельних форматів ( gray (YUV400) <-> YUV420), але кольорові (УФ) канали повинні бути просто порожніми, оскільки вхід монохромний.

Якщо я справді щось втрачаю, чи можу щось зробити, щоб виправити це? Чи є інший (без втрат) кодек, який може бути більш підходящим для моїх даних?


Оновлення 1 : Я використовував hexdump для порівняння вмісту нестиснених даних YUV raw-gray.yuv(ніколи не стискається) та x264-decompressed.yuv(стискається та потім декомпресується) більш детально. Ось перші кілька байтів.

[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

Значення з першого файлу на 4 - 5 менше, ніж в другому. Це ж виявляється, копаючи трохи глибше у файл.


Оновлення 2 : Якщо я використовую libx264 в режимі RGB, я можу отримати точну відповідність оригіналу, виконавши те саме, що описано вище, на додаток до наступного.

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

Остання команда повідомляє, що два файли однакові . На жаль, x264-bgr24.mkvприблизно в 3 рази більше x264-yuv420.mkv, тому стиснення в режимі RGB не настільки добре.

Десь я читав, що libx264 ефективно стискає відео в градаціях сірого в режимі YUV, оскільки він сприймає той факт, що лише канал Y містить будь-яку реальну інформацію (U і V канали обоє нульові для монохромного відео). У режимі RGB я вважаю, що всі канали містять однакову інформацію для монохромного введення. Можливо, libx264rgb цим не скористається.

Отже, чи є спосіб використовувати режим YUV без зміни відео, оскільки стиснення набагато ефективніше?


Оновлення 3 : мені вдалося вирішити проблему з libx264, використовуючи -pix_fmt yuvj420pзамість -pix_fmt yuv420p -color_range pc. Потім я відтворюю оригінальний файл точно після стиснення / декомпресії. З документації FFmpeg у мене склалося враження, що ці два набори прапорів були рівнозначними, але, очевидно, це не так. Єдина проблема в тому , що я отримую попередження з останнім набором прапорів: [swscaler @ 0x55b56347fe20] deprecated pixel format used, make sure you set the range correctly. Крім того, я знайшов цей звіт про помилку, який може бути пов'язаний з моєю проблемою. Я не впевнений у "правильному" способі робити речі без використання очевидно застарілого формату пікселів yuvj420p.


1
Оскільки дані є декомпресованими, вам буде краще, трансформуючи їх у текстовий формат (наприклад, використовуючи hexdump) та запустивши diff на цьому. diffпросто скаже, що файли десь інші. Один біт, один мегабайт, все одно. Оглядаючи шестнадцятковий розріз, ви можете краще оцінити, що сталося, і чи варто хвилюватись. Також переконайтесь, що операція не округла ширину чи висоту відео (у мене це було).
LSerni

1
Одним з можливих джерел перебоїв може бути інше затискання каналу Y (відповідно до CCIR-601). Перевірте, чи випадково ви втрачаєте значення Y нижче 16 і вище 240. Дивіться також video.stackexchange.com/questions/16840/…
LSerni

1
Ви також можете використовувати ffmpeg, щоб повторно розкласти свої два відео на окремі зображення та використовувати Imagemagickcompare для їх порівняння.
ксеноїд

1
Хороший спосіб порівняння втрат - використання хеш- мюксерів. Показати повний вихід ffmpeg -i RecordedData.avi. libx264rgb підтримує bgr24, тому ви можете розглянути цей кодер як варіант.
llogan

1
Просто кодуйте їх без втрат, використовуючи режим RGB x264 (пропуск конверсії формату пікселів).
Gyan

Відповіді:


6

Це не просто відповідь на вашу дійсну проблему, але я б розглядав можливість використання внутрішнього FFV1кодека FFmpeg :

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

Альтернативно, версія 3 його:

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

Тоді:

$ 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

Це не так ефективно, як libx264 в режимі без втрат при використанні yuv420p, але це більш ефективно, ніж використання libx264 з bgr24(у моїх тестах, швидкість передачі даних була десь посередині). Деякі установи, такі як Бібліотека Конгресу, також визнають FFV1 як відповідний формат збереження .


Це відповідь на моє початкове основне запитання, яке я відредагував, щоб зробити більш зрозумілим. У мене не виникло жодних проблем з FFV1. Насправді FFV1 досяг приблизно такого ж співвідношення стиснення, що і libx264 (w / -crf 0 -preset medium) для мого конкретного відео, і це було швидше. Ще краще, що він безпосередньо підтримує grayформат пікселів. Дійсно, це здається відмінним рішенням.
Нік К.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.