JPEG: The Most Popular Image Compression (You will not regret you had already studied Sinsis)

Hmmm… Sebetulnya gua sadar selama ini gua memakai blog untuk menulis hal-hal yang rada gak berguna. Makanya sekali-kali gua mau coba pake blog untuk menulis sesuatu yang semoga saja berguna buat yang laen. OK, ayo kita start. 😛

JPEG, seringkali kita berurusan dengan format gambar satu ini. Bahkan ketika kamu membuka halaman blog ini pun, sebenarnya kamu sedang menikmati salah satu teknologi optimalisasi yang pernah ada, JPEG. Singkatan dari Joint Photographic Experts Group. Format gambar ini dipakai mulai dari aplikasi kamera digital sampai optimalisasi gambar-gambar yang dikirimkan di internet. Pertanyaan yang pertama muncul biasanya adalah, kenapa JPEG menjadi sangat populer? Jawaban sederhananya adalah karena dengan format JPEG kamu akan mendapatkan file gambar dengan ukuran yang jauh lebih kecil dibandingkan dengan format BITMAP kek BMP.

Sebelum melihat bagaimana JPEG bekerja ada baiknya kita pahami dulu bagaimana BITMAP bekerja. Amati gambar di atas. Gambar di atas memiliki resolusi 370 x 205 pixel. Sehingga untuk menampung gambar tersebut dibutuhkan 75.850 pixel. Lalu bayangkan juga setiap pixel gambar merupakan percampuran dari 3 warna dasar yang sudah kita ketahui sejak kecil, Merah+Ijo+Biru a.k.a. RGB (RedGreenBlue). Loh kenapa harus Merah+Ijo+Biru? Bukannya warna dasar itu Merah+Kuning+Biru? Hmmm… Ternyata komputer memiliki cara berpikir yang laen. Dan klo mau ada yang kuning-kuningnya emang ada sistem warna tersendiri, CMYK, di mana Y-nya berasal dari kata Yellow. Tapi di sini anggap saja kita punya percampuran dari RGB. Terus sekarang karena setiap pixel direpresentasikan sebagai percampuran RGB, berarti kita butuh nilai-nilai yang bisa menampung ketiga jenis warna ini. Anggap saja kita pakai 1 byte untuk menampung 1 jenis warna. Bagi yang gak tahu definisi tentang byte dan penggunaannya bisa refer ke postingan sebelumnya tentang File Format ato baca di wiki. Hehehe… 😛 Berarti untuk satu jenis warna, kita punya variasi sebanyak 2^8 = 256 buah. Klo diterjemahkan ke bahasa komputer nilainya mulai dari 0 sampai 255. Nah, dengan kata laen kita butuh 3 byte untuk menampung definisi satu pixel yang berisi 3 percampuran warna RGB yang memiliki 256^3 = 16.777.216 variasi warna. Sehingga untuk format BITMAP, total untuk menampung gambar di atas tadi, kita butuh 75.850 pixel x 3 byte = 227.550 byte = 227,55 kbyte. Sungguh ukuran yang besar dan tidak efisien, terutama jika kita taruh di internet, dan yang ngakses berada di daerah dengan kecempatan akses internet yang oh Tuhan, aku tidak tega berkata, lemot. Tapi, tahukah kamu berapa ukuran file di atas sesungguhnya? Hanya sekitar 45 kbyte…

Terjadi penghematan 5 kali lipat dari format BITMAP yang semula. Bahkan, kita masih bisa juga menurunkan ukurannya lagi. Itulah JPEG. Sebuah teknologi optimalisasi yang sangat fenomenal. Karena sampai sekarang pun kita masih terus menggunakan teknologi satu ini. Apa kunci kompresi data gambar ini? Kuncinya adalah ketika kita bekerja dengan BITMAP, maka kita bekerja dengan pixel. Sedangkan jika kita bekerja dengan JPEG, kita akan bekerja dengan vektor. Bagi yang gak tahu vektor, bisa baca di tante wiki kita tercinta. 😀 Tapi ya tapi, entah mengapa ketika melihat algoritma JPEG aku sedikit ragu apa bener yang beginian ini vektor, karena kok sedikit lebih ke arah manipulasi matrix. Tapi ya emang iya sih, vektor bisa dituliskan dalam bentuk matrix. Whatever lah…

