ranggaptr's picture
update app
e08fd92
Raw
History Blame Contribute Delete
4.27 kB
import streamlit as st
import joblib
import numpy as np
import cv2
from PIL import Image
import os
from skimage.feature import local_binary_pattern, graycomatrix, graycoprops
# --- KONFIGURASI HALAMAN ---
st.set_page_config(page_title="Weather Classifier", layout="wide")
# --- FUNGSI LOAD MODEL ---
@st.cache_resource
def load_models(algorithm):
try:
# Sesuaikan path ini dengan struktur foldermu
base_path = "model"
if algorithm == 'SVM':
# Pastikan nama file di dalam folder model/svm/ sesuai dengan yang ada
model_path = os.path.join(base_path, "svm/svm_model_optimal_80_20.joblib")
scaler_path = os.path.join(base_path, "svm/scaler_svm.joblib")
le_path = os.path.join(base_path, "svm/label_encoder.joblib")
model = joblib.load(model_path)
scaler = joblib.load(scaler_path)
le = joblib.load(le_path)
elif algorithm == 'XGBoost':
# Pastikan nama file di dalam folder model/xgboost/ sesuai
model_path = os.path.join(base_path, "xgboost/xgb_model_optimal.joblib")
le_path = os.path.join(base_path, "xgboost/label_encoder_xgb.joblib")
model = joblib.load(model_path)
scaler = None
le = joblib.load(le_path)
return model, scaler, le
except Exception as e:
st.error(f"Error loading model files: {e}")
return None, None, None
# --- FUNGSI EKSTRAKSI FITUR (GLCM, LBP, HSV) ---
def extract_features_final(image_pil):
img_np = np.array(image_pil.convert('RGB'))
# Resize (Samakan dengan training, misal 128x128 atau 224x224)
img_np = cv2.resize(img_np, (224, 224))
# Preprocessing
hsv_image = cv2.cvtColor(img_np, cv2.COLOR_RGB2HSV)
h = hsv_image[:, :, 0]
s = hsv_image[:, :, 1]
gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
clahe_builder = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
gray_clahe = clahe_builder.apply(gray)
# Ekstraksi Fitur
hist_h = cv2.calcHist([h], [0], None, [8], [0, 256]).flatten()
hist_s = cv2.calcHist([s], [0], None, [8], [0, 256]).flatten()
lbp = local_binary_pattern(gray_clahe, P=8, R=1, method='uniform')
lbp_hist, _ = np.histogram(lbp.ravel(), bins=np.arange(0, 10), range=(0, 9))
lbp_hist = lbp_hist.astype('float')
lbp_hist /= (lbp_hist.sum() + 1e-6)
glcm = graycomatrix(gray_clahe, distances=[1], angles=[0], symmetric=True, normed=True)
contrast = graycoprops(glcm, 'contrast')[0, 0]
energy = graycoprops(glcm, 'energy')[0, 0]
homogeneity = graycoprops(glcm, 'homogeneity')[0, 0]
features = np.hstack([hist_h, hist_s, lbp_hist, contrast, energy, homogeneity])
return features.reshape(1, -1)
# --- UI UTAMA (WEATHER THEME) ---
st.title("☁️ Weather Classification App 🌦️")
st.write("Klasifikasi Cuaca (Cloudy, Rainy, Shine, Sunrise) menggunakan SVM & XGBoost")
algo_choice = st.sidebar.selectbox("Pilih Algoritma:", ["SVM", "XGBoost"])
uploaded_file = st.file_uploader("Upload foto cuaca...", type=["jpg", "png", "jpeg"])
if uploaded_file is not None:
image = Image.open(uploaded_file)
col1, col2 = st.columns(2)
with col1:
st.image(image, caption='Gambar Diupload', use_column_width=True)
if st.button("Tebak Cuaca"):
with st.spinner("Sedang menganalisis tekstur & warna langit..."):
model, scaler, le = load_models(algo_choice)
if model:
try:
features = extract_features_final(image)
if scaler:
features = scaler.transform(features)
prediction_index = model.predict(features)[0]
# Label otomatis menyesuaikan (Cloudy/Rainy/dll) dari file label_encoder
label = le.inverse_transform([prediction_index])[0]
with col2:
st.success(f"### Prediksi: {label}")
st.info(f"Model: {algo_choice}")
except Exception as e:
st.error(f"Error: {e}")