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 |
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.
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 di Github
Update 23/Sep/2026
Rahasia Kompresi JPEG: Mengupas Logika Matriks Kuantisasi dalam Python
Logika di mana matriks DCT dibagi dengan matriks Kuantisasi (Quantization matrix) dan dibulatkan menjadi bilangan bulat adalah hal utama yang membuat ukuran file JPEG bisa menjadi sangat kecil. Seperti yang sering dijelaskan dalam berbagai artikel pengantar kompresi gambar, proses pembagian ini "memaksa" detail berfrekuensi tinggi berubah menjadi angka 0. Hal inilah yang pada akhirnya membuat data tersebut menjadi sangat mudah untuk dikompresi.
Mari kita lihat bagaimana logika persis tersebut diimplementasikan dalam dunia nyata, mengambil contoh dari repositori GitHub fangwei123456/python-jpeg-encoder (tepatnya di dalam file jpegEncoder.py), dan membandingkannya dengan teori dasar:
1. Membuat Matriks Kuantisasi (Generating the Quantization Matrix)
Daripada menggunakan rumus perulangan sederhana seperti 1 + ((1 + i + j) * quality) yang sering diajarkan di kelas, fangwei123456/python-jpeg-encoder menggunakan matriks standar resmi ISO yang dirancang langsung oleh komite JPEG.
Dalam kode repositori tersebut, Anda akan menemukan tabel dasar ini ditulis secara langsung (hardcoded) di bagian atas skrip:
# Ini adalah Tabel Kuantisasi Luminance Standar resmi
# yang digunakan dalam repositori
std_luminance_quant_tbl = np.array([
[16, 11, 10, 16, 24, 40, 51, 61],
[12, 12, 14, 19, 26, 58, 60, 55],
[14, 13, 16, 24, 40, 57, 69, 56],
[14, 17, 22, 29, 51, 87, 80, 62],
[18, 22, 37, 56, 68, 109, 103, 77],
[24, 35, 55, 64, 81, 104, 113, 92],
[49, 64, 78, 87, 103, 121, 120, 101],
[72, 92, 95, 98, 112, 100, 103, 99]
])
Kemudian, repositori ini menyesuaikan tabel standar di atas berdasarkan parameter quality (kualitas) yang Anda masukkan. Jika quality = 50, program menggunakan tabel persis seperti di atas. Namun, jika quality diturunkan (misalnya menjadi 10 atau 25), tabel ini akan dikalikan dengan faktor skala untuk memperbesar angka-angkanya. Efeknya? Semakin besar pembaginya, semakin banyak angka 0 yang dihasilkan (dan gambar akan menjadi semakin buram atau pixelated).
2. Langkah Pembagian (DCT / Quantum)
Dalam penjelasan pseudocode teoritis, pembagian ini biasanya ditulis menggunakan perulangan bersarang (nested loop):
Quantized Value(i,j) = Round( DCT(i,j) / Quantum(i,j) )
Namun, pada fangwei123456/python-jpeg-encoder, operasi matematika ini tidak dilakukan menggunakan for i... for j.... Karena Python menangani kalkulasi matematika jauh lebih cepat menggunakan array, operasi ini dilakukan menggunakan fitur matriks dari pustaka NumPy. Kodenya terlihat sangat elegan dan singkat:
# 'yDctMatrix' adalah blok 8x8 dari nilai DCT
# 'luminanceQuantTbl' adalah matriks kuantisasi yang sudah diskalakan
# Satu baris kode ini membagi setiap piksel [i,j] dan membulatkannya,
# melakukan fungsi yang persis sama seperti pseudocode di atas!
yQuantMatrix = np.round(yDctMatrix / luminanceQuantTbl)
3. Melihat Ledakan Angka "Nol" (Output)
Jika Anda menjalankan fangwei123456/python-jpeg-encoder dalam mode debug (dengan menambahkan argumen 1 di akhir perintah saat menjalankannya), program akan mencetak langkah demi langkah ke layar.
Berikut adalah cuplikan asli dari output repositori tersebut saat memproses (encode) sebuah blok piksel 8x8:
yDctMatrix (Nilai DCT sebelum kuantisasi):
[[1024. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0.]
... ]
yQuantMatrix (Setelah dibagi dengan matriks Kuantisasi):
[[ 512. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0.]
... ]
(Perhatikan bagaimana hampir seluruh elemen blok tersebut berubah menjadi angka nol, mengonfirmasi teori bahwa pembagian inilah kunci utama di balik penghematan ukuran ruang penyimpanan dalam format JPEG!)





No comments:
Post a Comment