|
|
|
|
|
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 = [] |
|
|
|
|
|
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: |
|
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} |
|
""" |
|
|
|
|
|
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)." |
|
|
|
|
|
ela_imagen = realizar_ela(imagen) |
|
|
|
|
|
manipulada, razones = analizar_manipulacion(imagen, ela_imagen) |
|
|
|
|
|
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 |
|
|
|
|
|
import gradio as gr |
|
|
|
|
|
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=" 🔍 Error Level Analysis (ELA)", |
|
description="Este programa diseñado por José R. Leonett es para analizar imágenes en busqueda de manipulación utilizando la técnica de Error Level Analysis (ELA). Creado para el grupo de Peritos Forenses Digitales de Guatemala [www.forensedigital.gt](https://www.forensedigital.gt).", |
|
theme="huggingface" |
|
) |
|
|
|
|
|
iface.launch() |