| import gradio as gr |
| from transformers import AutoImageProcessor, AutoModelForImageClassification, pipeline |
| import torch |
| import torch.nn.functional as F |
| from PIL import Image |
|
|
| |
| |
| |
| print("Sedang memuat model... Mohon tunggu.") |
|
|
| |
| gatekeeper = pipeline("zero-shot-image-classification", model="google/siglip-base-patch16-224") |
|
|
| |
| model_name = "louislu9911/convnextv2-base-22k-384-finetuned-cassava-leaf-disease" |
| processor = AutoImageProcessor.from_pretrained(model_name) |
| model = AutoModelForImageClassification.from_pretrained(model_name) |
|
|
| |
| LABELS = { |
| 0: "Hawar Bakteri (CBB)", |
| 1: "Goresan Coklat (CBSD)", |
| 2: "Bercak Hijau (CGM)", |
| 3: "Virus Mosaik (CMD)", |
| 4: "Sehat (Healthy)" |
| } |
|
|
| |
| |
| |
| def deteksi(image): |
| if image is None: return "Error", "Silakan upload gambar." |
| |
| try: |
| |
| |
| |
| |
| |
| |
| all_candidates = [ |
| "cassava leaf", |
| |
| |
| "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", |
| |
| |
| "vector art digital illustration", |
| "3D rendered image", |
| "pixel art", |
| "sketch drawing cartoon", |
| "artificial plastic plant", |
| |
| |
| "cassava tuber root", "tree stem wood", "soil ground", "human person", |
| |
| |
| "solid black or dark image", |
| "blurry out of focus image", |
| "white blank image", |
| "far away field landscape" |
| ] |
| |
| |
| res = gatekeeper(image, candidate_labels=all_candidates) |
| top_label = res[0]['label'] |
| top_score = res[0]['score'] |
|
|
| |
| |
| |
| if top_label != "cassava leaf": |
| |
| pesan_error = "Objek Ditolak." |
| |
| |
| |
| 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)." |
|
|
| |
| elif any(k in top_label for k in ["black", "dark", "blurry", "white", "landscape"]): |
| pesan_error = "Kualitas foto buruk (Gelap/Blur/Kejauhan)." |
|
|
| |
| elif any(k in top_label for k in ["root", "stem", "soil", "human"]): |
| pesan_error = "Objek bukan daun (Terdeteksi Batang/Tanah/Manusia)." |
|
|
| |
| |
| else: |
| pesan_error = "Bukan Daun Singkong (Terdeteksi jenis tanaman lain)." |
| |
| return "DITOLAK", f"{pesan_error} (Skor AI: {top_score:.1%})" |
| |
| |
| if top_score < 0.20: |
| return "MERAGUKAN", f"Mirip singkong tapi AI ragu ({top_score:.1%}). Pastikan cahaya cukup & fokus." |
|
|
| |
| |
| |
| 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) |
|
|
| |
| |
| |
| 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() |