HomeCheck / app.py
Ferdinann's picture
Update app.py
96980ce verified
import gradio as gr
import tensorflow as tf
import pandas as pd
import numpy as np
from datetime import datetime
from PIL import Image
MODEL_PATH = "best_model.h5"
class_names = ['layak', 'rusak']
history_data = []
try:
best_model = tf.keras.models.load_model(MODEL_PATH)
print("βœ… Model berhasil dimuat.")
except Exception as e:
print(f"❌ Gagal memuat model: {e}")
# Dummy model untuk mencegah crash saat build jika file belum ada
best_model = None
# --- 2. Fungsi Helper ---
def get_detailed_info(label, confidence):
if label == 'layak':
if confidence > 0.85:
return "### βœ… STATUS: SANGAT LAYAK\n**Analisis:** Bangunan dalam kondisi prima. Struktur utama terlihat utuh dan sangat aman untuk dihuni."
return "### ⚠️ STATUS: LAYAK (DENGAN CATATAN)\n**Analisis:** Bangunan aman dihuni, namun ditemukan indikasi kerusakan minor. Disarankan pengecekan rutin pada area retakan."
else:
if confidence > 0.85:
return "### 🚨 STATUS: RUSAK PARAH\n**Analisis:** BAHAYA! Ditemukan kerusakan struktur fatal. Segera kosongkan area dan hubungi pihak berwenang."
return "### 🚧 STATUS: RUSAK RINGAN\n**Analisis:** Terdeteksi kerusakan fisik pada beberapa bagian. Perlu perbaikan teknis sebelum bangunan dinyatakan aman sepenuhnya."
def predict_image(img):
if best_model is None:
return {}, "Model belum dimuat."
# Preprocessing
img = img.resize((224, 224))
img_array = tf.keras.preprocessing.image.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) / 255.0
# Prediksi
predictions = best_model.predict(img_array)[0]
result = {class_names[i]: float(predictions[i]) for i in range(len(class_names))}
top_label = max(result, key=result.get)
description = get_detailed_info(top_label, result[top_label])
return result, description
# --- 3. Fungsi Logic Dashboard ---
def handle_upload(img):
if img is None: return {}, "_Menunggu foto bangunan..._"
return predict_image(img)
def handle_report(img, location):
if img is None:
return {}, pd.DataFrame(history_data, columns=["Waktu", "Status", "Lokasi"]), None, "❌ Gagal: Foto kosong."
output_dict, desc = predict_image(img)
status = max(output_dict, key=output_dict.get).upper()
now = datetime.now().strftime("%H:%M | %d-%m-%Y")
history_data.insert(0, [now, status, location if location else "Pusat Kota"])
df = pd.DataFrame(history_data, columns=["Waktu", "Status", "Lokasi"])
return output_dict, df, None, "βœ… Laporan berhasil disimpan ke riwayat!"
# --- 4. UI Layout HomeCheck ---
with gr.Blocks(title="HomeCheck AI") as demo:
# Header Area
with gr.Row():
with gr.Column(scale=8):
gr.Markdown("# 🏠 HomeCheck AI")
gr.Markdown("### *Sistem Deteksi Kelayakan Bangunan Cerdas*")
with gr.Column(scale=2):
gr.Markdown("![Logo](https://img.icons8.com/fluency/96/home.png)")
gr.Markdown("---")
with gr.Tabs():
with gr.TabItem("πŸ” Analisis Baru"):
with gr.Row():
# Kolom Kiri: Input
with gr.Column(variant="panel"):
gr.Markdown("#### πŸ“₯ Input Data")
input_img = gr.Image(sources=["upload", "webcam"], type="pil", label="Foto Bangunan")
input_loc = gr.Textbox(
label="Titik Lokasi",
placeholder="Contoh: Perumahan Indah Blok A, Medan",
lines=1
)
btn_report = gr.Button("πŸš€ SIMPAN LAPORAN", variant="primary")
# Kolom Kanan: Hasil
with gr.Column():
gr.Markdown("#### πŸ“Š Hasil Diagnosa")
output_label = gr.Label(num_top_classes=2, label="Probabilitas Akurasi")
with gr.Group():
output_description = gr.Markdown(
"**Instruksi:**\nSilakan ambil atau upload foto bagian bangunan yang ingin diperiksa.",
)
with gr.TabItem("πŸ“œ Riwayat Pemeriksaan"):
gr.Markdown("#### πŸ“‘ Log Laporan Tersimpan")
output_history = gr.Dataframe(
headers=["Waktu", "Status", "Lokasi"],
datatype=["str", "str", "str"],
interactive=False
)
gr.Markdown("---")
gr.Markdown("Β© 2026 HomeCheck AI")
# --- Interaction Logic ---
input_img.change(fn=handle_upload, inputs=input_img, outputs=[output_label, output_description])
btn_report.click(
fn=handle_report,
inputs=[input_img, input_loc],
outputs=[output_label, output_history, input_img, output_description]
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)