EU-IA commited on
Commit
7d6ac50
·
verified ·
1 Parent(s): 66617c2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +36 -30
app.py CHANGED
@@ -1,4 +1,4 @@
1
- #--- START OF FILE app.py ---
2
 
3
  import gradio as gr
4
  import cv2
@@ -8,7 +8,7 @@ import matplotlib.pyplot as plt
8
  from PIL import Image
9
  import imagehash
10
  import torch
11
- from scipy.stats import pearsonr
12
  import os
13
 
14
  # --- MÓDULO DE INICIALIZAÇÃO ---
@@ -36,9 +36,8 @@ except Exception as e:
36
 
37
  # --- FUNÇÕES DE ANÁLISE ---
38
 
39
- # --- MODIFICADO ---
40
- # Agora aceita start_frame e end_frame para analisar apenas um trecho.
41
  def analisar_fidelidade(video_path, start_frame=0, end_frame=0):
 
42
  cap = cv2.VideoCapture(video_path)
43
  if not cap.isOpened():
44
  raise gr.Error("Não foi possível abrir o arquivo de vídeo.")
@@ -47,7 +46,7 @@ def analisar_fidelidade(video_path, start_frame=0, end_frame=0):
47
  fps = cap.get(cv2.CAP_PROP_FPS) or 30
48
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
49
 
50
- # Valida e ajusta os frames de início e fim
51
  process_full_video = (start_frame == 0 and end_frame == 0) or (start_frame >= end_frame)
52
 
53
  if process_full_video:
@@ -160,15 +159,13 @@ def executar_teste_semantico(phash_distances, descriptions_text):
160
  # (Função como definida anteriormente)
161
  return None, "Função ainda não implementada completamente no template"
162
 
163
- # --- NOVA FUNÇÃO ---
164
- # Extrai frames de um trecho e os une em uma única imagem.
165
  def extrair_e_visualizar_frames(video_path, start_frame, end_frame):
 
166
  if not video_path or start_frame >= end_frame:
167
  return None
168
 
169
  cap = cv2.VideoCapture(video_path)
170
- if not cap.isOpened():
171
- return None
172
 
173
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
174
  start_frame = max(0, start_frame)
@@ -176,27 +173,41 @@ def extrair_e_visualizar_frames(video_path, start_frame, end_frame):
176
 
177
  cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
178
 
179
- extracted_frames = []
180
  for i in range(start_frame, end_frame):
181
  ret, frame = cap.read()
182
- if not ret:
183
- break
184
- # Adiciona texto com o número do frame
185
  frame_num_text = f"Frame: {i}"
186
  cv2.putText(frame, frame_num_text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA)
