Pada percobaan ini kita akan mencoba melakukan klasifikasi pada dua label citra, yaitu siang dan malam. Percobaan ini akan memberikan pengalaman bagi Anda untuk melakukan proses pra pengolahan data, ekstraksi fitur, dan melakukan klasifikasi dengan menggunakan classifier sederhana dan SVM.
Unduh dataset berikut,
Langkah 0 - Import Library
# Import Required Librariesfrom pathlib import Pathimport matplotlib.image as mpimgimport matplotlib.pyplot as pltimport cv2import randomimport numpy as npimport pandas as pd
Lakukan ekstraksi data gambar, kemudian definisikan lokasi gambar. Pada contoh ini, folder gambar berlokasi sama dengan lokasi file python
WARNING! Perhatikan ukuran (shape) dari data image. Atribut shape akan menampilkan dalam konteks baris (height) x kolom (width)
Lakukan inspeksi visual dengan fungsi random_img_viz yang telah dibuat sebelumnya pada gambar hasil pra pengolahan.
random_img_viz(train_std_img_list)
Hasilnya akan seperti gambar berikut,
Langkah 4 - Ekstraksi Fitur
Selanjutnya, untuk dapat membadakan antara label satu dengan label yang lain, kita memerlukan sebuah fitur. Fitur adalah penciri dari sebuah data yang dapat digunakan untuk membendakan data satu dengan yang lain. Pada percobaan kali ini, kita akan menggunakan fitur yang sederhana yaitu nilai rata-rata dari tingkat kecerahan gambar (average brightness). Namun sebelum dapat melakukan hal tersebut, kita akan mengubah ruang warna (colorspace) dari RGB menjadi HSV (Hue, Saturation, Value). Hal ini dikarenakan, tingkat kecerahan (brightness) lebih mudah didapatkan dari HSV berdasarkan nilai Valuenya.
Buatlah fungsi berikut untuk mendapatkan nilai rata-rata tingkat kecerahan
# Get feature based on average brightness using HSV colorspacedefavg_brightness(image):# Convert image to HSV img_hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)# Calculate the avg of brightness sum_brightness = np.sum(img_hsv[:,:,2])# take the 3rb value which is the V channel area = image.shape[0]* image.shape[1] avg = sum_brightness / areareturn avg
Lakukan pengecekan pada gambar secara acak. INGAT! Gunakan gambar yang telah melalui proses pra pengolahan data!
# Check on random imagerand_img = np.random.randint(0, len(train_std_img_list))feature_img = train_std_img_list[rand_img][0]avg_img =avg_brightness(feature_img)print(f'Image {rand_img}')print(f'Avg Brighness: {avg_img:.4f}')plt.imshow(feature_img)
Akan didapatkan hasil output seperti pada gambar
Langkah 5 - Klasifikasi dengan Metode Threshold
Pada tahap ini, kita akan melakukan proses klasifikasi sederhana dengan menggunakan nilai ambang batas (threshold) dari nilai rata-rata kecerahan yang kita tentukan sendiri.
Buatlah fungsi berikut,
defpredict_label(img,threshold):# Computer average brightness avg =avg_brightness(img) pred =0# Predict the label based on user defined thresholdif avg > threshold: pred =1return pred
Lakukan pengecekan prediksi secara acak pada data training
# Test the classifier on train datarand_img = np.random.randint(0, len(train_std_img_list))pred =predict_label(train_std_img_list[rand_img][0], threshold=120)# Evaluateprint(f'Image {rand_img}')print(f'Actual label: {train_std_img_list[rand_img][1]}')print(f'Predicted label: {pred}')plt.imshow(train_std_img_list[rand_img][0])
Hasilnya akan seperti pada gambar
Langkah 6 - Evaluasi (Manual)
Selanjutnya kita akan membuat fungsi evaluasi model sederhana, yaitu dengan membandingkan label yang diprediksi benar dengan seluruh data. Ingat kembali konsep confussion matrix.
Buatlah fungsi berikut,
defevaluate(img_list,threshold): miss_labels = []for file in img_list:# Get the ground truth / correct label img = file[0] label = file[1]# Get prediction pred_label =predict_label(img, threshold)# Compare ground truth and predif pred_label != label: miss_labels.append((img, pred_label, label)) total_img =len(img_list) corr_pred = total_img -len(miss_labels) accuracy = corr_pred / total_imgprint(f'Accuracy: {accuracy:.4f}')
Lakukan evaluasi pada data training dengan nilai ambang batas 120
# Evaluate on train dataevaluate(train_std_img_list, threshold=120)
Hasilnya adalah,
Accuracy: 0.8417
Anda dapat mengubah nilai ambang batas dan amati hasilnya.
Selanjutnya, kita akan melakukan evaluasi pada data testing. Namun sebelumnya, data testing harus diperlakukan sama dengan data training dalam konteks pra progolahan data dan ekstraksi fitur.
# Evaluate on test data# Load test datatest_img =load_dataset(test_dir)# Preprocesstest_std_img_list =preprocess(test_img)# Predictevaluate(test_std_img_list, threshold=120)
Hasil akurasi dari data testing adalah,
Accuracy: 0.8688
Another Way - Membuat Feature Vectors dan Klasifikasi dengan SVM
Pada proses klasifikasi sebelumnya, kita hanya membedakan kelas day dan night dengan nilai ambang batas. Cara tersebut memang mudah untuk digunakan, akan tetapi belum tentu secara baik dan general dapat memedakan kedua data. Oleh karena itu, pada bagian ini, kita akan mencoba menggunakan pendekatan lain untuk melakukan proses klasifikasi. Kita akan kembali mulai pada langkah 4
Langkah 4 alternatif - Membuat Feature Vectors
Perbedaan mendasar dari langkah 4 sebelumnya adalah, kita akan melakukan tabulasi semua nilai rata-rata kecerahan pada data, dan menyimpannya dalam bentuk tabel. Dalam konteks ini, kita akan membuat tabel dengan kolom fitur dan label.
Buatlah fungsi berikut,
# Create function to extract feature for every images and stored in tabular data# Stored in Pandas dataframedefextract_avg_bright_feature(img_list): avg_list = [] labels = []for img in img_list: img_avg =avg_brightness(img[0])# Get the avg brightness from image img_label = img[1]# Get the image label avg_list.append(img_avg) labels.append(img_label)# Stack data in columcular way data = np.column_stack((avg_list, labels))# Create a Pandas dataframe df = pd.DataFrame(data, columns=['AVG_BRIGHT', 'LABELS'])return df
Cek hasilnya pada data training,
# Extract feature on train datatrain_avg_img =extract_avg_bright_feature(train_std_img_list)print(f'Shape: {train_avg_img.shape}')train_avg_img.head()
Maka akan tampil output seperti pada gambar
Lakukan langkah yang serupa pada data testing
# Do the same thing on test datatest_avg_img =extract_avg_bright_feature(test_std_img_list)print(f'Shape: {test_avg_img.shape}')test_avg_img.head()
Hasilnya adalah seperti pada gambar
Langkah 5 alternatif
Selanjutnya, kita akan membuat model SVM dengan kernel RBF (default) dengan memanfaatkan libary scikit-learn.
Selanjutnya, kita akan melakukan evaluasi pada data training dan testing dengan bantuan library scikit-learn.
from sklearn.metrics import accuracy_score# Make a prediction on train datay_train_pred = model.predict(X_train)# Get the accuracy on train dataacc_train =accuracy_score(y_train, y_train_pred)# Make a prediction on test datay_test_pred = model.predict(X_test)# Get the accuracy on test dataacc_test =accuracy_score(y_test, y_test_pred)# Print Eval Resultprint(f'Accuracy on train: {acc_train}')print(f'Accuracy on test: {acc_test}')
Hasil akurasi dengan model SVM adalah,
Accuracy on train: 0.8583333333333333
Accuracy on test: 0.9