MetaQu commited on
Commit
64a94a9
·
verified ·
1 Parent(s): 3561a8c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -62
app.py CHANGED
@@ -1,78 +1,100 @@
 
 
 
1
  import cv2
2
  import numpy as np
3
- from PIL import Image, ExifTags
4
- from transformers import pipeline
5
 
6
- # === Load dua model AI detector ===
7
- detector1 = pipeline("image-classification", model="umm-maybe/AI-image-detector")
8
- detector2 = pipeline("image-classification", model="fal-ai/ai-or-not")
 
 
 
9
 
10
- # === Forensik sederhana ===
11
- def forensic_analysis(img_path):
12
- img = cv2.imread(img_path)
13
 
14
- # Blur score (varian Laplacian)
15
- gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
16
- blur_score = cv2.Laplacian(gray, cv2.CV_64F).var()
17
-
18
- # Noise score (std dev setelah highpass filter)
19
- noise = cv2.GaussianBlur(gray, (3, 3), 0)
20
- highpass = cv2.subtract(gray, noise)
21
- noise_score = np.std(highpass)
22
-
23
- # High frequency ratio (FFT)
 
 
24
  f = np.fft.fft2(gray)
25
  fshift = np.fft.fftshift(f)
26
  magnitude_spectrum = np.abs(fshift)
27
- hfreq_ratio = np.mean(magnitude_spectrum > np.percentile(magnitude_spectrum, 95))
28
-
29
- # EXIF check
30
- try:
31
- pil_img = Image.open(img_path)
32
- exif = pil_img._getexif()
33
- exif_exists = exif is not None
34
- except:
35
- exif_exists = False
36
-
 
 
37
  return {
38
- "blur": round(blur_score, 2),
39
- "noise": round(noise_score, 2),
40
- "hfreq_ratio": round(hfreq_ratio, 3),
41
- "exif": exif_exists
 
42
  }
43
 
44
- # === Deteksi AI vs Asli dengan ensemble ===
45
- def detect_ai(img_path):
46
- results1 = detector1(img_path)
47
- results2 = detector2(img_path)
48
-
49
- # Ambil skor "AI" (label bisa berbeda di tiap model)
50
- score1 = max([r['score'] for r in results1 if "artificial" in r['label'].lower()] + [0])
51
- score2 = max([r['score'] for r in results2 if "ai" in r['label'].lower()] + [0])
52
-
53
- ai_score = (score1 + score2) / 2 * 100
54
- real_score = 100 - ai_score
55
-
56
- forensic = forensic_analysis(img_path)
57
-
58
- # Aturan custom
59
- if ai_score > 60:
60
- verdict = "🟥 AI"
61
- elif real_score > 60 and forensic["exif"]:
62
- verdict = "🟩 Asli"
 
 
 
 
 
 
 
 
 
63
  else:
64
- verdict = "⚠️ Meragukan"
65
-
 
66
  return {
67
- "AI_score": round(ai_score, 2),
68
- "Real_score": round(real_score, 2),
69
- "Forensic": forensic,
70
- "Verdict": verdict
71
  }
72
 
73
- # === Contoh pemakaian ===
 
 
 
 
 
 
 
 
74
  if __name__ == "__main__":
75
- img_path = "download.jpeg" # ganti sesuai nama file upload
76
- result = detect_ai(img_path)
77
- print("Hasil Deteksi:")
78
- print(result)
 
1
+ import gradio as gr
2
+ from transformers import pipeline
3
+ from PIL import Image, ExifTags
4
  import cv2
5
  import numpy as np
 
 
6
 
7
+ # ===== 1. Load 3 Public Models =====
8
+ model_ids = [
9
+ "umm-maybe/AI-image-detector", # Detektor umum
10
+ "vikhyatk/moondream2", # Model multimodal
11
+ "microsoft/resnet-50" # Baseline visual classifier
12
+ ]
13
 
14
+ detectors = [pipeline("image-classification", model=m) for m in model_ids]
 
 
15
 
16
+ # ===== 2. Fungsi Forensik Manual =====
17
+ def forensic_analysis(img: Image.Image):
18
+ img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
19
+
20
+ # Blur (Laplacian variance)
21
+ blur_var = cv2.Laplacian(img_cv, cv2.CV_64F).var()
22
+
23
+ # Noise (High-pass filter std)
24
+ gray = cv2.cvtColor(img_cv, cv2.COLOR_BGR2GRAY)
25
+ noise = cv2.Laplacian(gray, cv2.CV_64F).std()
26
+
27
+ # High-frequency ratio (FFT)
28
  f = np.fft.fft2(gray)
29
  fshift = np.fft.fftshift(f)
30
  magnitude_spectrum = np.abs(fshift)
31
+ high_freq_ratio = np.sum(magnitude_spectrum > 50) / magnitude_spectrum.size
32
+
33
+ # Metadata kamera
34
+ exif_data = img.getexif()
35
+ has_exif = len(exif_data) > 0
36
+
37
+ forensic_score = 0
38
+ if blur_var > 500: forensic_score += 20
39
+ if noise > 10: forensic_score += 20
40
+ if high_freq_ratio > 0.3: forensic_score += 20
41
+ if has_exif: forensic_score += 40
42
+
43
  return {
44
+ "blur": round(blur_var, 2),
45
+ "noise": round(noise, 2),
46
+ "high_freq_ratio": round(high_freq_ratio, 3),
47
+ "has_exif": has_exif,
48
+ "forensic_score": forensic_score
49
  }
50
 
51
+ # ===== 3. Fungsi Prediksi Gabungan =====
52
+ def detect_ai(image):
53
+ votes = []
54
+ scores = []
55
+
56
+ # Jalankan semua model
57
+ for det in detectors:
58
+ preds = det(image)
59
+ label = preds[0]['label'].lower()
60
+ score = preds[0]['score']
61
+
62
+ if "ai" in label or "fake" in label or "artificial" in label:
63
+ votes.append("AI")
64
+ else:
65
+ votes.append("Real")
66
+ scores.append(score)
67
+
68
+ # Analisis forensik
69
+ forensic = forensic_analysis(image)
70
+
71
+ # Voting
72
+ ai_votes = votes.count("AI")
73
+ real_votes = votes.count("Real")
74
+
75
+ if ai_votes > real_votes:
76
+ final = "AI"
77
+ elif real_votes > ai_votes:
78
+ final = "Real"
79
  else:
80
+ # Gunakan forensic sebagai tie-breaker
81
+ final = "Real" if forensic["forensic_score"] > 50 else "AI"
82
+
83
  return {
84
+ "Hasil Deteksi": final,
85
+ "Voting Model": votes,
86
+ "Confidence Scores": scores,
87
+ "Forensik": forensic
88
  }
89
 
90
+ # ===== 4. Gradio UI =====
91
+ demo = gr.Interface(
92
+ fn=detect_ai,
93
+ inputs=gr.Image(type="pil"),
94
+ outputs="json",
95
+ title="AI vs Real Image Detector (Ensemble + Forensic)",
96
+ description="Menggunakan 3 model publik + analisis forensik (blur, noise, frekuensi, metadata)."
97
+ )
98
+
99
  if __name__ == "__main__":
100
+ demo.launch()