Sabit bir kameradan gelen bir videom var. Hem çözünürlük hem de FPS oldukça yüksek. Aldığım veriler Bayer biçimindedir ve piksel başına 10 bit kullanır. Platformumda 10 bit veri türü olmadığından, orijinal veriler 16 bit sözcükler kullanılarak bellekte saklanır. Verileri bir ağ üzerinden aktarmadan önce bir tür kayıpsız sıkıştırma uygulamak istiyorum .
- Kamera hareket etmiyor, bu yüzden ardışık çerçevelerin büyük bölümleri neredeyse aynı - ancak yine de tamamen kaçınılmaz gürültü nedeniyle (denoising bir seçenek değil, kayıpsız olması ve gürültüyü bile “kaybetmemesi” gerektiği için) ).
- Yüksek FPS nedeniyle, değişen parçalar bile art arda iki kare arasında çok fazla değişmez.
- Ancak, kamera da biraz titriyor gibi görünüyor. Çok az, ama yine de, sabit nesneler bile görüntü alanında tamamen öyle değildir.
- Sıkıştırma anında yapılmalıdır, bu yüzden çok fazla kare toplayamıyorum ve hepsini birlikte sıkıştıramıyorum, ancak 1 kare geriye bakabilir ve referans olarak kullanabilirim.
Yukarıdakilere dayanarak, ilk düşüncem veriyi bit paketlemektir, böylece bu 6 yedek bit her kelimede boşa harcanmaz. Bununla birlikte, eğer bazı entropi kodlaması (örn. Huffman vb.) Kullanırsam, fazlalık otomatik olarak dikkate alınacağını düşündüm, bu yüzden fazladan paketlemeye gerek yoktur. Bu yüzden aşağıdakileri yaptım:
- Birbirini takip eden iki kare arasında ikili fark yarattı. Orijinal veri aralığı 0 ~ 1023'tür (örneğin işaretsiz 10 bit). Fark verileri imzalanır ve aralık -1023 ~ 1023'e yükselir, ancak veri varyasyonu (veya doğru matematiksel terim nedir) orijinal verilerden çok daha az olur, aslında, değerlerin çoğu şaşırtıcı değildir, sıfıra yakındır .
- Farkı uygulayan Pirinç kodlaması. Anladığım kadarıyla, çoğunlukla küçük sayısal değerlere sahip veri setleri için iyi bir seçim gibi görünüyor.
Bu bana 1280x720 kareler için boyutta yaklaşık% 60 azalma sağlar ve test sistemim (tek bir çekirdekteki VirtualBox'ta Linux) saniyede ~ 40 sıkıştırma yapabilir (fazla optimizasyon olmadan). O kadar büyük değil, ama makul, sanırım (ya da öyle mi?).
Daha iyi yollar var mı? Sık yaptığım hatalar var mı? Kaçırdığım genel adımlar var mı? Daha sonra daha yüksek çözünürlüklü çerçeveler kullanılabilir - daha büyük çerçeve boyutları için daha iyi sıkıştırma oranları beklemeli miyim?
UPD .:
- Bu kütüphaneyi Rice kodlaması için kullandım . Kütüphane çok yavaştır (yazar bunu gerçek kullanım yerine öğrenme için bir şey olarak tanımlar), örneğin döngülerde bitleri tek tek okur ve yazar, bu da performansı öldürür. Başlangıçta bana sadece ~ 20 FPS verdi, bazı çok temel optimizasyonlardan sonra 40 FPS oldu (yukarıda bildirildiği gibi), daha sonra biraz daha optimize ettim, 80 oldu. Bu, vektörizasyon olmadan tek bir i7 çekirdeğinde.
- Vectorization gelince, ne yazık ki, Rice kodunu vektörleştirmek için bir yol düşünemedim (mümkün olup olmadığını bile bilmiyorum - Rice kodu hakkında herhangi bir veri bulamadık, Huffman kodu hakkında ne bulabiliriz Sıralı ve verimli bir şekilde vektörleştirilemez, bu Rice koduna ve diğer değişken uzunluklu kodlara uygulanabilir).
- Ayrıca tamamen farklı bir yaklaşım denedim: verileri küçük parçalara ayırın (örneğin 64 piksel gibi) ve basit sıfır bastırma kullanın. Bir bloktaki en büyük sayıyı buluyoruz, onu bloğun başına temsil etmek için gereken bit sayısını yazıyoruz (benim durumumda bunun için 4 ek bit gerekli), ardından bloktaki tüm sayıları aynı sayıda bit. Sıkıştırma oranının kötü olmasını bekledim, ancak parçalar küçükse, çoğunda gürültü sivri olmayacak, bu nedenle ikili farkları değer başına 4 ~ 6 bit gibi bir şeye indirgenebilir ve aslında, sadece Rice kodundan yaklaşık% 5 daha kötü, yaklaşık iki kat daha hızlı (örneğin benim durumum için 160 FPS). Onu vektörleştirmeyi denedim, ama vektörleşmeyi emmek gibi, belki de bundan dolayı sadece yaklaşık x1.8 daha fazla hızlanma elde edebildim.
Negatif sayılar önde gelen sıfırlara sahip olmadığından, ikili farktan sonra ve Rice / sıfır bastırmadan önce zikzak kodlaması uyguladım .