error-ela / app.py
leonett's picture
Update app.py
205e25d verified
raw
history blame
4.85 kB
# -*- coding: utf-8 -*-
import cv2
import numpy as np
from PIL import Image
from PIL.ExifTags import TAGS
import os
from datetime import datetime
import tempfile
def obtener_metadatos(imagen):
"""
Obtiene los metadatos de la imagen.
"""
try:
exif_data = imagen._getexif()
if not exif_data:
return {}
return {TAGS.get(tag_id, tag_id): value for tag_id, value in exif_data.items()}
except Exception as e:
print(f"Error al obtener metadatos: {e}")
return {}
def realizar_ela(imagen, quality=95, scale=100):
"""
Realiza el Error Level Analysis (ELA) en la imagen.
"""
try:
imagen_cv = cv2.cvtColor(np.array(imagen), cv2.COLOR_RGB2BGR)
temp_path = "temp_image.jpg"
cv2.imwrite(temp_path, imagen_cv, [cv2.IMWRITE_JPEG_QUALITY, quality])
imagen_comprimida = cv2.imread(temp_path)
diferencia = cv2.absdiff(imagen_cv, imagen_comprimida)
ela_imagen = scale * diferencia
ela_imagen = cv2.cvtColor(ela_imagen, cv2.COLOR_BGR2GRAY)
os.remove(temp_path)
return ela_imagen
except Exception as e:
print(f"Error al realizar ELA: {e}")
return None
def analizar_manipulacion(imagen, ela_imagen):
"""
Analiza si la imagen ha sido manipulada usando ELA como referencia principal.
"""
manipulada = False
razones = []
# Validar análisis ELA
if ela_imagen is None:
razones.append("No se pudo realizar el análisis ELA.")
else:
promedio_ela = np.mean(ela_imagen)
if promedio_ela > 10: # Umbral basado en pruebas
razones.append("El análisis ELA sugiere posibles alteraciones. Esto podría deberse a ediciones o ajustes automáticos del dispositivo.")
manipulada = True
else:
razones.append("El análisis ELA no sugiere alteraciones.")
return manipulada, razones
def procesar_imagen(archivo_imagen):
try:
imagen = Image.open(archivo_imagen)
nombre_archivo = os.path.basename(archivo_imagen)
stats = os.stat(archivo_imagen)
tamaño_archivo = stats.st_size / 1024
fecha_creacion = datetime.fromtimestamp(stats.st_ctime).strftime('%Y-%m-%d %H:%M:%S')
fecha_modificacion = datetime.fromtimestamp(stats.st_mtime).strftime('%Y-%m-%d %H:%M:%S')
info_basica = f"""
Información básica de la imagen:
Nombre del archivo: {nombre_archivo}
Tamaño: {tamaño_archivo:.2f} KB
Fecha de creación: {fecha_creacion}
Fecha de modificación: {fecha_modificacion}
"""
# Obtener metadatos (mostrar si están disponibles)
metadatos = obtener_metadatos(imagen)
if metadatos:
metadatos_info = "\nMetadatos EXIF encontrados:\n"
for key, value in metadatos.items():
metadatos_info += f"- {key}: {value}\n"
else:
metadatos_info = "\nLa imagen no contiene metadatos EXIF (esto no implica manipulación)."
# Realizar ELA
ela_imagen = realizar_ela(imagen)
# Analizar manipulación basado en ELA
manipulada, razones = analizar_manipulacion(imagen, ela_imagen)
# Construir mensaje principal y detallado
if manipulada:
resultado_principal = "**Conclusión:** Se detectaron posibles alteraciones en la imagen.\n"
else:
resultado_principal = "**Conclusión:** No se detectaron alteraciones evidentes en la imagen.\n"
razones_detalle = "\nRazones del análisis:\n"
for razon in razones:
razones_detalle += f"- {razon}\n"
resultado_final = info_basica + metadatos_info + "\n" + resultado_principal + razones_detalle
if ela_imagen is not None:
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp_file:
cv2.imwrite(tmp_file.name, ela_imagen)
ela_image_path = tmp_file.name
return ela_image_path, resultado_final
else:
return None, resultado_final + "\n(No se generó ELA debido a un error técnico.)"
except Exception as e:
error_msg = f"Error procesando la imagen: {e}"
print(error_msg)
return None, error_msg
# Interfaz de GRADIO con un tema moderno
import gradio as gr
# Usar un tema moderno (por ejemplo, "huggingface")
iface = gr.Interface(
fn=procesar_imagen,
inputs=gr.Image(type="filepath", label="Sube una imagen"),
outputs=[gr.Image(label="Error Level Analysis (ELA)"), gr.Textbox(label="Resultado del análisis")],
title="Análisis de Manipulación de Imágenes",
description="Sube una imagen para analizar posibles manipulaciones usando principalmente ELA.",
theme="huggingface" # Tema moderno
)
# Lanzar la interfaz
iface.launch()