Showing posts with label Quantization. Show all posts
Showing posts with label Quantization. Show all posts

Friday, June 12, 2015

How JPEG Works (Part-4)

Tahap ke 3 setelah dilakukan transformasi DCT adalah Quantization.

Kenapa perlu di kuantisasi?

Jawaban sederhananya adalah untuk membuang nilai-nilai "pixel" DCT yang rendah (nilai nilai yang mendekati 0).

Bagaimana caranya?

Tekniknya adalah dengan membagi "pixel" DCT dengan Quatization matrix.

Disini lah muncul paramater Quality.

Misalkan kita set parameter Quality bernilai 1 sampai 25. Quality 1 adalah top quality image, gambar tetap tajam seperti aslinya (akan tetapi ukuran file JPEG akan besar) . Quality 25 adalah bad quality image, gambar menjadi buram dan pixelized (akan tetapi ukuran file JPEG akan kecil).

Berikut ini adalah pseudo-code untuk membuat Quantization matrix.

for ( i = 0 ; i < N ; i++ )
 for ( j = 0 ; j < N ; j++ )
  Quantum[ i ][ j ] = 1 + ( ( 1 + i + j ) * quality );


Apabila quality = 2, maka Quntization matrix (Quantum[i][j]) menjadi:
3 5 7 9 11 13 15 17
5 7 9 11 13 15 17 19
7 9 11 13 15 17 19 21
9 11 13 15 17 19 21 23
11 13 15 17 19 21 23 25
13 15 17 19 21 23 25 27
15 17 19 21 23 25 27 29
17 19 21 23 25 27 29 31

Nilai dari Quantization matrix ini nanti menjadi pembagi untuk "pixel" DCT[i,j].

                         DCT(i,j)
Quantized Value(i,j) = -------------- Rounded integer
                        Quantum(i,j)

Kita ulangi dari hasil Part-3 sebagai berikut.


Pixel Asli





140 144 147 140 140 155 179 175
144 152 140 147 140 148 167 179
152 155 136 167 163 162 152 172
168 145 156 160 152 155 136 160
162 148 156 148 140 136 147 162
147 167 140 155 155 140 136 162
136 156 123 167 162 144 140 147
148 155 136 155 152 147 147 136


Pixel Normalisasi



12 16 19 12 12 27 51 47
16 24 12 19 12 20 39 51
24 27 8 39 35 34 24 44
40 17 28 32 24 27 8 32
34 20 28 20 12 8 19 34
19 39 12 27 27 12 8 34
8 28 -5 39 34 16 12 19
20 27 8 27 24 19 19 8


Hasil Transformasi DCT


186 -18 15 -9 23 -9 -14 19
21 -34 26 -9 -11 11 14 7
-10 -24 -2 6 -18 3 -20 -1
-8 -5 14 -15 -8 -3 -3 8
-3 10 8 1 -11 18 18 15
4 -2 -18 8 8 -4 1 -7
9 1 -3 4 -1 -7 -1 -2
0 -8 -2 2 1 4 -6 0

Hasil Transformasi DCT apabila dibagi dengan Quantization Matrix menjadi


DCT After Quantization


62 -4 2 -1 2 -1 -1 1
4 -5 3 -1 -1 1 1 0
-1 -3 0 0 -1 0 -1 0
-1 0 1 -1 0 0 0 0
0 1 1 0 -1 1 1 1
0 0 -1 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

Terlihat bahwa pada frekuensi tinggi sudah banyak sekali "pixel" dengan value 0 yang mana ini sangat mudah untuk dilakukan kompresi.

Apabila Quality kita turunkan menjadi 10 atau 25 misalkan, maka jumlah "pixel" dengan value 0 akan bertambah jauh lebih banyak lagi, ukuran file semakin kecil, tapi gambar semakin buram (makin pixelized).

Berikut contoh Kompresi JPEG dengan berbagai Quality.

Gambar asli


Quality = 1


Quality = 2


Quality = 10


Quality = 25

Pada kondisi dimana gambar cukup mampu di kompresi, maka dengan kompresi sampai tingkat 60% dari ukuran file asli, gambar masih bisa terlihat tajam.

Contoh coding/programming JPEG dalam bahasa C disini


Thursday, June 11, 2015

How JPEG Works (Part-3)

Pada bagian sebelumnya disebutkan inti dari konversi gambar ke format JPEG adalah proses DCT.

