leonett commited on
Commit
a6ad3b3
·
verified ·
1 Parent(s): 1d904a9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +18 -23
app.py CHANGED
@@ -9,9 +9,6 @@ import logging
9
  from pathlib import Path
10
  from PIL import ExifTags
11
  import plotly.graph_objects as go
12
- import plotly.express as px
13
- import pandas as pd
14
- import io
15
 
16
  # Configuración de logs
17
  logging.basicConfig(level=logging.INFO)
@@ -79,7 +76,7 @@ def analizar_manipulacion(imagen, metadatos):
79
  manipulada = True
80
  return manipulada, razones
81
 
82
- def calcular_porcentaje_ela(ela_imagen, mask):
83
  if mask is None or mask.size == 0:
84
  return 0.0
85
  total_pixeles = mask.size
@@ -128,7 +125,8 @@ def realizar_ela(imagen):
128
  result = np.where(mask[:, :, None] > 0, mask_colored, background)
129
  result = cv2.convertScaleAbs(result, alpha=1.2, beta=10)
130
 
131
- os.remove(temp_path)
 
132
  return result, mask
133
 
134
  except Exception as e:
@@ -153,12 +151,12 @@ def crear_graficos_estadisticas(porcentaje_ela, dimensiones, metadatos):
153
  title=dict(text="<b>Porcentaje de Áreas Manipuladas</b>", x=0.5),
154
  yaxis_title="Porcentaje (%)",
155
  height=250,
156
- showlegend=False
 
157
  )
158
 
159
  # Gráfico 2: Probabilidad de manipulación (Pie)
160
  niveles = ['Muy baja', 'Baja', 'Moderada', 'Alta', 'Muy alta']
161
- valores = [0.5, 1.5, 3.5, 10, 20]
162
  color_map = ['#00CC96', '#36A2EB', '#FFCE56', '#FF9F40', '#FF6384']
163
 
164
  prob_index = 0
@@ -182,7 +180,8 @@ def crear_graficos_estadisticas(porcentaje_ela, dimensiones, metadatos):
182
  fig_pie.update_layout(
183
  title=dict(text="<b>Nivel de Probabilidad</b>", x=0.5),
184
  height=250,
185
- showlegend=False
 
186
  )
187
 
188
  # Gráfico 3: Distribución de píxeles (Box plot)
@@ -197,14 +196,15 @@ def crear_graficos_estadisticas(porcentaje_ela, dimensiones, metadatos):
197
  title=dict(text="<b>Distribución de Anomalías</b>", x=0.5),
198
  yaxis_title="Porcentaje (%)",
199
  height=250,
200
- showlegend=False
 
201
  )
202
 
203
  # Gráfico 4: Tendencias temporales (Scatter)
204
  fig_scatter = go.Figure()