Selain itu, ada implikasi tersendiri dengan adanya kompensasi berkurangnya ukuran gambar ini. Karena JPEG menggunakan metoda lossy compression, maka ada beberapa komponen-komponen asli yang dihilangkan. Secara teknis kita bisa katakan kita menghilangkan elemen-elemen redundan (tidak perlu, red) penyusun gambar sehingga kita bisa tetap mendapatkan gambar yang sangat mirip dengan gambar originalnya. OK, kalau begitu langsung aja deh sekarang kita akan membahas bagaimana JPEG bekerja.

Pertama, JPEG akan membagi gambar menjadi blok-blok yang besar tiap bloknya 8 x 8 pixel. Contohnya adalah salah satu potongan gambar di atas. Klo dah gini kita dengan mudah bisa pastikan bahwa tidak ada variasi warna yang cukup berarti dalam ukuran seperti ini.

Kedua, format warna RGB pada file gambar pada umumnya memiliki korelasi yang sangat kuat antar komponennya. Maka dari itu dicarilah representasi warna yang korelasi antar komponennya kurang, dengan harapan kita akan mendapatkan sifat-sifat yang sama sekali berbeda antar komponennya, yang tentu saja, berimplikasi mungkin kita bisa mendapatkan sesuatu yang baru yang bisa kita manfaatkan untuk data kompresi ini.

Terus, ada satu lagi, bisa dibilang domain, yang beda dengan domain warna RGB yang kita ketahui, yaitu luminance (Y), kromines biru (Cb), dan kromines merah (Cr). Luminance itu membawa informasi tentang tingkat kecerahan. Sedangkan kromines itu membawa informasi tentang hue. Dan ternyata, dalam eksperiman psychovisual, manusia lebih sensitif terhadap luminance dibanding dengan kromines. Bingo! Sekarang kita benar-benar mendapatkan sifat yang benar-benar berbeda antar 2 komponen ini. Berarti kita bisa lebih sering-sering mengabaikan perbedaan-perbedaan yang ada di krominens. Dan yang lebih menyenangkannya lagi, kita punya 2 krominens.

Jadi, bagaimana sebetulnya merubah RGB ke YCbCr? Kita pake tool color space transform, bukan fourier transform lho. Berikut adalah caranya.

Berhubung determinannya nggak nol, berarti transformasi ini bisa dibalikkan.

Sampai di sini teman-teman kalian tidak akan pernah kecewa pernah belajar salah satu mata kuliah kita yang gak jelas bin abstrak bin aneh bin weirdo, yaitu Sinsis a.k.a. Sinyal dan Sistem. Karena bakal mengingatkan kita pada exp[-j2phi*ft]… Hwawawa… ==’ Seperti yang kita tahu, kita bisa merepresentasikan sinyal dalam 2 domain, waktu dan frekuensi. Yang keduanya adalah domain yang sama sekali berbeda dan, sinyalnya bisa dipastikan memiliki bentuk dan sifat yang sama sekali berbeda. Dan klo di perkuliahan kita biasa pake fourier transform untuk melakukan transformasi sinyal dari domain waktu ke domain frekuensi, begitu juga sebaliknya.

Di sini juga seperti itu. Tahap ketiga yang selanjutnya akan dilakukan adalah merubah setiap blok 8 x 8 pixel yang sudah berisi YCbCr ke domain frekuensi pake Discrete Cosine Transform (DCT) tipe kedua untuk 2 dimensi. Nah loh… Sekali lagi, ini bukan transformasi fourier, tapi sebangsanya. Yang jelas dengan DCT ini kita akan mendapatkan representasi warna dari YCbCr di domain frekuensi. Inilah transformasi yang akan kita pergunakan.

Di mana G(u,v) adalah hasil dari transformasi DCT di koordinat (u,v). Adapun u dan v, mereka sediri adalah koordinat di domain frekuensi dengan nilai mulai dari 0 sampai 7. Terus untuk α(n), dia akan bernilai akar seperdelapan (1/(8)^0,5) untuk n = 0, dan dia akan bernilai setengah untuk yang lainnya. α(n) sendiri adalah fungsi penormalisasi. Lalu g(x,y) adalah nilai salah satu komponen dari Y, Cb, atau Cr di koordinat (x,y).

Akan tetapi, seperti kita tahu, kita mendapatkan nilai YCbCr dari RGB dalam interval nilai positif semuanya. Nilai-nilai ini perlu kita buat lebih kompak terlebih dahulu sebelum di-DCT-kan, dengan cara mengurangi masing-masing nilai YCbCr dengan 128, sehingga kita mendapatkan interval nilai dari -128 sampai 127, bukan 0 sampai 255 lagi.