Berikut adalah rumus transformasi DCT.


Rumus DCT diatas menampilkan bagaimana gambar di proses dari domain spasial yaitu pixel (x,y) ke domain frekuensi yaitu "pixel" DCT (i,j).

Mungkin agak sulit membayangkan bagaimana rumus itu bekerja. Akan tetapi ilustrasi berikut membantu memudahkan penjelasan bagaimana rumus tsb bekerja.

Sebuah gambar terdiri dari banyak pixel. Gambar tsb di bagi-bagi dalam kotak-kotak kecil yang berisi 8 x 8 pixel. JPEG memang melakukan pengolahan gambar dengan basis 8 x 8 pixel, disebabkan ukuran pixel ini memberikan performa yang bagus bagi CPU komputer dan hasil kompresi yang cukup bagus, serta kecepatan pengolahan kompresi data.

Jika di perhatikan rumus DCT tsb, pada dasarnya cos [(2x+1)ix/2N] cos [(2y+1)jx/2N] dapat di buatkan lookup table (matrix x,y ) sehingga rumus nya menjadi lebih sederhana menjadi:

Cosines[x][j] * Cosines [y][j]

Demikian juga dengan 1/sqrt(2N) C[i] C[j]  dapat dibuatkan lookup table (matrix i,j) menjadi:


Coefficients[i][j]

Dengan demikian pengolahan DCT diatas dalam coding bahasa pemograman sbb:

for ( i = 0 ; i < N ; i++ )
   for ( j = 0 ; j < N ; j++ ) {
      temp = 0.0;
      for ( x = 0 ; x < N ; x++ )
         for ( y = 0 ; y < N ; y++ ) {
            temp += Cosines[ x ][ i ] *
            Cosines[ y ][ j ] * pixel[ x ][ y ];
            }
         temp *= sqrt( 2 * N ) * Coefficients[ i ][ j ];
      DCT[ i ][ j ] = INT_ROUND( temp );
   }

Disebabkan N=8, maka apabila dijalankan prosedur diatas akan terlihat bahwa apabila i=0 dan j=0 atau DCT [0][0] maka Cosines[x][0] = 1, dan Cosines[y][0]=1, artinya DCT[0][0] akan menjadi garis lurus (tidak ada komponen frekuensi). Maka DCT[0][0] sering disebut komponen DC. Sedangkan DCT selain dari DCT[0][0] fungsi cos tidak lagi =1, artinya variabel frekuensi sudah perperan (ingat cos bermain di ranah frekuensi)

Dengan demikian 64 buah pixel mulai dari pixel[0][0] sampai pixel[7][7] ditransformasikan ke DCT[0][0] sampai DCT[7][7], dengan nilai matrix:

DCT[0][0] = value paling besar <-- frekuensi 0 (komponen DC)
DCT[0][1] = value makin besar <-- frekuensi <> 0 (komponen AC)
. . .
DCT[i][j]
. . .
DCT[7][7] = value paling kecil (menjadi 0, apabila dibagi nilai Qunatisizer)

Nantinya DCT yang sudah di ujung-ujung karena nilainya setelah di bagi dengan Quantisizer value akan menjadi 0 maka sesuai dengan teknik kompresi, nilai 0 yang banyak dapat di kompress dengan sangat mudah.

Sebagi ilustrasi berikut adalah hasil pengolahan pixel (x,y) menjadi DCT(i,j).


Pixel perlu di normalisasi dari rentang 0 - 255 menjadi rentang -128 sd 127. Sehingga pixel (0,0) value 140 menjadi 140 - 128 = 12, dst.

Pixel normalisasi tsb di transformasi kan jadi "pixel" DCT.


Terlihat bahwa DCT(0,0) atau dalam matrix DCT[0][0] value nya adalah 186. Sedangkan DCT(7,7) valuenya 0. Terlihat semakin tinggi frekuensi (semakin mendekati posisi DCT(7,7)) maka semakin rendah nilai pixel DCT nya. Ide nya adalah nilai-nilai yang rendah (mendekati 0) bisa di buang, sehingga proses kompresi file gambar bisa terjadi.

Digambar terlihat bahwa komponen DC (Direct Current  atau komponen dengan frekuensi 0) dari DCT tsb yaitu DCT(0,0) value nya adalah 186.

