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

[C]Kompresja danych w tablicach

23 Maj 2011 18:13 5093 16
  • Poziom 28  
    Bawię się w wyświetlenie animacji na telefonia Nokia3310.
    Znalazłem jakiegoś gifa, przerobiłem go na 12klatek w BMP i wygenerowałem sobie dane.

    Wkleję może jak wyglądają 3 pierwsze klatki:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    W sumie jest 12 klatek.

    Zajmuje mi to 98% pamięci procesora;/

    Tak jak widać ogrom danych się powtarza,
    Czy dałoby się w jakiś prosty sposób skompresować te dane?

    NP. badając przykład pierwszej tablicy buzia[0] to od elementu drugiego (0x01) to się cały czas powtarza.

    Myślałem nad zrobieniem czegoś takiego, że element trzeci tablicy, to byłby wskaźnik na element drugi, tak samo element czwarty tablicy to byłby wskaźnik na element drugi.

    Dobrze myślę??

    W jaki sposób to skompresować ?
  • Poziom 26  
    Proponuje coś takiego:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    -zamiana tablicy dwuwymiarowej na jednowymiarową
    -elementy są dwu-bajtowe i w starszej części jest umieszczona liczba powtórzeń, a w drugiej wartość dla wyświetlacza
  • Poziom 28  
    W sumie moja tablica jest 3 wymiarowa (teraz nie ma mnie w domu i nie mam dokładnie tego kodu)

    Mógłbyś napisać troszkę kodu jak by to miało wyglądać.
  • Moderator Mikrokontrolery Projektowanie
  • Poziom 26  
    Twoja funkcja wyświetlająca wygląda pewnie jakoś tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    zatem należy to zmienić na coś takiego
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Kody nie są sprawdzone (napisane przed chwilą) i prezentują tylko sposób modyfikacji funkcji wyświetlającej.
  • Poziom 42  
    Jak widzisz zabawa z wyświetlaczami graficznymi przy takiej animacji (podmiana plików bmp) jest bardzo ale to bardzo kosztowna jeśli chodzi o pamięć nieulotną ;)

    Kompresja cię tu nie uratuje (korzystasz zapewne z jakiegoś AVR'ka) .... bo teraz masz jakąś grafikę typu buźka1, buźka2 itd .... ale za chwilę bdziesz chciał mieć coś innego co nawet przy wyborze jakiegoś algorytmu kompresji/dekompresji i tak doprowadzi cię do szału.

    W końcu nie na darmo wymyślono np kompresję JPEG, no ale o tym bez jakiegoś ARM'a to raczej można zapomnieć .... Zresztą na inne algorytmy dekompresji też stracisz co nieco pamięci i przy różnych grafikach zysk będzie mizerny raczej .....

    jak już to ja bym może pomyślał nad jakąś albo większą pamięcią FLASH procesora, albo nad jakąś zewnętrzną pamięcią podłączaną na szynie I2C albo SPI ...... wtedy mógłbyś sobie ładować animacji aż do znudzenia.
  • Poziom 43  
    Np. pomyśl o takiej M25P10. Kosztuje z 1zł a ma 1MB pojemności.

    EDIT. Ja zapłaciłem 1zł, ale widzę że w TME za mniej jak 5zł nie kupisz :/
    Ale to i tak się bardziej opłaca niż większy AVR czy zabawa w jakieś cudowane kompresje.
  • Poziom 32  
    Najlepiej pamiec zewnetrzna typu FLASH do tego dorób sobie połaczenie z PC po uarcie i bedziesz mogł sobie nawet filmiki ładować bez koniecznosci kazdorazowej kompilacji i programowania układu.
  • Poziom 42  
    asembler napisał:
    Najlepiej pamiec zewnetrzna typu FLASH do tego dorób sobie połaczenie z PC po uarcie i bedziesz mogł sobie nawet filmiki ładować bez koniecznosci kazdorazowej kompilacji i programowania układu.


    No przecież wyżej atom1477 właśnie podał nawet konkretny typ takiej zewn. pamięci FLASH ;)

    .... a jeszcze inna alternatywa to podłączenie karty pamięci SD/MMC na przykład ;) i można sobie od razu na PC wgrać na nią pliki do animacji a potem w procku odcytywać i przesyłać na swój LCD .... o ile po dłuższym przemyśleniu nadal będzie się chciało bawić w takie animacje na takim wyświetlaczu ;)
  • Poziom 32  
    mirekk36 napisał:
    asembler napisał:
    Najlepiej pamiec zewnetrzna typu FLASH do tego dorób sobie połaczenie z PC po uarcie i bedziesz mogł sobie nawet filmiki ładować bez koniecznosci kazdorazowej kompilacji i programowania układu.


    No przecież wyżej atom1477 właśnie podał nawet konkretny typ takiej zewn. pamięci FLASH ;)

    .... a jeszcze inna alternatywa to podłączenie karty pamięci SD/MMC na przykład ;) i można sobie od razu na PC wgrać na nią pliki do animacji a potem w procku odcytywać i przesyłać na swój LCD .... o ile po dłuższym przemyśleniu nadal będzie się chciało bawić w takie animacje na takim wyświetlaczu ;)

    Sensem mojej wypowiedzi było raczej połaczenie z PC po uarcie ale każdy czyta jak chce.
  • Poziom 42  
    Nie , no oczywiście że jeśli już chcieć z PC'ta te animacje puszczać to pewnie, że połączenie przez uart jest OK....
  • Poziom 28  
    Wygląda to tak:
    Tu mam tablicę z 8 buźkami:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    I funkcja wyświetlająca obrazek:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    W załączniku może doda jeszcze 2 pliki z wszystkimi funkcjami:

    Oczywiście dołączenie zewnętrznej pamięci to najprostsze rozwiązanie, dlatego wybrałem coś ambitniejszego czyli próba kompresji tego :)
  • Poziom 32  
    To skoncz na ambicji bo skoro chcesz animacje to przy konkretnej kompresji bedziesz mógł wyświetlać chromającego dziada najwyżej.
  • Poziom 28  
    OK, skoro to nie jest takie proste jak mi się na początku wydawało, to sobie odpuszczę.
  • Poziom 26  
    Kompresja tego jest banalna, najprościej zaimplementować RLE a dla kolejnych klatek XOR do poprzedniej + RLE.
    Skompresujesz dane które zamieściłeś bez problemu do 10%.

    Używaj najmniej używanego bajt'u jako klucza. np.
    x - klucz
    y - liczba powtórzeń
    n - liczba która się powtarza
    b - dowolny bajt != x
    W tablicy wygląda to tak bbbbxynbbbbbxynbbbb
    Wadą jest to że odtworzenie bajtu klucza wymaga 3 bajtów.
    Lecąc po tablicy jeśli napotkasz na klucz, to ładujesz licznik[y] do pętli która powtarza n.

    Później możesz już XOR'ować klatki przez siebie i kompresować wynik, dzięki czemu powtarzające się np. tło prawie nie zajmuje dodatkowego miejsca na kolejnych klatkach.

    Używając podwójnej kompresji RLE czyli kompresja 1 klatki później XOR pierwszej z drugą, drugą z trzecią itd + RLE wszystkiego zmniejszyłem 16KiB obraz znaków używany przez wyświetlacz do nieco ponad 1KiB.
    Tyle że miałem całe 200us na dekompresje kolejnego bajtu przy zegarze 1.8432Mhz.
  • Poziom 26  
    Kompresje dobiera się do typu danych i do twoich buziek najprostsza jest metoda którą podałem, bo masz duże bloki danych które składają się z takich samych bajtów. Kompresję możesz przeprowadzić na piechotę. Z tym, że nie możesz trzymać w tym wypadku wszystkich buziek w jednej tablicy bo w zależności od buźki będziesz miał inny wymiar. Tablica powinna być jednowymiarowa, ponieważ nie ma potrzeby dzielenia bajtów na należące do innego wiersza. Lepiej zgromadzić wszystkie bajty razem i po zbliżeniu się do końca wiersza przeskoczyć do następnej linii. Argumenty by dokładać kartę SD są bezpodstawne w tym akurat przypadku, gdzie masz bitmapy monochromatyczne. Dla grafik kolorowych jak najbardziej i wtedy nawet nie używałbym JPG, bo nie mam algorytmu dekompresji na mikrokontrolery.
  • Poziom 43  
    Do grafik kolorowych polecam kompresję DXT1.
    Jest bardzo prosta w implementacji i nie wymaga dużej mocy obliczeniowej.
    Swojego czasu na ARM7TDMI zrobiłem kodek DXT1 potrafiący kodować/dekodować kilkanaście klatek o rozdzielczości 320x240pixeli na sekundę.
    Kompresja jest raczej niewielka bo wynosi 1/4 ale za to jakość obrazu jest bardzo dobra. Ja nie widzę różnicy w stosunku to obrazu nieskompresowanego.
    Ale to tak tylko piszę. Tutaj się to pewnie nie przyda.