221 lines
7.8 KiB
Python
221 lines
7.8 KiB
Python
import cv2
|
|
import numpy as np
|
|
import joblib
|
|
import os
|
|
|
|
def extract_color_histogram(image, bins=(8, 8, 8)):
|
|
"""
|
|
Ekstraksi fitur Color Histogram RGB dari gambar
|
|
"""
|
|
# Konversi dari BGR ke RGB
|
|
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
|
|
|
# Hitung histogram untuk setiap channel
|
|
hist_r = cv2.calcHist([image_rgb], [0], None, [bins[0]], [0, 256])
|
|
hist_g = cv2.calcHist([image_rgb], [1], None, [bins[1]], [0, 256])
|
|
hist_b = cv2.calcHist([image_rgb], [2], None, [bins[2]], [0, 256])
|
|
|
|
# Normalisasi histogram
|
|
hist_r = cv2.normalize(hist_r, hist_r).flatten()
|
|
hist_g = cv2.normalize(hist_g, hist_g).flatten()
|
|
hist_b = cv2.normalize(hist_b, hist_b).flatten()
|
|
|
|
# Gabungkan semua histogram
|
|
features = np.concatenate([hist_r, hist_g, hist_b])
|
|
|
|
return features
|
|
|
|
def load_model_and_predict():
|
|
"""
|
|
Memuat model yang sudah disimpan dan melakukan prediksi
|
|
"""
|
|
print("=" * 60)
|
|
print("PREDIKSI KEMATANGAN TOMAT")
|
|
print("Menggunakan Model yang Sudah Disimpan")
|
|
print("=" * 60)
|
|
|
|
# Path ke model
|
|
models_folder = "models"
|
|
model_file = os.path.join(models_folder, "tomat_classifier.pkl")
|
|
encoder_file = os.path.join(models_folder, "label_encoder.pkl")
|
|
metadata_file = os.path.join(models_folder, "metadata.pkl")
|
|
|
|
# Cek apakah file model ada
|
|
if not os.path.exists(model_file):
|
|
print(f"Error: File model tidak ditemukan: {model_file}")
|
|
print("Jalankan main.py terlebih dahulu untuk training dan menyimpan model")
|
|
return
|
|
|
|
try:
|
|
# Muat model
|
|
print("\n1. MEMUAT MODEL")
|
|
print("-" * 40)
|
|
model = joblib.load(model_file)
|
|
label_encoder = joblib.load(encoder_file)
|
|
metadata = joblib.load(metadata_file)
|
|
|
|
print(f"Model berhasil dimuat: {model_file}")
|
|
print(f"Tipe Model: {metadata['model_type']}")
|
|
print(f"Jumlah Estimators: {metadata['n_estimators']}")
|
|
print(f"Jumlah Fitur: {metadata['n_features']}")
|
|
print(f"Kelas: {metadata['classes']}")
|
|
print(f"Akurasi Training: {metadata['accuracy']:.4f}")
|
|
|
|
# Muat metadata
|
|
print(f"\nMetadata berhasil dimuat: {metadata_file}")
|
|
|
|
# Prediksi dengan gambar baru
|
|
print("\n2. PREDIKSI GAMBAR BARU")
|
|
print("-" * 40)
|
|
|
|
# Contoh: prediksi semua gambar dalam folder
|
|
dataset_path = "."
|
|
classes = [d for d in os.listdir(dataset_path)
|
|
if os.path.isdir(os.path.join(dataset_path, d))]
|
|
|
|
print("Melakukan prediksi pada contoh gambar...")
|
|
|
|
for class_name in classes:
|
|
class_path = os.path.join(dataset_path, class_name)
|
|
image_files = [f for f in os.listdir(class_path)
|
|
if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
|
|
|
|
if image_files:
|
|
# Ambil gambar pertama sebagai contoh
|
|
sample_image = image_files[0]
|
|
image_path = os.path.join(class_path, sample_image)
|
|
|
|
try:
|
|
# Baca dan proses gambar
|
|
image = cv2.imread(image_path)
|
|
if image is not None:
|
|
# Ekstraksi fitur
|
|
features = extract_color_histogram(image)
|
|
features = features.reshape(1, -1) # Reshape untuk single prediction
|
|
|
|
# Prediksi
|
|
prediction = model.predict(features)[0]
|
|
prediction_proba = model.predict_proba(features)[0]
|
|
|
|
# Konversi ke label kelas
|
|
predicted_class = label_encoder.inverse_transform([prediction])[0]
|
|
|
|
# Tampilkan hasil
|
|
print(f"\nGambar: {sample_image}")
|
|
print(f"Kelas Aktual: {class_name}")
|
|
print(f"Prediksi: {predicted_class}")
|
|
print(f"Probabilitas:")
|
|
for i, class_name in enumerate(label_encoder.classes_):
|
|
print(f" {class_name}: {prediction_proba[i]:.4f} ({prediction_proba[i]*100:.2f}%)")
|
|
|
|
# Benar/Salah
|
|
is_correct = (class_name == predicted_class)
|
|
print(f"Status: {'BENAR' if is_correct else 'SALAH'}")
|
|
|
|
except Exception as e:
|
|
print(f"Error memproses {image_path}: {e}")
|
|
|
|
# Interactive prediction
|
|
print("\n3. PREDIKSI INTERAKTIF")
|
|
print("-" * 40)
|
|
print("Masukkan path gambar untuk prediksi (atau 'exit' untuk keluar):")
|
|
|
|
while True:
|
|
image_path = input("\nPath gambar: ").strip()
|
|
|
|
if image_path.lower() == 'exit':
|
|
break
|
|
|
|
if not os.path.exists(image_path):
|
|
print(f"Error: File tidak ditemukan: {image_path}")
|
|
continue
|
|
|
|
try:
|
|
# Baca dan proses gambar
|
|
image = cv2.imread(image_path)
|
|
if image is None:
|
|
print(f"Error: Tidak dapat membaca gambar: {image_path}")
|
|
continue
|
|
|
|
# Ekstraksi fitur
|
|
features = extract_color_histogram(image)
|
|
features = features.reshape(1, -1)
|
|
|
|
# Prediksi
|
|
prediction = model.predict(features)[0]
|
|
prediction_proba = model.predict_proba(features)[0]
|
|
|
|
# Konversi ke label kelas
|
|
predicted_class = label_encoder.inverse_transform([prediction])[0]
|
|
|
|
# Tampilkan hasil
|
|
print(f"\nHasil Prediksi:")
|
|
print(f"Kelas: {predicted_class}")
|
|
print(f"Probabilitas:")
|
|
for i, class_name in enumerate(label_encoder.classes_):
|
|
print(f" {class_name}: {prediction_proba[i]:.4f} ({prediction_proba[i]*100:.2f}%)")
|
|
|
|
# Confidence
|
|
max_prob = np.max(prediction_proba)
|
|
print(f"Confidence: {max_prob:.4f} ({max_prob*100:.2f}%)")
|
|
|
|
except Exception as e:
|
|
print(f"Error: {e}")
|
|
|
|
print("\n" + "=" * 60)
|
|
print("PREDIKSI SELESAI!")
|
|
print("=" * 60)
|
|
|
|
except Exception as e:
|
|
print(f"Error memuat model: {e}")
|
|
|
|
def predict_single_image(image_path):
|
|
"""
|
|
Fungsi untuk prediksi satu gambar
|
|
|
|
Parameters:
|
|
image_path: path ke file gambar
|
|
|
|
Returns:
|
|
tuple: (predicted_class, probabilities)
|
|
"""
|
|
# Muat model
|
|
models_folder = "models"
|
|
model_file = os.path.join(models_folder, "tomat_classifier.pkl")
|
|
encoder_file = os.path.join(models_folder, "label_encoder.pkl")
|
|
|
|
if not os.path.exists(model_file):
|
|
return None, None
|
|
|
|
try:
|
|
# Muat model dan encoder
|
|
model = joblib.load(model_file)
|
|
label_encoder = joblib.load(encoder_file)
|
|
|
|
# Baca gambar
|
|
image = cv2.imread(image_path)
|
|
if image is None:
|
|
return None, None
|
|
|
|
# Ekstraksi fitur
|
|
features = extract_color_histogram(image)
|
|
features = features.reshape(1, -1)
|
|
|
|
# Prediksi
|
|
prediction = model.predict(features)[0]
|
|
prediction_proba = model.predict_proba(features)[0]
|
|
|
|
# Konversi ke label kelas
|
|
predicted_class = label_encoder.inverse_transform([prediction])[0]
|
|
|
|
return predicted_class, prediction_proba
|
|
|
|
except Exception as e:
|
|
print(f"Error: {e}")
|
|
return None, None
|
|
|
|
if __name__ == "__main__":
|
|
load_model_and_predict()
|
|
|
|
|