NOBODY204 commited on
Commit
ce97a4a
ยท
verified ยท
1 Parent(s): c1906a4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -40
app.py CHANGED
@@ -4,97 +4,114 @@ import cv2
4
  import matplotlib.pyplot as plt
5
  from PIL import Image, ImageChops, ImageEnhance
6
  from scipy import ndimage
7
- import io, json, warnings
8
 
9
  warnings.filterwarnings("ignore")
10
 
11
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
12
- # ๐Ÿ›ก๏ธ MEDIASHIELD X IMAGESHIELD (FUSION v3.0)
13
- # Calibration spรฉciale : Archives & Mode Sombre
14
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
15
 
16
  def apply_gamma_correction(img):
17
- """Prรฉpare l'image pour l'analyse si elle est trop sombre."""
18
  gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
19
  brightness = np.mean(gray)
20
  if brightness < 65:
21
- # Correction pour rรฉvรฉler les artefacts de compression dans l'ombre
22
  gamma = 0.6
23
  invGamma = 1.0 / gamma
24
  table = np.array([((i / 255.0) ** invGamma) * 255 for i in np.arange(0, 256)]).astype("uint8")
25
  return cv2.LUT(img, table), f"๐ŸŒ™ Mode Sombre (Lumiรจre: {brightness:.1f})"
26
  return img, "โ˜€๏ธ Lumiรจre Standard"
27
 
 
 
 
 
 
 
 
 
 
 
28
  def analyze_forensics(img_input):
29
- if img_input is None: return None, "โŒ Aucune image"
30
 
31
- # 1. Prรฉparation (Correction de lumiรจre S2T)
32
  img_cv = cv2.cvtColor(img_input, cv2.COLOR_RGBA2RGB) if img_input.shape[2] == 4 else img_input.copy()
33
  img_ready, light_msg = apply_gamma_correction(img_cv)
34
  pil_img = Image.fromarray(img_ready)
35
 
36
- # 2. Analyse de Chrominance (Signatures Nano Banana)
 
 
 
37
  ycrcb = cv2.cvtColor(img_ready, cv2.COLOR_RGB2YCrCb)
38
  cr_var = ndimage.generic_filter(ycrcb[:,:,1], np.var, size=5)
39
- chroma_score = np.std(cr_var) / (np.mean(cr_var) + 1e-8)
40
 
41
- # 3. FFT & Grid Patterns (Signatures GAN/Diffusion)
42
- gray = cv2.cvtColor(img_ready, cv2.COLOR_RGB2GRAY).astype(np.float32)
43
- f_shift = np.fft.fftshift(np.fft.fft2(gray))
44
- magnitude = np.abs(f_shift)
45
- fft_vis = np.log(magnitude + 1)
46
 
47
- # 4. ELA (Error Level Analysis)
48
- quality = 90
49
  buf = io.BytesIO()
50
- pil_img.save(buf, format="JPEG", quality=quality)
51
  recomp = Image.open(io.BytesIO(buf.getvalue())).convert("RGB")
52
  ela_diff = ImageChops.difference(pil_img, recomp)
53
  ela_vis = ImageEnhance.Brightness(ela_diff).enhance(10)
54
 
55
- # 5. Calcul du Score Final
56
  score = 0
57
  reasons = []
58
- if chroma_score < 0.9:
59
- score += 35
60
- reasons.append("โš ๏ธ Bruit chromatique trop uniforme (Typique IA)")
61
- if np.std(magnitude) > 100000: # Seuil simplifiรฉ
 
 
 
 
 
62
  score += 30
63
- reasons.append("๐Ÿ”ฎ Artefacts de frรฉquence dรฉtectรฉs (FFT)")
 
64
  if np.mean(np.array(ela_diff)) < 1.2:
65
- score += 25
66
  reasons.append("๐Ÿ” Compression suspecte (ELA trop lisse)")
67
 
68
- final_verdict = "๐Ÿ”ด TRรˆS PROBABLEMENT IA" if score > 60 else "๐ŸŸข PROBABLEMENT Rร‰EL"
 
 
69
 
70
- # Visualisation
71
  fig, axes = plt.subplots(1, 3, figsize=(15, 5))
