import gradio as gr import cv2 import numpy as np import tensorflow as tf import os from tempfile import NamedTemporaryFile from tqdm import tqdm # Load model model = tf.keras.models.load_model('rain_detection_model.h5') IMG_SIZE = (256, 256) def batch_predict(frames): resized = [cv2.resize(f, IMG_SIZE) for f in frames] batch = np.array(resized) / 255.0 preds = model.predict(batch) results = [] for p in preds: label = "Hujan" if p[0] > 0.7 else "Terang" confidence = float(p[0]) if label == "Hujan" else 1 - float(p[0]) results.append((label, round(confidence, 2))) return results def process_video(video_file): cap = cv2.VideoCapture(video_file) fps = cap.get(cv2.CAP_PROP_FPS) total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) frame_interval = int(fps * 1) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) extra_space = 50 out_path = NamedTemporaryFile(delete=False, suffix=".mp4").name out = cv2.VideoWriter(out_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (width, height + extra_space)) frames = [] original_frames = [] frame_idxs = [] i = 0 with tqdm(total=total_frames) as pbar: while True: ret, frame = cap.read() if not ret: break if i % frame_interval == 0: frames.append(frame.copy()) frame_idxs.append(i) original_frames.append(frame) i += 1 pbar.update(1) print("[INFO] Melakukan prediksi cuaca setiap 1 detik...") label_conf_list = batch_predict(frames) label_dict = dict(zip(frame_idxs, label_conf_list)) current_label = "Tidak diketahui" current_conf = 0.0 current_color = (255, 255, 255) for i, frame in enumerate(original_frames): if i in label_dict: current_label, current_conf = label_dict[i] current_color = (0, 255, 0) if current_label == "Terang" else (0, 0, 255) # Tambah canvas putih di atas frame label_area = np.ones((extra_space, width, 3), dtype=np.uint8) * 255 combined_frame = np.vstack((label_area, frame)) text = f"{current_label} ({current_conf:.2f})" font = cv2.FONT_HERSHEY_SIMPLEX font_scale = 1 thickness = 2 (text_width, text_height), _ = cv2.getTextSize(text, font, font_scale, thickness) text_x = (width - text_width) // 2 text_y = (extra_space + text_height) // 2 # Tambah teks di canvas (tengah atas) cv2.putText(combined_frame, text, (text_x, text_y), font, font_scale, current_color, thickness) out.write(combined_frame) cap.release() out.release() print("[INFO] Proses selesai. Video disimpan di:", out_path) return out_path, out_path # Gradio Interface interface = gr.Interface( fn=process_video, inputs=gr.Video(label="Upload Video"), outputs=[ gr.Video(label="Hasil Prediksi (Putar Video)"), gr.File(label="Unduh Video Hasil Prediksi") ], title="Prediksi Cuaca", description="Upload video. Sistem akan memprediksi 'Hujan' atau 'Terang'." ) interface.launch(debug=True)