OK, jadi inilah hasil contoh transformasinya. Anggap saja ini matrix blok luminance.

Matrix pertama adalah matrix yang sudah dibuat lebih kompak bentuknya. Sedangkan matrix kedua adalah matrix hasil transformasi dari DCT. Yang perlu diperhatikan di sini adalah nilai-nilai pada sebelah kiri atas memiliki nilai yang cukup besar dan signifikan. Nilai yang paling ujung kiri sendiri disebut koefisien DC. Sisa yang lainnya namanya koefisien AC.

Keempat, langkah yang perlu dilakukan adalah kuantisasi. Mata manusia memiliki kepekaan yang bagus untuk melihat perbedaan kecil pada tingkat kecerahan di rentang area yang luas dibandingkan harus melihat perbedaan kecerahan di rentang area yang lebih sempit. Dengan kata lain, mata manusia bagus membedakan di frekuensi rendah tapi tidak bagus di frekuensi tinggi. Maka dari itu kita hanya perlu melakukan pengabaian nilai secara signifikan di frekuensi tinggi sekaligus melakukan optimalisasi keseluruhan nilai, terutama frekuensi rendah. Caranya dengan melakukan kuantisasi ke nilai yang lebih rendah. Berikut rumusnya.

A(i,j) adalah nilai awal hasil DCT yang belum terkuantisasi di posisi (i,j). B(i,j) adalah nilai hasil kuantisasi di posisi matrix (i,j). Q(i,j) adalah nilai faktor peng-kuantisasi dari matrix standar dari komite JPEG. Adapun fungsi bracket [ ] adalah fungsi pembulatan ke bilangan bulat terdekat. Adapun nilai β adalah faktor kualitas dari gambar yang dihasilkan. Anggap saja kualitas suatu gambar direpresentasikan oleh q, maka semakin tinggi nilai q maka semakin bagus kualitas gambar tersebut. Nah, nilai ƒβ ditentukan dari rumus berikut.

Standarnya sih keknya enaknya ƒƒβ bernilai 50. Dan inilah matriks standar pen-kuantisasi, Ql untuk luminance dan Qc untuk krominens, dan contoh matriks hasil kuantisasi.

Coba lihat, begitu banyak angka nol di sini. Maka dari itu kita hanya perlu melakukan setuhan akhir.

Terakhir! Adalah entropy coding namanya. Dia ini tipe loseless data compression. Caranya dengan mengurutkan data secara zigzag. Jadinya seperti kek gini, -26 -3 0 -3 -2 -6 2 -4 1 -4 1 1 5 1 2 -1 1 -1 2 0 0 0 0 0 -1 -1 0 0 0 .. .. .. Nah, klo dah gini, saatnya kita ingat-ingat pelajaran matdis kita dulu, karena ini adalah saatnya paman Huffman beraksi~! Dengan metode kompresi pohon Huffman, kita akan dapatkan data yang super duper kompak dan efisien.

Dan dalam keadaan seperti inilah JPEG dibentuk. Makanya wajar aja klo kita akan dapatkan file gambar dengan ukuran yang kecil berkali-kali lipat. Secara klo kita pake Huffman kita bekerja dalam satuan bit bukan byte. Yah, begitulah… JPEG dan dinamikanya… 😛 Apa gua harus bilang memukau? Hwawawa… Lebih tepat dibilang aneh deh nih algoritma keknya.

Oh ya, mungkin ada yang bertanya-tanya gimana caranya nge-decode nih kode ke gambar aslinya. Berarti urutannya tinggal kita balik. Kita susun ulang kode Huffman-nya, terus kita susun ulang kode entropi-nya, terus kita dekuantisasi (yang klo tadi dibagi faktor peng-kuantisasi, sekarang kita kali), trus kita balikan pake transformasi balik kosinus diskrit, abis itu ditambah 128 masing-masing, terakhir tinggal kita kalikan lagi sama inver matriks pen-transform RGB ke YCbCr biar YCbCr-nya bisa balik lagi ke RGB.

Dan inilah fungsi balikan untuk invers DCT tadi.

Dan khusus masalah DCT ini mungkin gua bakal bahas lebih lanjut kapan hari. Khukhukhu… Yasudah, kita sudahi dulu pembahasan kita kali ini. Bai-bai~

Source (AMS-American Mathematical Society, Wiki, Jurnal yang aku lupa catet judulnya, Dosen, dll)

Advertisements