72
  axes[0].imshow(img_cv); axes[0].set_title(f'Original ({light_msg})')
73
- axes[1].imshow(fft_vis, cmap='viridis'); axes[1].set_title('Frรฉquences (FFT)')
74
- axes[2].imshow(ela_vis); axes[2].set_title('Analyse ELA')
75
  for ax in axes: ax.axis('off')
 
76
 
77
- report = f"๐Ÿ›ก๏ธ MEDIASHIELD v3.0\nVERDICT: {final_verdict}\nScore: {score}/100\n\n{light_msg}\n\n" + "\n".join(reasons)
78
  return fig, report
79
 
80
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
81
- # UI Ariana Edition
82
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
83
 
84
  with gr.Blocks(title="MediaShield v3.0", theme=gr.themes.Soft()) as demo:
85
- gr.Markdown("# ๐Ÿ›ก๏ธ MediaShield v3.0 โ€” Forensic Archive Suite")
86
- gr.Markdown("Fusion du moteur ImageShield et du correcteur optique MediaShield.")
87
 
88
  with gr.Row():
89
- with gr.Column():
90
- input_file = gr.Image(label="Dรฉpรดt d'archive numรฉrique", type="numpy")
91
- run_btn = gr.Button("Dร‰MARRER L'ANALYSE FORENSIC", variant="primary")
92
- with gr.Column():
93
- output_plot = gr.Plot(label="Cartographie des signaux")
94
- output_text = gr.Textbox(label="Rapport d'expertise S2T", lines=8)
95
 
96
  run_btn.click(analyze_forensics, inputs=input_file, outputs=[output_plot, output_text])
97
 
98
  if __name__ == "__main__":
99
- demo.launch()
100
-
 
4
  import matplotlib.pyplot as plt
5
  from PIL import Image, ImageChops, ImageEnhance
6
  from scipy import ndimage
7
+ import io, warnings
8
 
9
  warnings.filterwarnings("ignore")
10
 
11
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
12
+ # ๐Ÿ›ก๏ธ MEDIASHIELD v3.0 โ€” ARCHIVE & FORENSIC SUITE
 
13
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
14
 
15
  def apply_gamma_correction(img):
16
+ """Prรฉpare l'image pour l'analyse si elle est trop sombre (Archives)."""
17
  gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
18
  brightness = np.mean(gray)
19
  if brightness < 65:
 
20
  gamma = 0.6
21
  invGamma = 1.0 / gamma
22
  table = np.array([((i / 255.0) ** invGamma) * 255 for i in np.arange(0, 256)]).astype("uint8")
23
  return cv2.LUT(img, table), f"๐ŸŒ™ Mode Sombre (Lumiรจre: {brightness:.1f})"
24
  return img, "โ˜€๏ธ Lumiรจre Standard"
25
 
26
+ def verify_natural_grain(img):
27
+ """Distingue le lissage IA du grain organique d'une photo rรฉelle."""
28
+ gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
29
+ local_var = ndimage.generic_filter(gray, np.var, size=3)
30
+ avg_var = np.mean(local_var)
31
+ # Un score trรจs bas (< 0.8) indique une texture mathรฉmatiquement 'trop' parfaite (IA)
32
+ if avg_var < 0.8:
33
+ return True, avg_var
34
+ return False, avg_var
35
+
36
  def analyze_forensics(img_input):
37
+ if img_input is None: return None, "โŒ Aucune image chargรฉe."
38
 
39
+ # 1. Nettoyage et Correction Gamma
40
  img_cv = cv2.cvtColor(img_input, cv2.COLOR_RGBA2RGB) if img_input.shape[2] == 4 else img_input.copy()
41
  img_ready, light_msg = apply_gamma_correction(img_cv)
42
  pil_img = Image.fromarray(img_ready)
43
 
44
+ # 2. Analyse du Grain (Anti-Faux Positifs Archives)
45
+ is_too_smooth, grain_val = verify_natural_grain(img_ready)
46
+
47
+ # 3. Analyse de Chrominance (Signatures Couleurs IA)
48
  ycrcb = cv2.cvtColor(img_ready, cv2.COLOR_RGB2YCrCb)
