Data Science · Data & Visualisasi
Dari piksel menjadi fitur
Komputer tidak melihat gambar. Ia melihat tabel angka. Presentasi ini menelusuri perjalanan sebuah gambar: bagaimana ia disimpan, direpresentasikan, dibersihkan, lalu diringkas menjadi vektor fitur yang siap dipakai model machine learning.
Bagian 1 · 4 menit
Data gambar
Arahkan kursor atau ketuk gambar untuk memeriksa piksel. Klik untuk mengunci titik.
Gambar digital adalah grid piksel. Setiap piksel menyimpan intensitas cahaya untuk tiga channel warna: merah, hijau, dan biru. Dengan 8 bit per channel, setiap channel punya 256 level (0–255), sehingga satu piksel bisa bernilai salah satu dari 16,7 juta warna.
Turunkan bit depth untuk melihat efek kuantisasi: lebih sedikit level berarti lebih sedikit gradasi warna dan ukuran data lebih kecil.
Format penyimpanan: JPG lossy (kompresi membuang detail), PNG lossless, TIFF/DICOM untuk citra ilmiah dan medis. Di memori, semua dibuka menjadi array angka yang sama.
Kode Python: membaca gambar
import cv2 img = cv2.imread("contoh.jpg") # BGR, uint8 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) print(img.shape, img.dtype) # (240, 320, 3) uint8 print(img[120, 160]) # nilai RGB satu piksel # kuantisasi ke 3 bit per channel bits = 3 step = 256 // (2 ** bits) quant = (img // step) * step
Bagian 2 · 4 menit
Representasi
Histogram intensitas: sumbu x = nilai 0–255, sumbu y = jumlah piksel.
Bentuk yang sama bisa dilihat dari beberapa sudut. Bagi program, gambar RGB adalah tensor 3 dimensi: tinggi × lebar × channel. Grayscale memadatkannya menjadi matriks 2D. Ruang warna HSV memisahkan warna (hue) dari kecerahan, sehingga lebih tahan terhadap perubahan pencahayaan.
Isi matriks di titik terpilih
Klik gambar untuk memindahkan titik. Potongan 6 × 6 piksel.
Rumus grayscale (luminansi ITU-R BT.601): Y = 0.299R + 0.587G + 0.114B. Hijau mendapat bobot terbesar karena mata manusia paling peka terhadapnya.
Kode Python: ruang warna dan histogram
import cv2, numpy as np import matplotlib.pyplot as plt R, G, B = img[..., 0], img[..., 1], img[..., 2] gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) # (240, 320) hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV) # H: 0–179 di OpenCV print(gray[100:106, 150:156]) # potongan matriks 6x6 for i, c in enumerate("rgb"): plt.plot(cv2.calcHist([img], [i], None, [256], [0, 256]), color=c) plt.show()
Bagian 3 · 6 menit
Preprocessing
Data mentah jarang langsung siap dipakai. Preprocessing menyeragamkan ukuran, membersihkan noise, dan memperjelas pola. Urutan langkah di bawah mengikuti urutan pipeline yang umum.
Coba skenario ini: naikkan noise ke 8%, lalu bandingkan filter Gaussian dengan Median. Median jauh lebih efektif untuk noise salt & pepper karena nilai ekstrem tidak ikut dirata-ratakan.
Normalisasi
Model belajar lebih stabil jika nilai berada di skala kecil. Statistik dari gambar hasil di sebelah kiri:
Kode Python: pipeline preprocessing
import cv2, numpy as np small = cv2.resize(img, (160, 120), interpolation=cv2.INTER_AREA) gray = cv2.cvtColor(small, cv2.COLOR_RGB2GRAY) blur = cv2.GaussianBlur(gray, (5, 5), 0) med = cv2.medianBlur(gray, 5) # ampuh untuk salt & pepper eq = cv2.equalizeHist(med) t, biner = cv2.threshold(eq, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) print("ambang Otsu:", t) flip = cv2.flip(small, 1) # augmentasi x01 = small.astype(np.float32) / 255.0 # min-max ke [0,1] z = (small - small.mean()) / small.std() # standardisasi
Bagian 4 · 5 menit
Feature extraction
8 bin per channel × 3 channel = 24 nilai. Dinormalisasi agar totalnya 1 per channel, sehingga tidak bergantung pada ukuran gambar.
Setiap sel menampilkan 9 arah tepi dominan. Garis yang lebih panjang berarti tepi ke arah itu lebih kuat.
Panjang vektor fitur
0
Kode Python: ekstraksi fitur
import cv2, numpy as np from skimage.feature import hog, local_binary_pattern # 1. Tepi gx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3) gy = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3) mag = np.hypot(gx, gy) canny = cv2.Canny(gray, 100, 200) # 2. Histogram warna (8 bin per channel) hist = np.concatenate([np.histogram(img[..., c], 8, (0, 256))[0] for c in range(3)]) hist = hist / hist.reshape(3, 8).sum(1).repeat(8) # 3. HOG fitur_hog, vis = hog(gray, orientations=9, pixels_per_cell=(16, 16), cells_per_block=(2, 2), visualize=True) # 4. Tekstur LBP lbp = local_binary_pattern(gray, P=8, R=1, method="default") fitur_lbp, _ = np.histogram(lbp, bins=256, range=(0, 256), density=True) X = np.concatenate([hist, fitur_hog, fitur_lbp]) # siap untuk model
Penutup · 1 menit
Ringkasan pipeline
- Gambar 320 × 240 RGB berisi 230.400 angka. Fitur seperti histogram warna meringkasnya menjadi 24 angka yang tetap bermakna.
- Preprocessing yang tepat bergantung pada jenis gangguan: median untuk noise impuls, equalization untuk kontras rendah.
- Fitur buatan tangan (handcrafted) seperti HOG dan LBP mudah dijelaskan. CNN mempelajari fiturnya sendiri dari data, tetapi butuh data dan komputasi jauh lebih besar.