Home > Laboratorium > Jak wygląda JPEG po 100 000 rekompresji?

Jak wygląda JPEG po 100 000 rekompresji?

Z cyklu „moje szalone eksperymenty”, czyli co się dzieje z obrazem  zapisanym w formacie JPEG, jeśli będziemy go ciągle otwierać i zapisywać.

Do tego doświadczenia posłużyłem się napisanym specjalnym programem który kolejno, aż do znudzenia, otwierał i zapisywał do JPG’a ten sam obraz. I tak 100 000 razy. Nie wchodziłem zbytnio w optymalizację na ten jeden raz, stąd też nieco to trwało.

Pewnie myślicie że po kilkunastu takich operacjach z pierwotnego zdjęcia została sieczka? Prawdę mówiąc też tak myślałem. Jakież było moje zdziwienia gdy się okazało że praktycznie nic się nie zmienia! Ale gdyby to był końcowy wniosek, wpis ten był by nudny, poszedłem zatem o krok dalej 8) .

Początkowo po prostu prowadziłem rekompresje obrazu zapisując go za każdym razem w tej samej jakości. I tak jak wyżej wspomniałem, jakość zdjęcia nie pogarszała się wraz z kolejnymi iteracjami – cały czas pozostawała na określonym poziomie wynikającym ze obranego stopnia kompresji.

Dlaczego tak się dzieje? Wynika to wprost z algorytmu JPEG. W dużym uproszczeniu, polega on na zmianie obrazu w drobne gradienty które najlepiej oddają dany fragment rysunku – w zależności od stopnia kompresji są one mniej lub bardziej widoczne. Więcej na ten temat można przeczytać na stronach Wikipedii.


Poziom jakości 1%, widoczne artefakty

I tak, po pierwszym zapisaniu z formatu źródłowego algorytm JPEG stosuje stratną kompresję zamieniając nasze zdjęcie w owe gradienty. Jeśli powtórzymy tą operację na skompresowanym już JPG’u, to sytuacja powtarza się, z tą tylko różnicą że nie ma już co zmieniać gdyż obraz poddawany kompresji wpasowuje się idealnie w to co zrobił by algorytm JPEG (a co uczynił przy poprzednim zapisie).

Dlatego właśnie, wraz z kolejnymi zapisaniami nie tracimy nic na jakości. Oczywiście pod warunkiem że nic nie zmieniamy na obrazku, oraz za każdym razem stosujemy ten sam stopień kompresji! Jednakże jest to sztuka dla sztuki, po co zapisywać jak nic się nie zmienia?

Nie do końca tak jest. Jeśli wykonamy operację które nie naruszają w sposób stratny zawartości rysunku (np.: zamalowanie twarzy) to możliwe jest ponowne zapisanie bez straty jakości. Do operacji takich zaliczyć możemy obrót o 90 stopni, bądź odbicie w pionie/poziomie. Stąd też właśnie, wbudowana w system Windows przeglądarka obrazów potrafi dokonywać rotacji bez uszczerbku na jakości zdjęcia.

Pamiętaj chemiku młody…

Tak jak mówiłem, powyższy wniosek jest nudny :) . Idąc krok dalej, postanowiłem przeprowadzić cały eksperyment jeszcze raz ale tym razem zmieniając poziom jakości kompresji losowo między 95% a 100% – zmieniając tym samym warunki pracy algorytmu JPEG.

I w tym momencie zaczyna robić się ciekawie. Tutaj faktycznie zaobserwujemy już destrukcję obrazu, zobaczcie sami.


Obraz źródłowy i po pierwszych 50 iteracjach


100 i 200 iteracji


300 i 400 iteracji


500 i 750 iteracji


1 000 i 1 500 iteracji


5 000 i 10 000 iteracji


25 000 i 50 000 iteracji

Jak widać, początkowo proces przebiega bardzo szybko. Im dalej, tym więcej powtórzeń potrzeba aby dostrzec jakie zachodzą zmiany w obrazie.

Wszystko wskazuje na to jakoby sytuacji stabilizowała się, jednak w okolicach 50 000 iteracji obserwujemy coś co można nazwać załamaniem się trendu.


50 500 i 51 000 iteracji


55 000 i 100 000 iteracji

Pomiędzy 60 000 iteracją a dalszymi, aż do 100 000 obserwowane są oscylacje obrazu, tzn. nie zmienia się on w sposób jak na początku, tylko zachowuje się jak szum, coś się przemieszcza delikatnie ale nic już się nie zmienia. Mówiąc w programistycznym slangu, wygląda to jakby obraz wpadł w nieskończoną pętlę.

Na koniec jeszcze raz to samo, ale zaprezentowane na filmie w przyspieszonym tempie, który bardzo dobrze oddaje tempo zachodzenia zmian.

Podsumowanie