49
  cr_var = ndimage.generic_filter(ycrcb[:,:,1], np.var, size=5)
50
+ chroma_uniformity = np.std(cr_var) / (np.mean(cr_var) + 1e-8)
51
 
52
+ # 4. FFT (Recherche de motifs de grille IA)
53
+ gray_f = cv2.cvtColor(img_ready, cv2.COLOR_RGB2GRAY).astype(np.float32)
54
+ f_shift = np.fft.fftshift(np.fft.fft2(gray_f))
55
+ fft_vis = np.log(np.abs(f_shift) + 1)
 
56
 
57
+ # 5. ELA (Error Level Analysis)
 
58
  buf = io.BytesIO()
59
+ pil_img.save(buf, format="JPEG", quality=90)
60
  recomp = Image.open(io.BytesIO(buf.getvalue())).convert("RGB")
61
  ela_diff = ImageChops.difference(pil_img, recomp)
62
  ela_vis = ImageEnhance.Brightness(ela_diff).enhance(10)
63
 
64
+ # 6. Systรจme de Score S2T Ariana
65
  score = 0
66
  reasons = []
67
+
68
+ if is_too_smooth:
69
+ score += 25
70
+ reasons.append(f"โšก Texture suspecte (Grain trop faible: {grain_val:.2f})")
71
+ else:
72
+ score -= 10
73
+ reasons.append("โœ… Grain organique dรฉtectรฉ (Photo rรฉelle)")
74
+
75
+ if chroma_uniformity < 0.9:
76
  score += 30
77
+ reasons.append("โš ๏ธ Bruit chromatique uniforme (Signature IA)")
78
+
79
  if np.mean(np.array(ela_diff)) < 1.2:
80
+ score += 20
81
  reasons.append("๐Ÿ” Compression suspecte (ELA trop lisse)")
82
 
83
+ # Bornage du score
84
+ score = max(0, min(100, score))
85
+ verdict = "๐Ÿ”ด IA Dร‰TECTร‰E" if score > 55 else "๐ŸŸ  SUSPECT" if score > 35 else "๐ŸŸข AUTHENTIQUE"
86
 
87
+ # Visualisation des preuves
88
  fig, axes = plt.subplots(1, 3, figsize=(15, 5))
89
  axes[0].imshow(img_cv); axes[0].set_title(f'Original ({light_msg})')
90
+ axes[1].imshow(fft_vis, cmap='magma'); axes[1].set_title('Spectre Frรฉquence (FFT)')
91
+ axes[2].imshow(ela_vis); axes[2].set_title('Analyse ELA (Compression)')
92
  for ax in axes: ax.axis('off')
93
+ plt.tight_layout()
94
 
95
+ report = f"๐Ÿ›ก๏ธ RAPPORT MEDIASHIELD v3.0\nVERDICT : {verdict}\nIndice de confiance IA : {score}/100\n\nDiagnostic :\n" + "\n".join(reasons)
96
  return fig, report
97
 
98
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
99
+ # INTERFACE UTILISATEUR (GRADIO)
100
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
101
 
102
  with gr.Blocks(title="MediaShield v3.0", theme=gr.themes.Soft()) as demo:
103
+ gr.Markdown("# ๐Ÿ›ก๏ธ MediaShield v3.0")
104
+ gr.Markdown("**Expertise Forensic S2T** : Dรฉtection IA, analyse de grain et correction d'archives.")
105
 
106
  with gr.Row():
107
+ with gr.Column(scale=1):
108
+ input_file = gr.Image(label="Charger une image (Photo ou Archive)", type="numpy")
109
+ run_btn = gr.Button("LANCER L'ANALYSE", variant="primary")
110
+ with gr.Column(scale=2):
111
+ output_plot = gr.Plot(label="Preuves visuelles")
112
+ output_text = gr.Textbox(label="Rapport d'expertise", lines=10)
113
 
114
  run_btn.click(analyze_forensics, inputs=input_file, outputs=[output_plot, output_text])
115
 
116
  if __name__ == "__main__":
117
+ demo.launch()