Pada dasarnya sebuah potongan gambar dengan pixel 8 x 8 (64 buah pixel) dapat di wakilkan dengan beberapa pixel DCT saja, bahkan apabila kompresi sangat ditekan bisa dengan mengambil komponen DC nya saja. Artinya dari domain spasial 64 pixel diubah menjadi 1 pixel saja di domain frekuensi (yaitu komponen DC saja - dalam gambar 186).

Bagian 4 akan menjelaskan tentang Quantisizer.

How JPEG Works (Part-2)

Pada bagian ke dua ini akan di bahas proses transformasi DCT (Discrete Cosine Transform).

Sebelum berlanjut, perlu di ingat kembali pada bagian sebelumnya, 1 lembar gambar berwarna dapat dibayangkan terdiri dari 3 lembar gambar: 1 gambar Red (dan gradasi Red), 1 gambar Green (dan gradasi Green), dan 1 gambar Blue (dan gradasi Blue).

3 lembar gambar ini, di konversi menjadi 3 lembar gambar baru yaitu: 1 lembar gambar Y, 1 lembar gambar Cb, 1 lembar gambar Cr. Ukuran kertas gambar Cb dan Cr separoh dari ukuran kertas gambar Y.

Selanjutnya masing-masing gambar: Y, Cb, dan Cr dilakukan transformasi DCT kepadanya.

Kenapa perlu DCT? Apa urgensi atau manfaat dilakukan DCT ini?

Pada dasarnya DCT ini mentransformasikan nilai pixel-pixel gambar dari domain spasial ke domain frekuensi. Agak sulit memang membayangkan kalimat ini "mengkonversi dari domain spasial ke domain frekuensi".

Untuk membayangkan diberikan ilustrasi sbb:

Misal ukuran gambar adalah 8x8 pixel (8 horizontal, 8 vertikal), artinya ada 64 buah pixel.

Karena 1 pixel Y mewakili 8 bit artinya nilai pixel Y berkisar antara 0 sampai 255:
0 = hitam
127= abu-abu
255=putih

Apabila 64 pixel tsb di urutkan dari urutan pixel 1 sampai pixel 64
p1, p2, p3, p4, ...., p64

dan ambil contoh nilai pixelnya sbb:
7, 20, 100, 56, 84, 230, 125, 4 ..., 39

Urutan tsb kita namakan domain spasial (domain ruang).

Apabila kita punya persamaan cosinus sbb:

c1, c2, c3, c4, ..., c64

dengan
c1 =  p1 cos(z) + p2 coz (2z) + p3 cos (3z) + ... p64 cos (64z) dengan z=0

c2 =  p1 cos(z) + p2 coz (2z) + p3 cos (3z) + ... p64 cos (64z) dengan z=1
...
c64 =  p1 cos(z) + p2 coz (2z) + p3 cos (3z) + ... p64 cos (64z) dengan z=63

Nah akan didapat nilai baru c1, c2, c3 sd c64. Nilai baru ini disebut domain frekuensi. 

Jadi transformasi DCT ini sederhananya merubah:
 p1, p2, p3, p4, ...., p64

menjadi
c1, c2, c3, c4, ..., c64


Apa urgensi nya megubah dari domain spasial ke domain frekuensi?

Urgensinya begini:

Apabila kita lakukan transformasi DCT, maka nilai - nilai awal akan besar, sedangkan nilai-nilai akhir akan bernilai kecil ( apabila di bagi dengan Qunatization akan mendekati 0).

Nilai-nilai awal (frekuensi cosinus rendah) c1, c2, c3, ..., c12  bernilai besar
Nilai-nilai akhir (frekuensi cosinus tinggi) c13, c14, c15, ..., c64 bernilai kecil (mendekati 0)

Artinya apa?

Artinya dengan banyaknya nilai c yang bernilai 0, maka data dapat di kompress lagi. Itulah penyebab gambar JPEG ukuran filenya bisa menjadi sangat kecil. Sehingga dalam file bisa di ringkas penulisannya (hanya untuk ilustrasi) misal: c1:5,c2:6,c3-c64:0 (asumsi dari c3 sd c64 nilai perhitungan cosinusnya sudah sama dengan 0). Ini sudah menghemat sekian byte penulisan file.

Pada bagian 3 kita akan pelajari algoritma DCT ini dalam bahasa programming agar semakin jelas.