Froge / app.py
Dayat555's picture
Update app.py
79ab99b verified
import gradio as gr
from transformers import AutoImageProcessor, AutoModelForImageClassification, pipeline
import torch
import torch.nn.functional as F
from PIL import Image
# ==========================================
# 1. INISIALISASI MODEL
# ==========================================
print("Sedang memuat model... Mohon tunggu.")
# Gatekeeper: Google SigLIP
gatekeeper = pipeline("zero-shot-image-classification", model="google/siglip-base-patch16-224")
# Specialist: ConvNeXt
model_name = "louislu9911/convnextv2-base-22k-384-finetuned-cassava-leaf-disease"
processor = AutoImageProcessor.from_pretrained(model_name)
model = AutoModelForImageClassification.from_pretrained(model_name)
# Label Mapping
LABELS = {
0: "Hawar Bakteri (CBB)",
1: "Goresan Coklat (CBSD)",
2: "Bercak Hijau (CGM)",
3: "Virus Mosaik (CMD)",
4: "Sehat (Healthy)"
}
# ==========================================
# 2. FUNGSI UTAMA
# ==========================================
def deteksi(image):
if image is None: return "Error", "Silakan upload gambar."
try:
# ------------------------------------------------------------
# VALIDASI INTERNAL (INPUT TETAP SPESIFIK)
# ------------------------------------------------------------
# Kita biarkan AI menebak secara detail di dalam hati,
# agar dia bisa membedakan fitur visual dengan akurat.
all_candidates = [
"cassava leaf", # TARGET
# Group Tanaman Lain (Musuh)
"papaya leaf", "castor bean leaf", "kapok leaf", "marijuana leaf",
"corn leaf", "rice plant leaf", "banana leaf",
"mango leaf", "tomato leaf", "chili pepper leaf",
"ginger turmeric leaf", # Tambahan biar jahe ketangkap
# Group Digital/Palsu
"vector art digital illustration",
"3D rendered image",
"pixel art",
"sketch drawing cartoon",
"artificial plastic plant",
# Group Bukan Daun
"cassava tuber root", "tree stem wood", "soil ground", "human person",
# Group Kualitas Buruk
"solid black or dark image",
"blurry out of focus image",
"white blank image",
"far away field landscape"
]
# Jalankan Gatekeeper
res = gatekeeper(image, candidate_labels=all_candidates)
top_label = res[0]['label']
top_score = res[0]['score']
# --- LOGIKA OUTPUT (KE USER) ---
# Di sini kita "sensor" jawaban AI biar tidak spesifik/sok tau.
if top_label != "cassava leaf":
pesan_error = "Objek Ditolak." # Default
# 1. CEK DIGITAL / PALSU
# Kalau labelnya mengandung kata-kata ini, kita bilang "Bukan Foto Asli"
fake_keywords = ["vector", "illustration", "3D", "pixel", "sketch", "cartoon", "artificial", "plastic"]
if any(k in top_label for k in fake_keywords):
pesan_error = "Bukan foto daun asli (Terdeteksi gambar digital/palsu)."
# 2. CEK KUALITAS FOTO
elif any(k in top_label for k in ["black", "dark", "blurry", "white", "landscape"]):
pesan_error = "Kualitas foto buruk (Gelap/Blur/Kejauhan)."
# 3. CEK BUKAN DAUN (BATANG/TANAH/MANUSIA/UMBI)
elif any(k in top_label for k in ["root", "stem", "soil", "human"]):
pesan_error = "Objek bukan daun (Terdeteksi Batang/Tanah/Manusia)."
# 4. SISA NYA ADALAH "TANAMAN LAIN" (JAGUNG, PEPAYA, JAHE, DLL)
# Kita tidak perlu sebut namanya. Cukup bilang "Bukan Daun Singkong".
else:
pesan_error = "Bukan Daun Singkong (Terdeteksi jenis tanaman lain)."
return "DITOLAK", f"{pesan_error} (Skor AI: {top_score:.1%})"
# Syarat Skor Minimal
if top_score < 0.20:
return "MERAGUKAN", f"Mirip singkong tapi AI ragu ({top_score:.1%}). Pastikan cahaya cukup & fokus."
# ------------------------------------------------------------
# DIAGNOSA PENYAKIT
# ------------------------------------------------------------
inputs = processor(images=image, return_tensors="pt")
with torch.no_grad():
logits = model(**inputs).logits
probs = F.softmax(logits, dim=-1)
idx = probs.argmax(-1).item()
confidence = probs[0][idx].item()
if confidence < 0.50:
return "Tidak Teridentifikasi", f"Pola penyakit tidak jelas. ({confidence:.1%})"
return LABELS[idx], f"Keyakinan: {confidence:.1%}"
except Exception as e:
return "System Error", str(e)
# ==========================================
# 3. INTERFACE
# ==========================================
title = "🍂 Deteksi Singkong (Simple Validator)"
description = "Sistem hanya menerima foto Daun Singkong Asli. Foto buram, digital, atau tanaman lain akan ditolak."
iface = gr.Interface(
fn=deteksi,
inputs=gr.Image(type="pil", label="Upload Foto"),
outputs=[gr.Label(num_top_classes=0, label="Status"), gr.Textbox(label="Keterangan")],
title=title,
description=description,
flagging_mode="never"
)
iface.launch()