Spaces:
Sleeping
Sleeping
| 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() |