import gradio as gr from transformers import pipeline from PIL import Image, ExifTags import numpy as np import cv2 # ---------------------------- # MODEL DETEKSI AI # ---------------------------- try: hf_detector = pipeline("image-classification", model="umm-maybe/AI-image-detector") except Exception as e: hf_detector = None print("HF AI-detector gagal dimuat:", e) try: general_model = pipeline("image-classification", model="google/vit-base-patch16-224") except Exception as e: general_model = None print("General classifier gagal dimuat:", e) # ---------------------------- # ANALISIS LOKAL # ---------------------------- def calculate_blur(image): gray = np.array(image.convert("L")) return cv2.Laplacian(gray, cv2.CV_64F).var() def calculate_noise(image): gray = np.array(image.convert("L"), dtype=np.float32) noise_std = np.std(gray - np.mean(gray)) return noise_std def has_camera_exif(image): try: exif = image._getexif() if exif: for tag, value in exif.items(): decoded = ExifTags.TAGS.get(tag, tag) if decoded in ["Make", "Model"]: return True except: return False return False # ---------------------------- # DETEKSI HYBRID DENGAN THRESHOLD LAMA # ---------------------------- def detect_image(image: Image.Image): output_lines = [] # -------- HF AI-detector -------- hf_score = 0 hf_label = "N/A" hf_conf = 0 if hf_detector: try: result = hf_detector(image) hf_label = result[0]['label'] hf_conf = result[0]['score'] * 100 if any(x in hf_label.lower() for x in ["fake", "ai", "artificial"]): hf_score = hf_conf except: hf_score = 0 if hf_score > 50: # threshold HF lama final_result = "🤖 AI Detected" weighted_score = hf_score output_lines.append(f"### Hasil Deteksi:\n{final_result}") output_lines.append(f"HF AI-detector: {hf_label} ({hf_conf:.2f}%)") return "\n".join(output_lines) # -------- General model -------- general_score = 0 general_label = "N/A" general_conf = 0 if general_model: try: result2 = general_model(image) general_label = result2[0]['label'] general_conf = result2[0]['score'] * 100 if any(x in general_label.lower() for x in ["anime","cartoon","illustration","maya","3d"]): general_score = general_conf except: general_score = 0 # -------- Analisis lokal -------- blur_score = calculate_blur(image) noise_score = calculate_noise(image) exif_present = has_camera_exif(image) local_score = 0 if blur_score < 100 or noise_score < 10: local_score += 50 if not exif_present: local_score += 10 # -------- Weighted Score -------- weighted_score = general_score*0.7 + local_score*0.3 if weighted_score > 50: final_result = "🤖 AI Detected" else: final_result = "✅ Foto Asli" # -------- Output -------- output_lines.append(f"### Hasil Deteksi:\n{final_result}") output_lines.append(f"Weighted Skor: {weighted_score:.2f}") output_lines.append(f"HF AI-detector: {hf_label} ({hf_conf:.2f}%)") output_lines.append(f"General Model: {general_label} ({general_conf:.2f}%)") output_lines.append(f"Blur Score: {blur_score:.2f}") output_lines.append(f"Noise Score: {noise_score:.2f}") output_lines.append(f"Metadata Kamera: {'Ada' if exif_present else 'Tidak Ada'}") return "\n".join(output_lines) # ---------------------------- # Gradio Interface (5.x syntax) # ---------------------------- with gr.Blocks(title="AI vs Foto Asli Detector (Versi Akurat)") as demo: gr.Markdown("Unggah gambar, sistem akan mendeteksi apakah gambar kemungkinan besar asli atau dihasilkan AI.") with gr.Row(): img_input = gr.Image(type="pil", label="Unggah Gambar") output_md = gr.Markdown(label="Hasil Deteksi") detect_btn = gr.Button("Deteksi") detect_btn.click(fn=detect_image, inputs=img_input, outputs=output_md) if __name__ == "__main__": demo.launch()