Kompresi Gambar Sederhana

Kompresi Gambar Sederhana

https://www.ridwanreza.com/2021/09/kompresi-gambar-sederhana.html

Diberikan sebuah gambar, kita ingin melakukan kompresi pada gambar tersebut.

Pada dasarnya, sebuah gambar 2 dimensi merupakan blok/matriks yang memiliki warna pada setiap titik/elemennya.

Misalkan matriks tersebut bernama A, sebagai berikut

$$A=\begin{bmatrix}a_{1,1}&a_{1,2}&a_{1,3}&a_{1,4}&\cdots&a_{1,n-1}&a_{1,n} \\a_{2,1}&a_{2,2}&a_{2,3}&a_{2,4}&\cdots&a_{2,n-1}&a_{2,n} \\\vdots&\vdots&\vdots&\vdots&\ddots&\vdots&\vdots \\a_{m-1,1}&a_{m-1,2}&a_{m-1,3}&a_{m-1,4}&\cdots&a_{m-1,n-1}&a_{m-1,n} \\a_{m,1}&a_{m,2}&a_{m,3}&a_{m,4}&\cdots&a_{m,n-1}&a_{m,n}\end{bmatrix}$$

elemen matriks $a_{i,j}$ bisa berupa vektor warna 3 elemen RGB, atau 4 elemen CMYK.

Ide paling sederhana untuk melakukan kompresi adalah dengan mengecilkan ukuran matriks tersebut. Misalkan kita buat matriks B, dengan elemen-elemen matriks B adalah rata-rata dari submatriks berukuran 2 kali 2 dari matriks A. $$B=\begin{bmatrix}avg\left(\begin{bmatrix}a_{1,1}&a_{1,2}\\a_{2,1}&a_{2,2}\end{bmatrix}\right)&avg\left(\begin{bmatrix}a_{1,3}&a_{1,4}\\a_{2,3}&a_{2,4}\end{bmatrix}\right)&\cdots&avg\left(\begin{bmatrix}a_{1,n-1}&a_{1,n}\\a_{2,n-1}&a_{2,n}\end{bmatrix}\right) \\\vdots&\vdots&\ddots&\vdots& \\avg\left(\begin{bmatrix}a_{m-1,1}&a_{m-1,2}\\a_{m,1}&a_{m,2}\end{bmatrix}\right)&avg\left(\begin{bmatrix}a_{m-1,3}&a_{m-1,4}\\a_{m,3}&a_{m,4}\end{bmatrix}\right)&\cdots&avg\left(\begin{bmatrix}a_{m-1,n-1}&a_{m-1,n}\\a_{m,n-1}&a_{m,n}\end{bmatrix}\right) \end{bmatrix}$$

Pengambilan rata-rata memiliki makna "mengambil rata-rata warna" pada setiap 4 titik/elemen matriks.

Bisa juga dengan menggunakan maksimum, miimum atau silahkan Anda eksperimen dengan formula Anda sendiri :)

Berikut ini saya tampilkan contoh program menggunakan python, jupyter notebook

In [1]:
#Library yang digunakan
import numpy as np
import math

#memasang library Pillow
!pip install Pillow 
import PIL.Image #menggunakan library PIL
Requirement already satisfied: Pillow in c:\users\admin\appdata\local\programs\python\python39\lib\site-packages (8.3.2)

Pada program ini, Library PIL hanya akan digunakan untuk konversi gambar menjadi bentuk numerik matriks, dan mengubah matriks menjadi gambar.

Untuk kompresinya, akan kita lakukan secara manual :)

In [2]:
#Ambil data gambar, pastikan file python/ipynb satu folder dengan gambar yang ingin dikompresi
gambar = PIL.Image.open(r"gambar.png")
#Konversi gambar menjadi bentuk matriks numerik
A = np.array(gambar) #bentuk matriks numerik dari gambar
In [20]:
print("Dimensi Matriks AR =",A.shape)
print("Banyak Baris AR =",A.shape[0])
print("Banyak Kolom AR =",A.shape[1])
print("Komponen Warna untuk 1 titik/pixel AR =",A.shape[2])
print(A)
Dimensi Matriks AR = (742, 1320, 4)
Banyak Baris AR = 742
Banyak Kolom AR = 1320
Komponen Warna untuk 1 titik/pixel AR = 4
[[[223 237 207 255]
  [233 248 216 255]
  [232 246 215 255]
  ...
  [245 250 225 255]
  [245 250 225 255]
  [245 250 225 255]]

 [[223 237 207 255]
  [233 248 216 255]
  [232 246 215 255]
  ...
  [245 250 225 255]
  [245 250 225 255]
  [245 250 225 255]]

 [[223 237 207 255]
  [233 248 216 255]
  [232 246 215 255]
  ...
  [245 250 225 255]
  [245 250 225 255]
  [245 250 225 255]]

 ...

 [[225 219 204 255]
  [234 229 213 255]
  [232 227 211 255]
  ...
  [223 226 203 255]
  [224 227 204 255]
  [225 227 205 255]]

 [[231 226 211 255]
  [241 236 220 255]
  [239 234 218 255]
  ...
  [227 229 207 255]
  [228 230 208 255]
  [228 230 208 255]]

 [[242 237 222 255]
  [253 248 231 255]
  [251 246 230 255]
  ...
  [235 237 215 255]
  [235 238 215 255]
  [236 238 216 255]]]

