Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from PIL import Image, ExifTags | |
| import numpy as np | |
| import cv2 | |
| # ---------------------------- | |
| # 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) | |
| return np.std(gray - np.mean(gray)) | |
| 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 | |
| # -------- FFT ANALYSIS -------- | |
| def high_freq_artifacts(image): | |
| gray = np.array(image.convert("L"), dtype=np.float32) | |
| f = np.fft.fft2(gray) | |
| fshift = np.fft.fftshift(f) | |
| magnitude_spectrum = np.abs(fshift) | |
| rows, cols = gray.shape | |
| crow, ccol = rows // 2 , cols // 2 | |
| r = min(crow, ccol) // 4 | |
| mask = np.zeros((rows, cols)) | |
| mask[crow-r:crow+r, ccol-r:ccol+r] = 1 | |
| low_energy = np.sum(magnitude_spectrum * mask) | |
| total_energy = np.sum(magnitude_spectrum) | |
| high_ratio = (total_energy - low_energy) / total_energy * 100 | |
| return high_ratio | |
| # ---------------------------- | |
| # DETEKSI AI HYBRID ADAPTIF | |
| # ---------------------------- | |
| def detect_image(image: Image.Image): | |
| blur_score = calculate_blur(image) | |
| noise_score = calculate_noise(image) | |
| exif_present = has_camera_exif(image) | |
| high_freq_score = high_freq_artifacts(image) | |
| # ---------- Scoring adaptif ---------- | |
| hf_norm = min(high_freq_score / 10, 10) | |
| noise_norm = max(0, 12 - noise_score) | |
| weighted_score = 0.5 * hf_norm + 0.5 * noise_norm | |
| # Threshold tegas | |
| is_ai = False | |
| if not exif_present and weighted_score > 5 and blur_score < 150: | |
| is_ai = True | |
| final_result = "π€ AI Detected" if is_ai else "β Foto Asli" | |
| output_lines = [ | |
| f"### Hasil Deteksi:\n{final_result}", | |
| f"Blur Score: {blur_score:.2f}", | |
| f"Noise Score: {noise_score:.2f}", | |
| f"High-Freq Artifacts Score: {high_freq_score:.2f}", | |
| f"Weighted Score: {weighted_score:.2f}", | |
| f"Metadata Kamera: {'Ada' if exif_present else 'Tidak Ada'}" | |
| ] | |
| return "\n".join(output_lines) | |
| # ---------------------------- | |
| # GRADIO INTERFACE | |
| # ---------------------------- | |
| with gr.Blocks(title="Hybrid AI Realistic Detector (Jejak Digital)") 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() | |