abrarwahid's picture
Initial clean version for pipeline
78aefa8
Raw
History Blame Contribute Delete
2.33 kB
"""Bags of Visual Words: pembentukan codebook (MiniBatchKMeans) & histogram fitur."""
import numpy as np
from sklearn.cluster import MiniBatchKMeans
import config
def sample_descriptors_for_codebook(all_descriptors_list, max_total, random_state):
"""
Menggabungkan descriptor dari seluruh citra lalu men-subsample hingga
maksimum `max_total` baris agar pelatihan codebook tetap efisien memori
untuk dataset beribu-ribu citra.
"""
stacked = np.vstack(
[d for d in all_descriptors_list if d is not None and len(d) > 0]
)
if len(stacked) <= max_total:
return stacked
rng = np.random.RandomState(random_state)
idx = rng.choice(len(stacked), size=max_total, replace=False)
return stacked[idx]
def build_codebook(descriptor_sample, k, random_state=None, batch_size=None):
"""Melatih MiniBatchKMeans sebagai kamus visual (codebook) berukuran k."""
random_state = config.RANDOM_STATE if random_state is None else random_state
batch_size = (
config.MINIBATCH_KMEANS_BATCH_SIZE if batch_size is None else batch_size
)
kmeans = MiniBatchKMeans(
n_clusters=k,
random_state=random_state,
batch_size=min(batch_size, len(descriptor_sample)),
n_init=10,
max_iter=200,
)
kmeans.fit(descriptor_sample)
return kmeans
def compute_histogram(descriptors, codebook, normalize="hellinger"):
"""
Kuantisasi descriptor ke histogram BoVW dengan transformasi Root-BoVW (Hellinger).
"""
k = codebook.n_clusters
if descriptors is None or len(descriptors) == 0:
return np.zeros(k, dtype=np.float32)
word_indices = codebook.predict(descriptors)
histogram, _ = np.histogram(word_indices, bins=np.arange(k + 1))
histogram = histogram.astype(np.float32)
if normalize == "l2":
norm = np.linalg.norm(histogram)
if norm > 0:
histogram = histogram / norm
elif normalize == "l1":
total = histogram.sum()
if total > 0:
histogram = histogram / total
elif normalize == "hellinger":
# Transformasi Root-BoVW (Sangat superior untuk deteksi tekstur)
total = histogram.sum()
if total > 0:
histogram = histogram / total
histogram = np.sqrt(histogram)
return histogram