leonett commited on
Commit
34b96fe
·
verified ·
1 Parent(s): 78ac94b

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -163
app.py DELETED
@@ -1,163 +0,0 @@
1
- import gradio as gr
2
- import cv2
3
- import os
4
- import zipfile
5
- from PIL import Image, ImageOps
6
- from datetime import datetime
7
- import hashlib
8
-
9
- def procesar_video(video):
10
- try:
11
- video_path = video
12
- original_name = os.path.basename(video_path)
13
-
14
- timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
15
- temp_dir = f"temp_{datetime.now().strftime('%Y%m%d%H%M%S')}"
16
- os.makedirs(temp_dir, exist_ok=True)
17
-
18
- # Extracción de todos los fotogramas
19
- from moviepy.editor import VideoFileClip
20
- clip = VideoFileClip(video_path)
21
- frame_count = int(clip.fps * clip.duration)
22
- frame_paths = []
23
- for i, frame in enumerate(clip.iter_frames()):
24
- img = Image.fromarray(frame)
25
- img_path = os.path.join(temp_dir, f"frame_{i:04d}.jpg")
26
- img.save(img_path)
27
- frame_paths.append(img_path)
28
- clip.close()
29
-
30
- if frame_count == 0:
31
- raise gr.Error("No se pudieron extraer fotogramas del video")
32
-
33
- # Selección estratégica de 4 fotogramas equidistantes
34
- n_seleccion = 4
35
- step = max(1, frame_count // (n_seleccion + 1))
36
- selected_indices = [step * (i+1) for i in range(n_seleccion)]
37
- selected_frames = [frame_paths[min(i, len(frame_paths)-1)] for i in selected_indices]
38
-
39
- # Creación de collage profesional
40
- images = []
41
- for img_path in selected_frames:
42
- img = Image.open(img_path)
43
- bordered_img = ImageOps.expand(img, border=2, fill='white') # Borde blanco
44
- images.append(bordered_img)
45
-
46
- # Configuración del diseño
47
- img_w, img_h = images[0].size
48
- margin = 30
49
- border_size = 20
50
- shadow_offset = 5
51
-
52
- collage_width = (img_w * 2) + margin + (border_size * 2)
53
- collage_height = (img_h * 2) + margin + (border_size * 2)
54
-
55
- collage = Image.new('RGB',
56
- (collage_width, collage_height),
57
- (230, 230, 230)) # Fondo gris claro
58
-
59
- # Posiciones con efecto de profundidad
60
- positions = [
61
- (border_size, border_size),
62
- (border_size + img_w + margin, border_size),
63
- (border_size, border_size + img_h + margin),
64
- (border_size + img_w + margin, border_size + img_h + margin)
65
- ]
66
-
67
- # Pegar imágenes con sombra
68
- for i, img in enumerate(images):
69
- # Sombra
70
- shadow = Image.new('RGBA', (img_w + shadow_offset, img_h + shadow_offset), (0,0,0,50))
71
- collage.paste(shadow, (positions[i][0]+shadow_offset, positions[i][1]+shadow_offset), shadow)
72
-
73
- # Imagen principal
74
- collage.paste(img, positions[i])
75
-
76
- collage_path = os.path.join(temp_dir, "collage_forense.jpg")
77
- collage.save(collage_path, quality=95, dpi=(300, 300))
78
-
79
- # Generación del ZIP con cadena de custodia
80
- base_name = os.path.splitext(original_name)[0]
81
- zip_filename = f"{base_name}_Fotogramas.zip"
82
- final_zip_path = os.path.join(temp_dir, zip_filename)
83
-
84
- with zipfile.ZipFile(final_zip_path, mode="w") as zipf:
85
- # Añadir todos los frames
86
- for img_path in frame_paths:
87
- zipf.write(img_path, os.path.basename(img_path))
88
-
89
- # Archivo TXT con formato profesional
90
- with open(video_path, "rb") as f:
91
- video_hash = hashlib.md5(f.read()).hexdigest()
92
-
93
- chain_content = (
94
- "=== CADENA DE CUSTODIA DIGITAL ===\r\n\r\n"
95
- f"• Archivo original: {original_name}\r\n"
96
- f"• Fecha de procesamiento: {timestamp}\r\n"
97
- f"• Fotogramas totales: {frame_count}\r\n"
98
- f"• Hash MD5 video: {video_hash}\r\n"
99
- f"• Fotogramas muestra: {', '.join([f'#{i+1}' for i in selected_indices])}\r\n\r\n"
100
- "Este documento certifica la integridad del proceso de extracción.\n"
101
- "Sistema Certificado por Peritos Forenses Digitales de Guatemala. \n"
102
- "www.forensedigital.gt"
103
- )
104
- zipf.writestr("00_CADENA_CUSTODIA.txt", chain_content)
105
-
106
- return collage_path, final_zip_path, temp_dir
107
-
108
- except Exception as e:
109
- raise gr.Error(f"Error en procesamiento: {str(e)}")
110
-
111
- def limpiar_cache(temp_dir):
112
- if temp_dir and os.path.exists(temp_dir):
113
- for file in os.listdir(temp_dir):
114
- os.remove(os.path.join(temp_dir, file))
115
- os.rmdir(temp_dir)
116
-
117
- with gr.Blocks(title="Extractior Forense de Fotogramas") as demo:
118
- gr.Markdown("# 📷 Extractor Forense de Fotogramas de Videos")
119
- gr.Markdown("**Herramienta certificada para extracción forense de fotogramas de videos** (No se guarda ninguna información). Soporta todos los formatos de video compatibles con OpenCV/FFmpeg.")
120
- gr.Markdown("Desarrollado por José R. Leonett para el Grupo de Peritos Forenses Digitales de Guatemala - [www.forensedigital.gt](https://www.forensedigital.gt)")
121
-
122
- with gr.Row():
123
- with gr.Column():
124
- video_input = gr.Video(
125
- label="CARGAR VIDEO",
126
- sources=["upload"],
127
- format="",
128
- interactive=True
129
- )
130
- procesar_btn = gr.Button("🔍 INICIAR ANÁLISIS", interactive=False)
131
- with gr.Column():
132
- # gr.Markdown("## Resultados:")
133
- gallery_output = gr.Image(label="COLLAGE DE REFERENCIA", height=400)
134
- download_file = gr.File(label="DESCARGAR EVIDENCIAS", visible=True)
135
-
136
- temp_dir_state = gr.State()
137
- zip_path_state = gr.State()
138
-
139
- def habilitar_procesado(video):
140
- return gr.update(interactive=True) if video else gr.update(interactive=False)
141
-
142
- video_input.change(
143
- fn=habilitar_procesado,
144
- inputs=video_input,
145
- outputs=procesar_btn,
146
- queue=False
147
- )
148
-
149
- def procesar_y_mostrar(video):
150
- if temp_dir_state.value:
151
- limpiar_cache(temp_dir_state.value)
152
- collage, zip_path, temp_dir = procesar_video(video)
153
- return collage, zip_path, temp_dir, zip_path
154
-
155
- procesar_btn.click(
156
- fn=procesar_y_mostrar,
157
- inputs=video_input,
158
- outputs=[gallery_output, download_file, temp_dir_state, zip_path_state]
159
- )
160
-
161
- if __name__ == "__main__":
162
- demo.queue()
163
- demo.launch(server_name="0.0.0.0", server_port=7860)