Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[atmega][c] Dekompresja JPEG, czy możliwa?

lucas_mcs 05 Paź 2009 20:41 3553 18
  • #1 05 Paź 2009 20:41
    lucas_mcs
    Poziom 22  

    Od dłuższego czasu szukam informacji i nie mogę znaleźć nic ciekawego.

    Potrzebuje wykonać dekoder JPEG na uC (najprawdopodobniej atmega), poszukuje informacji jak bardzo realne jest zrobienie czegoś takiego na uC. Czy jest gdzieś podobny projekt z kodem źródłowym?

    Obrazki będą raczej małe ~200x200 px

    Jak dużej mocy obliczeniowej potrzeba na zdekodowanie takiego obrazka w krótkim czasie? Dekodowanie musi być dość szybkie - chodzi mi o szybki odbiór danych (skompresowany JPEG) dekompresje i zachowanie w nieskompresowanej postaci jak gdyby "w locie" - czyli zakładając ze wysłanie 1 obrazka trwa 1 sekunde to chce zeby wtym czasie został on też zdekodowany i zapisany. Oczywiście najbardziej interesuje mnie realny czas jaki jest osiągalny.
    Mam nadzieje ze to zrozumiałe co napisałem.

    Czy są jakieś gotowe biblioteki do dekodowania jpeg w C? (na uC, lub nawet PC - sam nie znalazłem jeszcze dobrych źródeł) - nie marzy mi się implementowanie tego na podstawie opisu algorytmu..

    0 18
  • #3 05 Paź 2009 20:47
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Przejrzyj ten temat

    https://www.elektroda.pl/rtvforum/topic1392440.html

    Program na ARM zajmuje 170kB kodu i prawie 50kB RAMu, nie sądze żeby jakakolwiek ATmega była w stanie udźwignąć JPEG w rozsądnym czasie.

    4\/3!!

    0
  • #4 05 Paź 2009 22:25
    lucas_mcs
    Poziom 22  

    No to nie ciekawie, dzięki za nakierowanie, nie sądziłem, że JPEG będzie aż tak skomplikowany. MP3 podobno daje się odtworzyć na Atmedze a zawsze wydawało mi się bardziej obciązające niż odtwarzanie zdjęć.
    Zresztą przecież wszystkie MP4, telefony świetnie sobie radzą z dekodowaniem i wyświetlaniem jpg i innych formatów.

    Mój problem polega na tym, że muszę w krótkim czasie przesłać obrazki przez uC do zewnętrznej pamięci flash. Jak te obrazki znajdą się w pamięci to będą wyświetlane jako animacja, ale to już mniej ważne. Problem polega na tym, że obrazki w formacie który się nadaje bezpośrednio do wyświetlania (nazwijmy to zwykłą bitmapą "BMP") zajmują bardzo duzo miejsca więc w konsekwencji są bardzo wolno przesyłane
    (nie można zwiększyć szybkości transmisji)

    Myślałem właśnie żeby wysyłac bezpośrednio w formacie JPG i dekodować przed zapisaniem do flasha - ale dekodowanie i zapis musi się odbywać w tempie transmisji, żeby wszytko nadążało.

    W związku z tym mam pytanie jakie metody dekompresji się tu nadadzą, żeby uC (atmega, może xmega) dawał radę...

    Kompresja(może być stratna) przed wysłaniem będzie się odbywała na PC - i liczy się skuteczne zmniejszenie ilości przesyłanych danych oraz czas dekompresji na uC.

    Czy koledzy mają jakieś pomysły?

    0
  • #5 05 Paź 2009 22:39
    tmf
    Moderator Mikrokontrolery Projektowanie

    MP3 AVRy dekoduja, ale za pomoca zewnetrznego, sprzetowego dekodera. Co do JPEG to moze nie jest tak tragicznie, biblioteki na PC sa pisane tak, ze nie przejmuja sie iloscia zajmowanej pamieci RAM, najpewniej daloby sie ilosc koniecznych zasobow mocno ograniczyc, tyle, ze sam obrazek 200x200px w 8-bitowej glebi koloru to juz 40000 bajtow, w true color masz 120000 bajtow, czyli straszna marnosc przy podlaczeniu do ATMegi, ale juz XMega sobie z tym poradzi. Ale moze prosciej jest przesylac zamiast JPEG GIFy? Dekodowanie gifow przy pewnych uproszczeniach jest proste, jesli potrzebujesz wieksza glebie kolorow to png. Co do JPEG to 8 bitowiec to udzwignie przy dolozeniu mu wspomagania w postaci np. CPLD. Na opencores znajdziesz gotowe sprzetowe dekodery JPEG. Oczywiscie powstaje pytanie czy zamiast takiego dziwolaga nie zastosowac np. AVR32 lub ARMa?

    0
  • #6 08 Paź 2009 14:36
    lucas_mcs
    Poziom 22  

    Procesor niestety zostaje ATMega168
    Obrazek będzie QVGA 320x240 8bit/kolor

    Jaki sposób kompresji się może nadać, żeby ta atmega sobie poradziła?
    Teraz już mówimy o jakimkolwiek stopniu kompresji, nawet nieznacznym

    Zastanawiałem się też nad pomysłem połowicznego dekompresowania na PC, przesyłania i dokończenia dekompresji na ATMedze..

    Czy jest gdzieś jakieś porównanie algorytmów kompresji/czasów/obciążenia procesora?

    0
  • #8 08 Paź 2009 15:20
    tmf
    Moderator Mikrokontrolery Projektowanie

    Twoj obrazek zajmie 76800 bajtow, masz tyle pamieci? Czy chcesz od razu dekompresowac do FLASH?
    LZW nie wiem czy ci przypasuje, bo co prawda dekompresja jest szybka, ale potrzebujesz pamiec do przechowywania tabeli slownikowych. Slowniki moga zajac sporo RAMu. Z prostych rzeczy to RLE - tylko to raczej do prostych obrazkow wygenerowanych na komputerze, zdjecia raczej sie nie skompresuja. Mozesz sprobowac z GIF, PNG, ale to wszystko odmiany LZW + header, wiec problem podstawowy ten sam - potrzebujesz sporo pamieci RAM.

    0
  • #9 08 Paź 2009 20:25
    lucas_mcs
    Poziom 22  

    Z tego co wyliczyłem to dane obrazu zajmą 3*8*320*240=230400 bajtów
    Tak, dekompresja będzie od razu do flasha (będize to szybki DataFlash)

    uC ma 16k flasha i 1k sramu więc krucho jest z warunkami..

    Z dzisiejszych poszukiwań to przypadło mi LZ77/ LZ78
    http://pl.wikipedia.org/wiki/LZ77
    o ile dobrze zrozumiałem to dekompresja jest dość prosta.

    Pewną zaletą będzie to że obrazki będą dość jednolite (w sensie 40% tła w jednolitym kolorze 40% powtarzalnych wzorów i około 20% danych które mogą nie ulec skompresowaniu ze względu na duża różnorodność)

    Może podpowiedzą dla kogoś będzie, że mogę na przykład przesyłać tylko częściowo zdekompresowane dane i ostatni krok algorytmu może się wykonać na uC (A wcześniejsze kroki na PC)


    Wymyśliłem też "własny algorytm" na kompresję i dekompresję polegającą na liczeniu wystąpień bitów:
    111111111111110000000000000000111111111111111111111111
    kolejno 14 jedynek, 16 zer, 24 jedynki
    dane będa wysyłane jako bajty informujące o ilości wystąpień jedynek i zer naprzemiennie.. czyli zamiast danych wysyłałoby sie informacje o ilości
    14,16,24,..itd
    Czyli teoretycznie zamiast 8bajtów wysyłałoby się 3bajty a uC nabierząco generowałby ciągi i zapisywał do Flasha

    ....co byłoby skuteczne przy długich ciągach samych jedynek i samych zer, natomiast w przypadku ciągów krótszych niż 8 tych samych znaków to było by jeszcze więcej danych niż w oryginale..

    Dodano po 14 [minuty]:

    tmf napisał:
    LZW nie wiem czy ci przypasuje, bo co prawda dekompresja jest szybka, ale potrzebujesz pamiec do przechowywania tabeli slownikowych.


    Mogę zastosować modyfikację tego ograniczając słownik do X pozycji tak żeby nie przepełnic pamięci uC, Po stronie PC kompresująć wybierze się te pozycje które dają najlepszą kompresję..

    0
  • #10 09 Paź 2009 09:53
    tmf
    Moderator Mikrokontrolery Projektowanie

    Moj blad - niedokladnie spojrzalem i myslem, ze masz obraz o 8 bitowej glebi, a ty masz 8bitow/kolor. Czyli istotnie 3xtyle. LZ77/78 to algorytm podobny do LZW i jest stosowany wlasnie w GIFie. Wymaga przy dekompresji budowania tabeli slownikowej i procek z 1kB SRAM nie da rady. Ale z tego co piszesz to wlasnie RLE bedzie dla ciebie idealne - z grubsza dziala to dokladnie jak twoj pomysl z liczeniem takich samych bitow, tyle, ze dziala na bajtach.

    0
  • #11 09 Paź 2009 12:09
    atom1477
    Poziom 43  

    To ja proponuję uproszczony JPEG.
    Czyli DCT + wycinanie współczynników o najwyższych częstotliwościach.
    Przetestowane i działa. Jakość zadziwiająco dobra. Stopień kompresji jakieś 1/4.
    DCT na AVR nawet mam. Jeden blok 8x8pixeli w 0,2ms.
    240x240 pixeli to 900 bloków. Czyli 3x900x0,2ms = 540ms.
    Ale DCT o ile mam to jest nie do końca przetestowane. Więc dużo przy tym jeszcze roboty a czas wykonania może się znacząco wydłużyć.
    Czy gra naprawdę jest warta świeczki?
    ARM7 już by sobie z tą moją kompresją poradził.

    Jeżeli to mają być raczej takie gify, to może jakaś kompresja różnicowa?
    Wysyłał byś wartość o jaką kolejny pixel różni się od poprzedniego.
    Pixele o wartościach powiedzmy 0...120. Różnica w zakresie -120...120.
    Wartość -121 - dwa kolejne identyczne pixele.
    Wartość -122 - 4 kolejne identyczne pixele
    Wartość -123 - 6 kolejnych identycznych pixeli.
    Czyli dla różnorodnych pixeli miał byś pewną nadmiarowość danych, ale dla identycznych już kompresję.
    Albo inaczej:
    Pixele od 0...250.
    Wartość 251 - dwa pixele takie jak poprzedni
    Wartość 252 - 4 pixele takie jak poprzedni.
    Wartość 253 - 6 pixeli takich jak poprzedni.

    Coś nawet podobnego do RLE.

    0
  • #12 09 Paź 2009 15:01
    lucas_mcs
    Poziom 22  

    Dzięki za wypowiedzi.

    Dalsze testy wyłoniły faktycznie trzech kandydatów
    RLE, LZW, LZ77

    co do LZW to
    na tej stronie
    można przeczytać

    Cytat:

    Decompression

    During decompression, the algorithm rebuilds the dictionary in the opposite direction; it thus does not need to be stored.


    że nie trzeba zapamiętywać słownika

    Dziś zająłem się głównie RLE, wyszło mi że jestem w stanie uzyskać kompresję
    w okolicy 1,6:1 w trybie bezstratnym wykorzystując jakieś źródło w C znalezione w internecie.

    LZ77 jest stosowany w PNG i ma lepsze rezultaty, nie szukałem jeszcze dokładnych informacji



    Dane które otrzymuje są w JPG (z kamery internetowej) i są dalej rozkompresowywane do RAW i przesyłane... Jednym z warunków jest tez
    nie doprowadzenie do pogorszenia jakości w stosunku do dostarczanego na początku JPG


    Mam pytanie do JPG:
    Czy nie jest przypadkiem tak, że docelowo JPG ucina ilość bitów na kolor i np obcina dwa/trzy najmłodsze bity, po czym przy dekompresji odwzorowuje je szumem?

    Napisałem dziś na szybko aplikację symulującą utrate informacji na danej ilości bitów (brakujące dane zastępowane są szumem) i rezultaty są całkiem obiecujące
    [atmega][c] Dekompresja JPEG, czy możliwa?

    Zasadniczo mogłbym obciąć 2 najmłodsze bity z każdego koloru i zastąpić je szumem, ale warunek jest taki że to muszą być te same dane które obcina JPEG -> czyli zasadniczo sprowadzałoby sie to do wycięcia szumu i zastąpienia go innym szumem :-)

    0
  • #13 09 Paź 2009 16:46
    atom1477
    Poziom 43  

    lucas_mcs napisał:
    Mam pytanie do JPG:
    Czy nie jest przypadkiem tak, że docelowo JPG ucina ilość bitów na kolor i np obcina dwa/trzy najmłodsze bity, po czym przy dekompresji odwzorowuje je szumem?


    A gdzieś takich głupot się naczytał?
    Obcinanie owszem jest, ale dopiero po transformacie DCT. Więc wpływ tego obcinania na kolory nie jest bezpośredni.
    Ale żaden szum potem nie jest dodawany. Chyba że weźmieny ten szum który powstaje podczas transformat, ale to się chyba nie liczy. Bo on nie jest tak normalnie dodawany. Sam się dodaje.

    0
  • #14 10 Paź 2009 13:16
    m.bartczak
    Poziom 16  

    Zawsze mozesz sprobowac tez zrobic cos w rodzaju starego, amigowego HAM:

    Albo kompresje algorytmen kompresowania tekstur DXT

    HAM daje kompresie rzedu 3:1, DXT mozesz zrobic nawet 8:1, oba sa super banalne do zaimplementowania na AVR'ze.

    0
  • #15 10 Paź 2009 13:23
    atom1477
    Poziom 43  

    lucas_mcs: a mógł byś wrzucić trochę przykładowych obrazków?
    Najlepiej po kilka różnych wersji i każda wersja żeby zawierała ze 3 następujące po sobie klatki. Może różnica pomiędzy klatkami też jest mała i to pozwoli na zwiększenie kompresji.

    0
  • #16 10 Paź 2009 16:40
    lucas_mcs
    Poziom 22  

    atom1477 napisał:
    lucas_mcs: a mógł byś wrzucić trochę przykładowych obrazków?
    Najlepiej po kilka różnych wersji i każda wersja żeby zawierała ze 3 następujące po sobie klatki. Może różnica pomiędzy klatkami też jest mała i to pozwoli na zwiększenie kompresji.


    Obrazków nie mogę wrzucić bo nawet nie posiadam w tej chwili, ale też o tej kwestii myślałem.

    Seria ramek generalnie bedzie tworzyła iluzje 3D i będzie to np obracający się przedmiot(różne kształty i rozmiary, także półprzezroczyste i niejednolite) na jednorodnym tle (czyli seria zdjęc z różnych kątów) więc animacja jako całość będzie także dawała się mocno kompresować. Ale tu już chyba zbyt mnożą się problemy.

    Trzeba pamiętać że uC ma 1kB SRAM, dekompresja powinna iść strumieniowo. Jak potem te dane będą wyświetlane to nie chce też zmieniać formatu danych zapisywanych do FLASHa, żeby nie przerabiać algorytmu wyświetlania, który już jest gotowy..

    Odnośnie JPEG to musiało mi się pomylić z czym innym, ale naocznie ciężko mi jest zauważyć różnicę pomiędzy 1szym a 3cim obrazkiem :)

    Dzięki za podpowiedź odnośnie algorytmów kompresji tekstur - nie wpadłem na to i na pewno też poszukam w tym dziale

    0
  • #17 10 Paź 2009 16:59
    atom1477
    Poziom 43  

    Gdyby było więcej RAMu to można by dać kompresję różnicową pomiędzy klatkami. To znaczy pierwsza klatka była by przesyłana normalnie, może nawet bez jakiejkolwiek kompresji, a kolejne jako (skompresowana (nawet bezstratnie)) różnica pomiędzy ramką poprzednią a bierzącą.
    Ale że RAMu mało, to to nie przejdzie.
    Przetestowane nawet na zwykłych filmach (gdzie jest dużo szumu w obrazie) i działa znakomicie.

    0
  • #18 10 Paź 2009 21:04
    m.bartczak
    Poziom 16  

    Nie wiem czy ktokolwiek opisywał algorytmy kompresji tekstur gdziekolwiek :)

    Możesz je znaleźć na WIKI na szczęście:

    http://en.wikipedia.org/wiki/Hold-And-Modify - wybitnie łatwe do implementacji - kompresja ok. 3:1

    W wypadku najprostszej implementacji należy przyjąć stałą bazę kolorów 'podstawowych', dzięki temu nie będzie trzeba jej zapamiętywać.

    W takiej imlementacji każdy bajt reprezentuje odpowiednio:

    00RRGGBB - kolor piksela określany jest przez kombinację 64 kolorów podstawowych RGB
    01RRRRRR - kolor piksela określany jest na podstawie koloru piksela bezpośrednio na lewo, z podmienionymi 6 najstarszymi bitami R
    10GGGGG - kolor piksela określany jest na podstawie koloru piksela bezpośrednio na lewo, z podmienionymi 6 najstarszymi bitami G
    11BBBBBB - kolor piksela określany jest na podstawie koloru piksela bezpośrednio na lewo, z podmienionymi 6 najstarszymi bitami B

    http://en.wikipedia.org/wiki/S3_Texture_Compression#DXT1 - polceam najprostszy DXT1 ze względu na stopień kompresji

    0