import gradio as gr import cv2 import numpy as np import tensorflow as tf from tensorflow.keras.applications.resnet_v2 import preprocess_input # 1. Load Model ResNet50V2 yang udah di-training model = tf.keras.models.load_model("model_cctv.h5") # Urutan kategori WAJIB SAMA persis dengan output Colab (sesuai urutan alfabet folder) CATEGORIES = ['kebakaran', 'normal'] # Disarankan alfabetis: K baru N, pastikan sesuai training! IMG_SIZE = (224, 224) FRAMES_PER_VIDEO = 20 def predict_video(video_path): if video_path is None: return "Upload video dulu, Bro!" cap = cv2.VideoCapture(video_path) total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) if total_frames == 0: return "Video rusak atau tidak terbaca." interval = max(1, total_frames // FRAMES_PER_VIDEO) frames = [] count = 0 extracted = 0 # 2. Ekstraksi Frame while cap.isOpened() and extracted < FRAMES_PER_VIDEO: ret, frame = cap.read() if not ret: break if count % interval == 0: # Convert BGR (OpenCV) ke RGB (Keras/Gradio) frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) frame_res = cv2.resize(frame, IMG_SIZE) frames.append(frame_res) extracted += 1 count += 1 cap.release() if len(frames) == 0: return "Gagal mengekstrak frame dari video." # 3. Preprocessing frames_array = np.array(frames) frames_array = preprocess_input(frames_array) # 4. Prediksi dengan Model predictions = model.predict(frames_array) predicted_classes = np.argmax(predictions, axis=1) # 5. Majority Voting (Ambil Suara Terbanyak) counts = np.bincount(predicted_classes, minlength=len(CATEGORIES)) majority_class_idx = np.argmax(counts) majority_class = CATEGORIES[majority_class_idx] confidence = counts[majority_class_idx] / len(predicted_classes) return f"🚨 Hasil Deteksi: {majority_class.upper()} \nšŸ“Š Tingkat Keyakinan (Majority Vote): {confidence*100:.1f}%" # 6. Bikin Tampilan (UI) Pakai Gradio (KODE INI HARUS DI LUAR FUNGSI / TIDAK MENJOROK) interface = gr.Interface( fn=predict_video, inputs=gr.Video(label="Upload Video CCTV (Max 30s)"), outputs=gr.Textbox(label="Kesimpulan Sistem"), title="Sistem Deteksi Anomali CCTV Pintar (Kebakaran)", description="Upload video CCTV mentah. Sistem akan memecahnya menjadi 20 frame, menganalisis dengan ResNet50V2, dan mengambil keputusan berdasarkan Majority Voting." ) if __name__ == "__main__": interface.launch()