205
  fig_scatter.add_trace(go.Scatter(
206
  x=['Compresión', 'Ruido', 'Manipulación'],
207
- y=[max(0, porcentaje_ela-1), max(0, porcentaje_ela-0.5), porcentaje_ela],
208
  mode='lines+markers',
209
  line=dict(color='#FF6B35', width=3),
210
  marker=dict(size=10)
@@ -212,17 +212,18 @@ def crear_graficos_estadisticas(porcentaje_ela, dimensiones, metadatos):
212
  fig_scatter.update_layout(
213
  title=dict(text="<b>Análisis de Componentes</b>", x=0.5),
214
  yaxis_title="Intensidad",
215
- height=250
 
216
  )
217
 
218
  return fig_bar, fig_pie, fig_box, fig_scatter
219
 
220
  def procesar_imagen(archivo_imagen):
221
  if not archivo_imagen:
222
- return None, "❌ **ERROR: Por favor, cargue una imagen antes de analizar.**", None, "", None, None, None, None
223
 
224
  if not os.path.exists(archivo_imagen):
225
- return None, "❌ **ERROR: El archivo de imagen no existe o es inválido.**", None, "", None, None, None, None
226
 
227
  try:
228
  img = Image.open(archivo_imagen)
@@ -236,7 +237,7 @@ def procesar_imagen(archivo_imagen):
236
  text_path = os.path.join(evidence_dir, f"{nombre}_analisis.txt")
237
  zip_path = os.path.join(evidence_dir, f"{nombre}_errorELA.zip")
238
 
239
- img.save(original_path)
240
  ela_result, mask = realizar_ela(img)
241
 
242
  if mask is None:
@@ -244,7 +245,7 @@ def procesar_imagen(archivo_imagen):
244
 
245
  cv2.imwrite(ela_path, ela_result)
246
 
247
- porcentaje_ela = calcular_porcentaje_ela(ela_result, mask)
248
  probabilidad = estimar_probabilidad_manipulacion(porcentaje_ela)
249
 
250
  # Crear gráficos estadísticos
@@ -322,14 +323,14 @@ def procesar_imagen(archivo_imagen):
322
 
323
  ela_rgb = cv2.cvtColor(ela_result, cv2.COLOR_BGR2RGB)
324
 
325
- return zip_path, analysis_text, ela_rgb, google_maps_url or "", fig_bar, fig_pie, fig_box, fig_scatter
326
 
327
  except Exception as e:
328
  logger.error(f"Error en procesamiento: {str(e)}")
329
  mensaje_error = f"❌ **ERROR CRÍTICO:** {str(e)}"
330
  error_img = np.zeros((300, 600, 3), dtype=np.uint8)
331
  cv2.putText(error_img, "ERROR INTERNO", (80, 160), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
332
- return None, mensaje_error, error_img, "", None, None, None, None
333
 
334
  # 🎨 Tema moderno
335
  theme = gr.themes.Soft(primary_hue="blue", secondary_hue="slate", neutral_hue="stone")
@@ -347,12 +348,6 @@ with gr.Blocks(title="Análisis Forense de Imágenes con ELA", theme=theme, css=
347
  transform: scale(1.02) !important;
348
  box-shadow: 0 4px 12px rgba(255, 107, 53, 0.3) !important;
349
  }
350
- .stats-container {
351
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
352
- padding: 10px;
353
- border-radius: 10px;
354
- margin: 5px;
355
- }
356
  .equal-height {
357
  height: 400px !important;
358
  }
 
9
  from pathlib import Path
10
  from PIL import ExifTags
11
  import plotly.graph_objects as go
 
 
 
12
 
13
  # Configuración de logs
14
  logging.basicConfig(level=logging.INFO)
 
76
  manipulada = True
77
  return manipulada, razones
78
 
79
+ def calcular_porcentaje_ela(mask):
80
  if mask is None or mask.size == 0:
81
  return 0.0
82
  total_pixeles = mask.size
 
125
  result = np.where(mask[:, :, None] > 0, mask_colored, background)
126
  result = cv2.convertScaleAbs(result, alpha=1.2, beta=10)
127
 
128
+ if os.path.exists(temp_path):
129
+ os.remove(temp_path)
130
  return result, mask
131
 
132
  except Exception as e:
 
151
  title=dict(text="<b>Porcentaje de Áreas Manipuladas</b>", x=0.5),
152
  yaxis_title="Porcentaje (%)",
153
  height=250,
154
+ showlegend=False,
155
+ margin=dict(l=20, r=20, t=40, b=20)
156
  )
157
 
158
  # Gráfico 2: Probabilidad de manipulación (Pie)
159
  niveles = ['Muy baja', 'Baja', 'Moderada', 'Alta', 'Muy alta']
 
160
  color_map = ['#00CC96', '#36A2EB', '#FFCE56', '#FF9F40', '#FF6384']
161
 
162
  prob_index = 0
 
180
  fig_pie.update_layout(
181
  title=dict(text="<b>Nivel de Probabilidad</b>", x=0.5),
182
  height=250,
183
+ showlegend=False,
184
+ margin=dict(l=20, r=20, t=40, b=20)
185
  )
186
 
187
  # Gráfico 3: Distribución de píxeles (Box plot)
 
196
  title=dict(text="<b>Distribución de Anomalías</b>", x=0.5),
197
  yaxis_title="Porcentaje (%)",
198
  height=250,
199
+ showlegend=False,
200
+ margin=dict(l=20, r=20, t=40, b=20)
201
  )
202
 
203
  # Gráfico 4: Tendencias temporales (Scatter)
204
  fig_scatter = go.Figure()
205
  fig_scatter.add_trace(go.Scatter(
206
  x=['Compresión', 'Ruido', 'Manipulación'],
207
+ y=[max(0.1, porcentaje_ela-1), max(0.1, porcentaje_ela-0.5), max(0.1, porcentaje_ela)],
208
  mode='lines+markers',
209
  line=dict(color='#FF6B35', width=3),
210
  marker=dict(size=10)
 
212
  fig_scatter.update_layout(
213
  title=dict(text="<b>Análisis de Componentes</b>", x=0.5),
214
  yaxis_title="Intensidad",
215
+ height=250,
216
+ margin=dict(l=20, r=20, t=40, b=20)
217
  )
218
 
219
  return fig_bar, fig_pie, fig_box, fig_scatter
220
 
221
  def procesar_imagen(archivo_imagen):
222
  if not archivo_imagen:
223
+ return [None, "❌ **ERROR: Por favor, cargue una imagen antes de analizar.**", None, ""] + [None] * 4
224
 
225
  if not os.path.exists(archivo_imagen):
226
+ return [None, "❌ **ERROR: El archivo de imagen no existe o es inválido.**", None, ""] + [None] * 4
227
 
228
  try:
229
  img = Image.open(archivo_imagen)
 
237
  text_path = os.path.join(evidence_dir, f"{nombre}_analisis.txt")
238
  zip_path = os.path.join(evidence_dir, f"{nombre}_errorELA.zip")
239
 
240
+ img.save(original_path, "JPEG")
241
  ela_result, mask = realizar_ela(img)
242
 
243
  if mask is None:
 
245
 
246
  cv2.imwrite(ela_path, ela_result)
247
 
248
+ porcentaje_ela = calcular_porcentaje_ela(mask)
249
  probabilidad = estimar_probabilidad_manipulacion(porcentaje_ela)
250
 
251
  # Crear gráficos estadísticos
 
323
 
324
  ela_rgb = cv2.cvtColor(ela_result, cv2.COLOR_BGR2RGB)
325
 
326
+ return [zip_path, analysis_text, ela_rgb, google_maps_url or "", fig_bar, fig_pie, fig_box, fig_scatter]
327
 
328
  except Exception as e:
329
  logger.error(f"Error en procesamiento: {str(e)}")
330
  mensaje_error = f"❌ **ERROR CRÍTICO:** {str(e)}"
331
  error_img = np.zeros((300, 600, 3), dtype=np.uint8)
332
  cv2.putText(error_img, "ERROR INTERNO", (80, 160), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
333
+ return [None, mensaje_error, error_img, ""] + [None] * 4
334
 
335
  # 🎨 Tema moderno
336
  theme = gr.themes.Soft(primary_hue="blue", secondary_hue="slate", neutral_hue="stone")
 
348
  transform: scale(1.02) !important;
349
  box-shadow: 0 4px 12px rgba(255, 107, 53, 0.3) !important;
350
  }
 
 
 
 
 
 
351
  .equal-height {
352
  height: 400px !important;
353
  }