Pada matriks A, setiap titik/pixel memiliki 4 komponen warna.

Untuk masing-masing komponen, diolah dengan menghitung rata-ratanya untuk setiap submatriks 2 kali 2.

In [3]:
baris=int(A.shape[0]/2)
kolom=int(A.shape[1]/2)

#Buat matriks B, dengan ukuran baris,kolom
#elemen warna dari b_i,j sementara diisi dengan 0 (nol)
B=np.array([[[0 for k in range(A.shape[2])] for j in range(kolom)] for i in range(baris)])

for i in range(baris):
    for j in range(kolom):
        for k in range(4):
            B[i][j][k]=math.floor((A[2*i][2*j][k]/4 + A[2*i][2*j+1][k]/4 +
                                   A[2*i+1][2*j][k]/4 + A[2*i+1][2*j+1][k]/4))
In [4]:
#Matriks B, kita konversikan kembali menjadi sebuah gambar
B=np.uint8(B)
pil_image=PIL.Image.fromarray(B)
pil_image.save("gambar_ratarata.png")
In [5]:
#Coba simpan dalam format BMP
pil_image=PIL.Image.fromarray(A)
pil_image.save("gambar_asli.bmp")

pil_image=PIL.Image.fromarray(B)
pil_image.save("gambar_ratarata.bmp")

Buka folder tempat kita bekerja, lihatlah file hasil kompresi kita image.png Matriks B berukuran seperempat dari matriks A, perkiraannya, hasil kompresi akan menghasilkan ukuran file seperempat kalinya.

Perhatikan file dengan format .bmp, ukuran file kompresi persis seperempat kalinya dari ukuran file asli.

Kita sudah bisa melakukan kompresi gambar dengan melakukan operasi matriks.

Silahkan Anda coba untuk melakukan operasi gambar lainnya dengan cara mengolah matriks dan elemen warna yang dimiliki :)

Catatan :Penting diketahui

Tipe data yang digunakan pada elemen warna memiliki karakteristik khusus. Elemen warna pada masing-masing elemen bernilai diantara 0 sampai 255.

Ketika menghitung rata-rata, untuk setiap $i,j$, gunakan $$\frac{A[2*i][2*j][0]}{4}+\frac{A[2*i+1][2*j][1]}{4}+\frac{A[2*i][2*j+1][2]}{4}+\frac{A[2*i+1][2*j+1][3]}{4}$$ jangan gunakan $$\frac{A[2*i][2*j][0]+A[2*i+1][2*j][1]+A[2*i][2*j+1][2]+A[2*i+1][2*j+1][3]}{4}$$

Pada elemen warna, apabila sebuah angka dijumlahkan melebihi 255, maka hasil penjumlahannya akan dikurangi dengan 256.

Contoh : 45+60=105, 200+100=44

In [6]:
print("Elemen warna A[0][0][0]=",A[0][0][0])
print("Elemen warna A[0][1][0]=",A[0][1][0])
print("A[0][0][0]+A[0][1][0]=",A[0][0][0]+A[0][1][0])
Elemen warna A[0][0][0]= 223
Elemen warna A[0][1][0]= 233
A[0][0][0]+A[0][1][0]= 200
C:\Users\Admin\AppData\Local\Temp/ipykernel_15972/122976558.py:3: RuntimeWarning: overflow encountered in ubyte_scalars
  print("A[0][0][0]+A[0][1][0]=",A[0][0][0]+A[0][1][0])

Diskusi, saran dan masukkan silahkan hubungi Ridwan :)

Comments

  1. Las Vegas Casino & Hotel - Mapyro
    The 사천 출장샵 casino features a restaurant, casino, and nightclub, including a poker room, 이천 출장마사지 a restaurant and a 속초 출장샵 coffee shop. 포항 출장안마 Guests can 대구광역 출장샵 even set a date in  Rating: 3.4 · ‎29 reviews

    ReplyDelete

Post a Comment

Popular posts from this blog

Fungsi Rekursif

Aljabar Python

Pengolahan Matriks (manual)

Contoh Fungsi : Standar Deviasi