I to w zasadzie już wszystko. Może nie jest to zbyt wiele wnoszący do życia eksperyment, jednak na pewno ciekawy :) . Od strony praktycznej, jeśli bałeś się korzystać z systemowej funkcji rotacji zdjęć w trosce o jakoś obrazu, teraz możesz robić to bez najmniejszych oporów.

  1. 1 maja 2010 at 22:47 | #1

    @rozmiar
    Czy możesz do tego posta doać wykres, wielkość pliku/iteracja?

    Oraz wielkość pliku/ stopien kompresji.

    Chcę także zwórcić twoją uwage na kilka metod kompresjii JPG

    Sam PS daje 3 metody, normalna/normalna z optymalizacja/porogresywna 3-5 przegiegowa

    Natomiast w starym dobrym Paint Shop Pro była nawet możliwosć manipulacji wielkością makro bloków na których dokonywana była dyskretna transformacja cosinusowa.

  2. 1 maja 2010 at 22:51 | #2

    OK, na szczęście mam jeszcze wszystkie składowe pliki więc jak tylko zbiorę te dane to zamieszczę.

  3. Saskatchewan
    2 maja 2010 at 10:09 | #3

    @clondike: wiem i dlatego „pogrubiłem” słówko *teoretycznie*. To zdanie było skierowane do tych, co stwierdzili, że to porównanie jak i cały tekst były niepotrzebne i nic nie wnoszą.

  4. caruso
    2 maja 2010 at 11:34 | #4

    Ile zajęło 100k iteracji i na jakim sprzęcie?

  5. 2 maja 2010 at 15:49 | #5

    Dobre pytanie, robiłem to w kilku turach, ale ogółem to kilka godzin. Procesor Pentium Dual-Core E5300.

  6. YanPL
    6 maja 2010 at 12:00 | #6

    najciekawszy w tym całym eksperymencie jest ten czarny bloczek po prawej stronie. Skąd on się tam wziął? Jakim cudem jest on tylko jeden, mimo że obok niego obraz początkowo był bardzo podobny? dlaczego po 100k iteracjach powoli zaczyna znikać?
    jak długo należałoby kompresować i dekompresować obraz, żeby otrzymać jednokolorowy plik? i jaki byłby to kolor?

  7. 6 maja 2010 at 12:19 | #7

    Ten czarny blok w mojej opinii wziął się z tego że obszar ten był idealnie czarny w obrazku źródłowym (czyste RGB(0,0,0)).

    Jednokolorowego zdjęcia chyba nigdy bym nie otrzymał, z uwagi na te końcowe oscylacje, widać po prostu że o ile przy pierwszych 50k iteracji coś się ładnie i płynnie zmienia to po tym załamaniu już nie.

  8. janek2012
    6 maja 2010 at 21:27 | #8

    Wielokrotne zapisywania zdjęcia w JPG to częsta sprawa, ale co jesli ktoś będzie tak genialny, że zapisze w tym folmacie jakieś logo? A później powtórzy to pół miliona razy? Weźmy np. takie logo Windows 7 (bardzo kolorowe) oraz Java – raptem kilka kolorów. Tutaj powinny dziać się dopiero ciekawe rzeczy :)

  9. stubborn
    9 maja 2010 at 17:40 | #9

    A mozesz podac kod programu ktory wykorzystales do zapisu plikow?

  10. 9 maja 2010 at 17:44 | #10

    Swój własny, napisany w Delphi. Do obsługi JPG użyłem standardowej klasy TJPEGImage.

  11. stubborn
    9 maja 2010 at 18:24 | #11

    A czy moglbys go udostepnic?

  12. 9 maja 2010 at 19:08 | #12

    To jest parę linijek kodu, pisane na poczekaniu:

    procedure TForm2.Button1Click(Sender: TObject);
    var
      i: Integer;
      prefix: String;
      f1, f2: TJPEGImage;
      b: TBitmap;
    begin
    
      prefix := 'lena';
    
      for i := 1 to 100000 do
      begin
        b := TBitmap.Create;
    
        f1 := TJPEGImage.Create;
        f2 := TJPEGImage.Create;
    
        f1.LoadFromFile('output\'+prefix+IntToStr(i-1)+'.jpg');
    
        b.Assign(f1);
    
        f2.CompressionQuality := 95+Random(11);
        f2.Assign(b);
        f2.SaveToFile('output\'+prefix+IntToStr(i)+'.jpg');
    
        f1.Free;
        f2.Free;
    
        b.Free;
    
        Application.ProcessMessages;
      end;
    
    end;
    
  13. stubborn
    9 maja 2010 at 19:13 | #13

    dziekuje bardzo

  14. 13 maja 2010 at 20:13 | #14

    Bardzo ciekawe zjawisko. Dlatego właśnie używam png ;)

Strony komentarza
  1. Brak jeszcze trackbacków