2017-06-10 57 views
14

Próbuję wdrożyć kodowanie QM do celów edukacyjnych. Moim głównym zasobem jest rozdział 5.11 z Podręcznika kompresji danych, wydanie piąte. To jest mój szorstki implementacja kodera teraz:Implementacja kodowania QM w Pythonie - czy 16 bitowe słowo jest obowiązkowe?

def _encode_bit(self, bit): 
    if bit == self._lps: 
     self._code_lps() 
    else: 
     self._code_mps() 

def _code_mps(self): 
    self._a = self._a - self._q_e() 
    if self._a < 0x8000: 
     self._switch_intervals_if_needed() 
     self._renormalize() 
     self._p_table.next_mps() 

def _code_lps(self): 
    self._c = self._c + self._a - self._q_e() 
    self._a = self._q_e() 
    self._switch_intervals_if_needed() 
    self._renormalize() 
    self._p_table.next_lps() 

def _renormalize(self): 
    while self._a < 0x8000: 
     #C < 0,5 (0xFFFF/3) 
     if self._c < 0x5555: 
      b = 0 
      d = 0 
     else: 
      b = 1 
      d = 0x5555 
     self._write_bit(b) 
     logger.debug("Written '%i' to output", b) 
     #C = 2 * (C - D) 
     self._c = (self._c - d) << 1 
     #A = 2 * A 
     self._a <<= 1 

mam mapowanie interwał do liczb całkowitych, ponieważ powinien on być bardziej efektywne, jak rozumiem. W książce wspomniano, że 16 bitowe słowo jest używane do mapowania, ale ponieważ robię to w Pythonie, nie jestem pewien czy wymuszam 16 bitową długość wszystkich zmiennych. Problem polega na tym, że po uruchomieniu mojego kodera, C (self._c w kodzie), który powinien wskazywać na dół przedziału MPS, jeśli rozumiem, poprawnie przepełnia on ponad 16-bitową długość bardzo szybko, a jego wartość staje się bardzo duża. Z tego powodu zakodowane bity to w większości ciąg znaków LPS. Czy powinienem jakoś wymuszać zmienną długość? Czy istnieje inny problem w moim kodzie? Spędziłem kilka dni na tym, próbując dowiedzieć się, co poszło nie tak ...

+1

Nie jestem zaznajomiony z koderem QM, ale podejrzewam, że istnieje problem z metodą "renormalizacji". Pomogłoby to w dodaniu pseudokodu do algorytmu _exact_, którego używasz. –

+1

Dzięki za komentarz! Cóż, to jest część, której nie zrozumiałem całkowicie i która pochodzi z materiałów mojego nauczyciela, którzy użyli tego samego źródła. Po przeczytaniu rozdziału w Handbook of Data Compression wciąż nie rozumiałem, jak powstaje wynik, więc przejąłem od niego ten kawałek. Z książki, którą zrozumiałem, wynika, że ​​renormalizacja ma miejsce, ponieważ chcę zachować A ('self._a' w kodzie) blisko 1, więc mogę pominąć bardziej złożone mnożenie podczas kodowania. Oryginalny kod można zobaczyć na slajdzie 63 w [prezentacja nauczyciela] (http://outrata.inf.upol.cz/courses/kd/komprese.pdf) –

Odpowiedz

3

W dowolnej formie kompresji arytmetycznej (jak QM), trzeba pozostać w granicach maksymalnych dozwolonych bitów (w tym przypadku 16), w przeciwnym razie będziesz mieć różnego rodzaju problemy. Te problemy obejmują błędy zaokrąglania, ponieważ teoretycznie możesz potrzebować nieskończonej precyzji. Sam algorytm zaokrągli w razie potrzeby i wykona renormalizację, aby zmaksymalizować wykorzystanie zakresu bitów. Odpowiedź na twoje pytanie brzmi "tak".

+2

, aby użyć 16-bitowego słowa, można użyć modułu 'ctypes' : https://docs.python.org/3/library/ctypes.html#ctypes.c_int16 –

+0

Dziękuję bardzo! Ta odpowiedź, chociaż nie sprawiła, że ​​mój kod działa, popchnęła mnie do działania. Teraz wyjście wygląda bardziej sensownie, ale proces kodowania/dekodowania nie zwróci oryginalnych danych wejściowych, więc muszę trochę dalej zbadać, ponieważ prawdopodobnie jest inny błąd. –

+0

Look w rozdziale 2.16 https://books.google.co.in/books?id=ujnQogzx_2EC&pg=PA129&lpg=PA129&dq=arithmetic+compression+qm&source=bl&ots=FpqBpD3wrT&sig=Z81N-n0MTIJV_YNDwcWKWlDds-o&hl=en&sa=X&ved=0ahUKEwirwb3RitTUAhWHNI8KHegkCOUQ6AEIQTAF# v = onepage & q = arytmetyczne% 20compression% 20qm & f = false. Ładny opis algorytmu. Zabawny, JPEG wykorzystuje kompresję QM. – mikep