Spaces:
Sleeping
Sleeping
# -*- coding: utf-8 -*- | |
""" | |
Aplikasi Gradio untuk Analisis Komparatif Deteksi Helm Keselamatan | |
================================================================== | |
Deskripsi: | |
Aplikasi ini memungkinkan pengguna untuk mengunggah video dari lingkungan konstruksi | |
dan membandingkan kinerja dua model AI (YOLOv5m dan YOLOv8m) dalam mendeteksi | |
helm keselamatan secara real-time. Aplikasi ini dirancang untuk menjadi alat | |
evaluasi yang praktis dan mudah digunakan. | |
Fitur Utama: | |
- Perbandingan langsung antara model Generalis (YOLOv5) dan Spesialis (YOLOv8). | |
- Antarmuka pengguna (GUI) yang interaktif dan mudah dipahami. | |
- Pemrosesan video dengan batasan durasi dan resolusi untuk stabilitas. | |
- Menampilkan video hasil dengan anotasi deteksi (bounding box). | |
- Memberikan ringkasan hasil analisis kualitatif dan kuantitatif. | |
- Menyediakan dokumentasi, cara penggunaan, dan kredit yang jelas. | |
Pengembang: Faisal Fahmi Yuliawan | |
Berdasarkan Analisis pada Artikel Ilmiah. | |
""" | |
# --- 1. IMPORT LIBRARY --- | |
import gradio as gr | |
from ultralytics import YOLO | |
import cv2 | |
import numpy as np | |
import os | |
import tempfile | |
import time | |
import logging | |
# --- 2. SETUP & KONFIGURASI AWAL --- | |
# Konfigurasi logging untuk memantau proses | |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
# --- 3. PEMUATAN MODEL AI --- | |
# Memuat kedua model saat aplikasi dimulai untuk respons yang lebih cepat. | |
# Ini menggunakan memori lebih, tetapi meningkatkan pengalaman pengguna. | |
try: | |
logging.info("Memulai pemuatan model AI...") | |
# Model 1: Spesialis (Fokus pada Helm) | |
model_spesialis = YOLO('keremberke/yolov8m-hard-hat-detection') | |
model_spesialis.overrides['conf'] = 0.25 | |
model_spesialis.overrides['iou'] = 0.45 | |
logging.info("β Model Spesialis (YOLOv8m-HH) berhasil dimuat.") | |
# Model 2: Generalis (Mendeteksi banyak objek konstruksi) | |
model_generalis = YOLO('keremberke/yolov5m-construction-safety') | |
model_generalis.overrides['conf'] = 0.25 | |
model_generalis.overrides['iou'] = 0.45 | |
logging.info("β Model Generalis (YOLOv5m-CS) berhasil dimuat.") | |
# Membuat dictionary untuk kemudahan akses model | |
models = { | |
"YOLOv8m (Spesialis Helm)": model_spesialis, | |
"YOLOv5m (Generalis Konstruksi)": model_generalis | |
} | |
logging.info("Semua model siap digunakan.") | |
except Exception as e: | |
logging.error(f"Gagal memuat salah satu model AI: {e}") | |
# Jika model gagal dimuat, aplikasi tidak dapat berjalan. | |
# Gradio akan menangani error ini dan menampilkannya di UI. | |
raise RuntimeError(f"Tidak dapat memuat model AI. Aplikasi tidak dapat dijalankan. Error: {e}") | |
# --- 4. FUNGSI UTAMA PEMROSESAN VIDEO --- | |
def process_video_and_analyze(video_path, selected_model_name, progress=gr.Progress(track_tqdm=True)): | |
""" | |
Fungsi utama untuk memproses video, melakukan deteksi objek, | |
dan mengembalikan video hasil beserta analisisnya. | |
""" | |
if video_path is None: | |
return None, "Status: Silakan unggah video terlebih dahulu.", "" | |
try: | |
logging.info(f"Memulai pemrosesan video: {video_path} menggunakan model: {selected_model_name}") | |
start_time = time.time() | |
# Pilih model berdasarkan input dari UI | |
model = models[selected_model_name] | |
# Buka file video | |
cap = cv2.VideoCapture(video_path) | |
if not cap.isOpened(): | |
logging.error(f"Gagal membuka file video: {video_path}") | |
return None, "Error: Gagal membuka file video. Format mungkin tidak didukung.", "" | |
# Dapatkan properti video | |
fps = cap.get(cv2.CAP_PROP_FPS) or 30 | |
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) | |
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) | |
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) | |
# Batasi resolusi untuk performa yang lebih baik | |
target_width = 640 | |
target_height = int(height * (target_width / width)) if width > 0 else 480 | |
# Konfigurasi video output | |
# Menggunakan tempfile untuk file output sementara | |
temp_output_path = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False).name | |
fourcc = cv2.VideoWriter_fourcc(*"mp4v") | |
out = cv2.VideoWriter(temp_output_path, fourcc, fps, (target_width, target_height)) | |
# Variabel untuk analisis | |
detection_count = 0 | |
helm_detected_count = 0 | |
progress(0, desc="Memulai Pemrosesan...") | |
for frame_idx in range(total_frames): | |
ret, frame = cap.read() | |
if not ret: | |
break | |
# Update progress bar | |
progress(frame_idx / total_frames, desc=f"Memproses Frame {frame_idx+1}/{total_frames}") | |
# Resize frame | |
frame_resized = cv2.resize(frame, (target_width, target_height)) | |
# Lakukan prediksi (inferensi) | |
results = model.predict(frame_resized, verbose=False) | |
# Render hasil deteksi ke frame | |
annotated_frame = results[0].plot() | |
# Hitung deteksi | |
detection_count += len(results[0].boxes) | |
# Hitung deteksi helm secara spesifik | |
if selected_model_name == "YOLOv8m (Spesialis Helm)": | |
for box in results[0].boxes: | |
class_id = int(box.cls) | |
# Kelas '0' biasanya 'Hardhat' di model ini | |
if model.names[class_id].lower() in ['hardhat', 'helmet']: | |
helm_detected_count += 1 | |
elif selected_model_name == "YOLOv5m (Generalis Konstruksi)": | |
for box in results[0].boxes: | |
class_id = int(box.cls) | |
if model.names[class_id].lower() == 'helmet': | |
helm_detected_count += 1 | |
out.write(annotated_frame) | |
end_time = time.time() | |
processing_time = end_time - start_time | |
# Tutup file video | |
cap.release() | |
out.release() | |
logging.info(f"Video berhasil diproses dalam {processing_time:.2f} detik.") | |
# Siapkan teks analisis | |
analysis_text = f""" | |
### Analisis Kinerja Model: {selected_model_name} | |
- **Waktu Proses Total:** {processing_time:.2f} detik | |
- **Total Frame Diproses:** {total_frames} | |
- **Jumlah Deteksi Keseluruhan:** {detection_count} objek | |
- **Jumlah Deteksi Helm:** {helm_detected_count} objek | |
**Catatan:** | |
- **Model Spesialis (YOLOv8m):** Diharapkan memiliki akurasi deteksi helm yang tinggi, namun hanya mendeteksi kelas terkait helm ('Hardhat', 'NO-Hardhat'). | |
- **Model Generalis (YOLOv5m):** Mampu mendeteksi berbagai objek (11 kelas termasuk 'person', 'vest'), namun akurasi untuk 'helmet' mungkin lebih rendah karena fokusnya terbagi. | |
""" | |
return temp_output_path, f"Status: Video berhasil diproses! ({processing_time:.2f} detik)", analysis_text | |
except Exception as e: | |
logging.error(f"Terjadi error saat memproses video: {e}", exc_info=True) | |
return None, f"Error: Terjadi kesalahan internal - {e}", "" | |
# --- 5. PEMBUATAN ANTARMUKA PENGGUNA (GRADIO UI) --- | |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky")) as iface: | |
# --- Bagian Judul dan Deskripsi --- | |
gr.Markdown( | |
""" | |
# π‘οΈ Analisis Komparatif Deteksi Helm Keselamatan | |
Selamat datang di prototipe aplikasi untuk analisis perbandingan model AI dalam mendeteksi helm keselamatan. | |
Aplikasi ini memungkinkan Anda untuk melihat perbedaan kinerja antara model AI yang **spesialis** (hanya untuk helm) | |
dan model AI yang **generalis** (untuk berbagai objek konstruksi). | |
""" | |
) | |
with gr.Row(): | |
with gr.Column(scale=1): | |
# --- Bagian Input Pengguna --- | |
gr.Markdown("### **Langkah 1: Konfigurasi & Unggah**") | |
selected_model_ui = gr.Radio( | |
choices=list(models.keys()), | |
label="Pilih Model AI untuk Perbandingan", | |
value="YOLOv8m (Spesialis Helm)", | |
info="Pilih algoritma yang ingin Anda gunakan untuk mendeteksi objek." | |
) | |
video_input = gr.Video( | |
label="Unggah Video Anda", | |
info="Format video yang direkomendasikan adalah .mp4. Durasi maksimal ~30 detik." | |
) | |
detect_btn = gr.Button("π Mulai Deteksi", variant="primary") | |
gr.Markdown("---") | |
gr.Markdown("### **Cara Penggunaan**") | |
gr.Markdown( | |
""" | |
1. **Pilih Model AI** yang ingin Anda uji dari opsi di atas. | |
2. **Unggah file video** dari perangkat Anda atau **pilih contoh** di bawah. | |
3. Klik tombol **"Mulai Deteksi"** dan tunggu proses selesai. | |
4. Lihat **video hasil** dan **analisis kinerja** di sebelah kanan. | |
5. Ulangi dengan model lain untuk melihat perbandingannya. | |
""" | |
) | |
with gr.Column(scale=1): | |
# --- Bagian Output Hasil --- | |
gr.Markdown("### **Langkah 2: Lihat Hasil Deteksi**") | |
video_output = gr.Video(label="Video Hasil Deteksi") | |
status_text = gr.Textbox(label="Status Proses", interactive=False) | |
gr.Markdown("---") | |
gr.Markdown("### **Ringkasan Analisis**") | |
analysis_output = gr.Markdown(label="Analisis Kinerja") | |
# --- Bagian Contoh Video --- | |
gr.Examples( | |
examples=[ | |
[os.path.join(os.path.dirname(__file__), "video_contoh_1.mp4"), "YOLOv8m (Spesialis Helm)"], | |
[os.path.join(os.path.dirname(__file__), "video_contoh_2.mp4"), "YOLOv5m (Generalis Konstruksi)"] | |
], | |
inputs=[video_input, selected_model_ui], | |
outputs=[video_output, status_text, analysis_output], | |
fn=process_video_and_analyze, | |
cache_examples=True, | |
label="Contoh Video (Klik untuk mencoba)" | |
) | |
# --- Bagian Informasi dan Kredit --- | |
with gr.Accordion("βΉοΈ Informasi, Kredit, dan Potensi Pengembangan", open=False): | |
gr.Markdown( | |
""" | |
### **Identitas Prototipe** | |
- **Pengembang:** Faisal Fahmi Yuliawan (sebagai bagian dari studi ilmiah). | |
- **Tujuan:** Menyediakan alat bantu visual untuk membandingkan kinerja model AI dalam konteks keselamatan kerja (K3), khususnya deteksi helm. | |
- **Relevansi:** Masalah kepatuhan penggunaan APD (Alat Pelindung Diri) seperti helm adalah kasus nyata dan krusial di industri konstruksi untuk mencegah kecelakaan fatal. | |
### **Kredit Pihak Ketiga** | |
- **Model AI:** - `keremberke/yolov8m-hard-hat-detection` (Model Spesialis) dari Hugging Face. | |
- `keremberke/yolov5m-construction-safety` (Model Generalis) dari Hugging Face. | |
- **Teknologi:** - **Ultralytics YOLO:** Framework utama untuk model AI. | |
- **Gradio:** Framework untuk membangun antarmuka web interaktif ini. | |
- **OpenCV & FFmpeg:** Untuk pemrosesan dan manipulasi video. | |
### **Potensi Pengembangan & Komersialisasi** | |
- **Skalabilitas:** Arsitektur aplikasi ini dapat dengan mudah diperluas untuk mencakup lebih banyak model AI atau jenis APD lain (misalnya, rompi, sepatu bot, sarung tangan). | |
- **Integrasi:** Dapat diintegrasikan dengan sistem CCTV di lokasi konstruksi untuk pemantauan otomatis dan sistem peringatan *real-time*. | |
- **Potensi Bisnis:** Memiliki potensi komersial sebagai produk SaaS (*Software as a Service*) untuk perusahaan konstruksi yang ingin meningkatkan standar K3 dan melakukan audit kepatuhan secara digital. | |
""" | |
) | |
# --- Hubungkan Aksi Tombol ke Fungsi --- | |
detect_btn.click( | |
fn=process_video_and_analyze, | |
inputs=[video_input, selected_model_ui], | |
outputs=[video_output, status_text, analysis_output] | |
) | |
# --- 6. LUNCURKAN APLIKASI --- | |
if __name__ == "__main__": | |
# Untuk menjalankan, simpan kode ini sebagai file .py (misal: app.py) | |
# Buat 2 file video contoh: video_contoh_1.mp4 dan video_contoh_2.mp4 di folder yang sama. | |
# Jalankan dari terminal dengan: python app.py | |
iface.launch(debug=True, share=True) | |