Sử dụng codec video lossless để lưu trữ dữ liệu video khoa học (đơn sắc)


8

Câu hỏi cơ bản: một codec phù hợp để lưu trữ / lưu trữ dữ liệu video khoa học một cách dễ dàng ?

Tôi đang cố gắng giúp nhóm nghiên cứu của mình thực hiện việc lưu trữ / lưu trữ một số video được ghi lại bằng kính hiển vi. Các video (thang độ xám) này ở định dạng BGR24 không nén (rawvideo), 660x492 @ 61fps và thường dài khoảng 1 phút. Những người bạn trong phòng thí nghiệm của tôi đang phát điên với kích thước tuyệt đối của những tập tin này (mỗi gigabyte). Tôi đề nghị nén chúng bằng cách sử dụng codec không mất dữ liệu. .

Đây là những gì tôi đã cố gắng. Đầu tiên, tôi lấy 10 giây đầu tiên của một trong những video này và chuyển đổi sang định dạng đơn sắc (thô) bằng FFMpeg.

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

Sau đó, tôi đã cố gắng sử dụng chế độ lossless của libx264 (bằng cách cài đặt -crf 0 ) để nén tệp kết quả

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

Cuối cùng, tôi trích xuất dữ liệu YUV thô từ cả tệp MKV thô và h264 và so sánh chúng.

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

Đây, diff lệnh báo cáo rằng các tệp khác nhau khi tôi mong đợi chúng giống nhau. Tại sao lại thế này? Đây có phải chỉ là một số lỗi làm tròn nhẹ, hoặc tôi có thể mất thứ gì đó sau khi thực hiện nén H264 (được cho là không mất)? Có một số chuyển đổi định dạng pixel xảy ra ( gray (YUV400) <-> YUV420 ), nhưng các kênh màu (UV) chỉ nên trống vì đầu vào là đơn sắc.

Nếu tôi thực sự đang mất một cái gì đó, tôi có thể làm gì để khắc phục điều này? Có một codec (lossless) nào có thể phù hợp hơn với dữ liệu của tôi không?


Cập nhật 1 : Tôi đã sử dụng hexdump để so sánh nội dung của dữ liệu YUV không nén từ raw-gray.yuv (không bao giờ nén) và x264-decompressed.yuv (nén và sau đó giải nén) chi tiết hơn. Dưới đây là một vài byte đầu tiên.

[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

Các giá trị từ tệp trước ít hơn 4 đến 5 so với các giá trị trong tệp sau. Điều tương tự được tìm thấy đào sâu hơn một chút vào tập tin.


Cập nhật 2 : Nếu tôi sử dụng libx264 ở chế độ RGB, tôi có thể có được kết quả khớp chính xác với bản gốc bằng cách thực hiện tương tự như trên ngoài các thao tác sau.

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ệnh cuối cùng báo cáo rằng hai tệp là giống hệt nhau . Không may, x264-bgr24.mkv lớn hơn khoảng 3 lần x264-yuv420.mkv, do đó, nén ở chế độ RGB là không tốt.

Tôi đã đọc ở đâu đó rằng libx264 nén video thang độ xám một cách hiệu quả ở chế độ YUV bởi vì nó chỉ nhận ra thực tế là chỉ có kênh Y chứa bất kỳ thông tin thực nào (các kênh U và V đều bằng 0 đối với video đơn sắc). Ở chế độ RGB, tôi tin rằng tất cả các kênh sẽ chứa thông tin giống hệt nhau cho đầu vào đơn sắc. Có lẽ libx264rgb không tận dụng điều đó.

Vì thế, Có cách nào để tôi sử dụng chế độ YUV mà không thay đổi video không, vì cách nén này hiệu quả hơn nhiều theo cách này?


Cập nhật 3 : Tôi đã có thể giải quyết vấn đề với libx264 bằng cách sử dụng -pix_fmt yuvj420p thay vì -pix_fmt yuv420p -color_range pc. Sau đó, tôi tái tạo tệp gốc chính xác sau khi nén / giải nén. Từ tài liệu FFmpeg, tôi có ấn tượng rằng hai bộ cờ này tương đương nhau, nhưng điều này rõ ràng không phải là trường hợp. Vấn đề duy nhất là tôi nhận được cảnh báo với bộ cờ sau: [swscaler @ 0x55b56347fe20] deprecated pixel format used, make sure you set the range correctly. Ngoài ra, tôi tìm thấy điều này báo cáo lỗi điều đó có thể liên quan đến vấn đề của tôi Tôi không chắc chắn về cách "phù hợp" để làm mọi việc mà không sử dụng định dạng pixel yuvj420p rõ ràng không dùng nữa.


1
Vì dữ liệu được giải nén, bạn sẽ tốt hơn bằng cách chuyển đổi cả hai thành một bản văn định dạng (ví dụ: sử dụng hexdump ) và chạy diff trên đó. diff sẽ chỉ đơn giản nói rằng các tập tin là một vài nơi khác nhau. Một bit, một megabyte, tất cả đều giống nhau. Bằng cách kiểm tra hex diff, bạn có thể ước tính tốt hơn những gì đã xảy ra và liệu có gì phải lo lắng không. Ngoài ra, hãy kiểm tra xem thao tác không làm tròn chiều rộng hoặc chiều cao của video (tôi đã xảy ra với tôi).
LSerni

1
Một nguồn gây gián đoạn có thể là kẹp kênh Y khác nhau (theo CCIR-601). Kiểm tra xem có bất kỳ cơ hội nào bạn dường như mất các giá trị Y dưới 16 và trên 240. Xem thêm video.stackexchange.com/questions/16840/
LSerni

1
Bạn cũng có thể sử dụng ffmpeg để phân tách lại hai video của mình thành các hình ảnh riêng lẻ và sử dụng hình ảnh của compare để so sánh chúng.
xenoid

1
Một cách tốt để so sánh sự mất mát là sử dụng băm muxer. Hiển thị đầu ra hoàn chỉnh của ffmpeg -i RecordedData.avi. libx264rgb hỗ trợ bgr24, vì vậy bạn có thể coi bộ mã hóa đó là một tùy chọn.
llogan

1
Chỉ cần mã hóa chúng một cách dễ dàng bằng chế độ RGB của x264 (bỏ qua chuyển đổi định dạng pixel).
Gyan

Câu trả lời:


6

Đây không phải là một câu trả lời thẳng cho vấn đề thực tế của bạn, nhưng tôi sẽ xem xét sử dụng FFmpeg-Internal FFV1 tiền mã hóa:

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

Ngoài ra, phiên bản 3 của nó:

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

Sau đó:

$ 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

Nó không hiệu quả như libx264 ở chế độ lossless khi sử dụng yuv420p, nhưng nó hiệu quả hơn so với sử dụng libx264 với bgr24 (trong các thử nghiệm của tôi, tốc độ dữ liệu nằm ở đâu đó ở giữa). Một số tổ chức như Thư viện Quốc hội cũng công nhận FFV1 là một định dạng bảo quản phù hợp .


Đây là một câu trả lời cho câu hỏi cơ bản ban đầu của tôi, mà tôi đã chỉnh sửa để làm rõ hơn. Tôi không gặp phải bất kỳ vấn đề nào với FFV1. Trong thực tế, FFV1 đạt được tỷ lệ nén tương tự như libx264 (w / -crf 0 -preset medium ) cho video cụ thể của tôi và nó nhanh hơn. Thậm chí tốt hơn, nó hỗ trợ trực tiếp gray định dạng pixel. Thật vậy, đây dường như là một giải pháp tuyệt vời.
Nick C.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.