187
- extracted_frames.append(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
188
 
189
  cap.release()
 
190
 
191
- if not extracted_frames:
192
- return None
 
 
193
 
194
- # Une os frames horizontalmente
195
- combined_image = np.hstack(extracted_frames)
 
 
 
 
 
 
 
 
 
 
 
196
 
197
- # Salva a imagem combinada em um arquivo temporário
198
  pil_img = Image.fromarray(combined_image)
199
- path = "frames_extraidos.png"
200
  pil_img.save(path)
201
  return path
202
 
@@ -246,14 +257,13 @@ def gerar_grafico_foco(ssim_global, ssim_foco, jitter, num_frames, fps):
246
  return plot_to_file(fig, "foco")
247
 
248
 
249
- # --- FUNÇÃO DE CALLBACK PRINCIPAL (MODIFICADA) ---
250
  def run_full_analysis(video_path, descriptions_text, start_frame, end_frame, progress=gr.Progress()):
251
  if video_path is None: raise gr.Error("Por favor, faça o upload de um vídeo.")
252
 
253
- # Converte para inteiros
254
  start_frame, end_frame = int(start_frame), int(end_frame)
255
 
256
- progress(0, desc="Extraindo frames para visualização...")
257
  frames_imagem_path = extrair_e_visualizar_frames(video_path, start_frame, end_frame)
258
 
259
  progress(0.1, desc="Analisando fidelidade do trecho...")
@@ -283,10 +293,9 @@ def run_full_analysis(video_path, descriptions_text, start_frame, end_frame, pro
283
  if error_msg: gr.Warning(error_msg)
284
 
285
  progress(1.0, desc="Análise completa!")
286
- # --- MODIFICADO --- Retorna o caminho da nova imagem de frames também
287
  return frames_imagem_path, fidelidade_plot_path, cor_plot_path, foco_plot_path, semantico_path, anomalias_plot_path
288
 
289
- # --- INTERFACE GRADIO (MODIFICADA) ---
290
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
291
  gr.Markdown("# Suíte de Validação Completa para Geração de Vídeo (ADUC-SDR)")
292
  with gr.Row():
@@ -294,7 +303,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
294
  video_input = gr.Video(label="1. Upload do vídeo")
295
  descriptions_input = gr.Textbox(lines=5, label="3. Descrições (Opcional)", placeholder="Uma descrição por cena para o teste de inteligência...")
296
 
297
- # --- NOVOS COMPONENTES ---
298
  with gr.Row():
299
  start_frame_input = gr.Number(label="Frame Inicial", value=0, precision=0, info="Deixe 0 e 0 para analisar o vídeo inteiro.")
300
  end_frame_input = gr.Number(label="Frame Final", value=0, precision=0, info="Ex: 88 e 94 para analisar esse trecho.")
@@ -302,9 +310,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
302
  analyze_button = gr.Button("4. Executar Análise Completa", variant="primary")
303
 
304
  with gr.Tabs():
305
- # --- NOVA ABA ---
306
  with gr.TabItem("Frames Extraídos"):
307
- extracted_frames_img = gr.Image(label="Visualização dos Frames Lado a Lado")
308
  with gr.TabItem("1. Fidelidade e Coerência"):
309
  plot_fidelidade = gr.Image(label="Gráfico de Análise de Fidelidade (SSIM e pHash)")
310
  with gr.TabItem("2. Cor e Iluminação"):
@@ -316,11 +323,10 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
316
  with gr.TabItem("5. Inteligência Adaptativa"):
317
  plot_semantico = gr.Image(label="Gráfico de Estresse Semântico")
318
 
319
- # --- MODIFICADO --- Atualiza inputs e outputs do botão
320
  analyze_button.click(
321
  fn=run_full_analysis,
322
  inputs=[video_input, descriptions_input, start_frame_input, end_frame_input],
323
- outputs=[extracted_frames_img, plot_fidelidade, plot_cor, plot_foco, plot_semantico, plot_anomalias]
324
  )
325
 
326
  if __name__ == "__main__":
 
1
+ --- START OF FILE app.py ---
2
 
3
  import gradio as gr
4
  import cv2
 
8
  from PIL import Image
9
  import imagehash
10
  import torch
11
+ import collections # Adicionado para a nova lógica de visualização
12
  import os
13
 
14
  # --- MÓDULO DE INICIALIZAÇÃO ---
 
36
 
37
  # --- FUNÇÕES DE ANÁLISE ---
38
 
 
 
39
  def analisar_fidelidade(video_path, start_frame=0, end_frame=0):
40
+ """Lê um trecho do vídeo e calcula as métricas de fidelidade (SSIM, pHash)."""
41
  cap = cv2.VideoCapture(video_path)
42
  if not cap.isOpened():
43
  raise gr.Error("Não foi possível abrir o arquivo de vídeo.")
 
46
  fps = cap.get(cv2.CAP_PROP_FPS) or 30
47
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
48
 
49
+ # Valida e ajusta os frames de início e fim. Se inválido, analisa o vídeo todo.
50
  process_full_video = (start_frame == 0 and end_frame == 0) or (start_frame >= end_frame)
51
 
52
  if process_full_video:
 
159
  # (Função como definida anteriormente)
160
  return None, "Função ainda não implementada completamente no template"
161
 
 
 
162
  def extrair_e_visualizar_frames(video_path, start_frame, end_frame):
163
+ """Extrai frames de um trecho e os organiza em uma grade alinhada a múltiplos de 8."""
164
  if not video_path or start_frame >= end_frame:
165
  return None
166
 
167
  cap = cv2.VideoCapture(video_path)
168
+ if not cap.isOpened(): return None
 
169
 
170
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
171
  start_frame = max(0, start_frame)
 
173
 
174
  cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
175
 
176
+ extracted_frames, frame_shape = {}, None
177
  for i in range(start_frame, end_frame):
178
  ret, frame = cap.read()
179
+ if not ret: break
180
+ if frame_shape is None: frame_shape = frame.shape
181
+
182
  frame_num_text = f"Frame: {i}"
183
  cv2.putText(frame, frame_num_text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA)
184
+ extracted_frames[i] = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
185
 
186
  cap.release()
187
+ if not extracted_frames: return None
188
 
189
+ # Cria um frame preto para usar como preenchimento
190
+ h, w, c = frame_shape
191
+ black_frame = np.zeros((h, w, c), dtype=np.uint8)
192
+ cv2.putText(black_frame, "VAZIO", (w//2 - 50, h//2), cv2.FONT_HERSHEY_SIMPLEX, 1, (100, 100, 100), 2)
193
 
194
+ # Determina o início e o fim da grade, alinhados a múltiplos de 8
195
+ grid_start = (start_frame // 8) * 8
196
+ grid_end = ((end_frame - 1) // 8 + 1) * 8
197
+
198
+ # Preenche um dicionário com os frames reais ou de preenchimento
199
+ rows_dict = collections.defaultdict(list)
200
+ for i in range(grid_start, grid_end):
201
+ row_index = i // 8
202
+ rows_dict[row_index].append(extracted_frames.get(i, black_frame))
203
+
204
+ # Monta as linhas horizontalmente e depois as empilha verticalmente
205
+ image_rows = [np.hstack(rows_dict[row_index]) for row_index in sorted(rows_dict.keys())]
206
+ combined_image = np.vstack(image_rows)
207
 
208
+ # Salva e retorna o caminho da imagem final
209
  pil_img = Image.fromarray(combined_image)
210
+ path = "frames_extraidos_grid.png"
211
  pil_img.save(path)
212
  return path
213
 
 
257
  return plot_to_file(fig, "foco")
258
 
259
 
260
+ # --- FUNÇÃO DE CALLBACK PRINCIPAL ---
261
  def run_full_analysis(video_path, descriptions_text, start_frame, end_frame, progress=gr.Progress()):
262
  if video_path is None: raise gr.Error("Por favor, faça o upload de um vídeo.")
263
 
 
264
  start_frame, end_frame = int(start_frame), int(end_frame)
265
 
266
+ progress(0, desc="Extraindo e visualizando frames...")
267
  frames_imagem_path = extrair_e_visualizar_frames(video_path, start_frame, end_frame)
268
 
269
  progress(0.1, desc="Analisando fidelidade do trecho...")
 
293
  if error_msg: gr.Warning(error_msg)
294
 
295
  progress(1.0, desc="Análise completa!")
 
296
  return frames_imagem_path, fidelidade_plot_path, cor_plot_path, foco_plot_path, semantico_path, anomalias_plot_path
297
 
298
+ # --- INTERFACE GRADIO ---
299
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
300
  gr.Markdown("# Suíte de Validação Completa para Geração de Vídeo (ADUC-SDR)")
301
  with gr.Row():
 
303
  video_input = gr.Video(label="1. Upload do vídeo")
304
  descriptions_input = gr.Textbox(lines=5, label="3. Descrições (Opcional)", placeholder="Uma descrição por cena para o teste de inteligência...")
305
 
 
306
  with gr.Row():
307
  start_frame_input = gr.Number(label="Frame Inicial", value=0, precision=0, info="Deixe 0 e 0 para analisar o vídeo inteiro.")
308
  end_frame_input = gr.Number(label="Frame Final", value=0, precision=0, info="Ex: 88 e 94 para analisar esse trecho.")
 
310
  analyze_button = gr.Button("4. Executar Análise Completa", variant="primary")
311
 
312
  with gr.Tabs():
 
313
  with gr.TabItem("Frames Extraídos"):
314
+ extracted_frames_img = gr.Image(label="Visualização dos Frames em Grade")
315
  with gr.TabItem("1. Fidelidade e Coerência"):
316
  plot_fidelidade = gr.Image(label="Gráfico de Análise de Fidelidade (SSIM e pHash)")
317
  with gr.TabItem("2. Cor e Iluminação"):
 
323
  with gr.TabItem("5. Inteligência Adaptativa"):
324
  plot_semantico = gr.Image(label="Gráfico de Estresse Semântico")
325
 
 
326
  analyze_button.click(
327
  fn=run_full_analysis,
328
  inputs=[video_input, descriptions_input, start_frame_input, end_frame_input],
329
+ outputs=[extracted_frames_img, plot_fidelidade, plot_cor, plot_foco, plot_semantico, anomalias_plot_path]
330
  )
331
 
332
  if __name__ == "__main__":