Spaces:
Running
Running
File size: 5,564 Bytes
a98d699 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
import gradio as gr
import cv2
import numpy as np
import matplotlib.pyplot as plt
import os
# Define um estilo de gráfico que fica bem no modo escuro do Gradio
plt.style.use('dark_background')
def analyze_videos(video_original_path, video_interpolado_path, progress=gr.Progress()):
"""
Função principal que é chamada pelo Gradio para analisar os vídeos.
"""
if video_original_path is None or video_interpolado_path is None:
return None, "Por favor, envie os dois arquivos de vídeo para iniciar a análise."
# --- 1. Carregar frames do vídeo original ---
progress(0, desc="Carregando vídeo original...")
try:
cap_orig = cv2.VideoCapture(video_original_path)
frames_originais = []
while True:
ret, frame = cap_orig.read()
if not ret: break
frames_originais.append(frame)
cap_orig.release()
if not frames_originais:
return None, "Erro: Não foi possível ler frames do vídeo original. O arquivo pode estar corrompido."
except Exception as e:
return None, f"Erro ao processar o vídeo original: {e}"
# --- 2. Comparar com o vídeo longo ---
try:
cap_longo = cv2.VideoCapture(video_interpolado_path)
total_frames_longo = int(cap_longo.get(cv2.CAP_PROP_FRAME_COUNT))
if total_frames_longo == 0:
return None, "Erro: O vídeo gerado parece não ter frames."
posicoes_encontradas = []
index_frame_longo = 0
while True:
ret, frame_longo = cap_longo.read()
if not ret: break
# Atualiza a barra de progresso
progress(index_frame_longo / total_frames_longo, desc=f"Analisando Frame {index_frame_longo}/{total_frames_longo}")
for index_original, frame_original in enumerate(frames_originais):
if frame_longo.shape == frame_original.shape:
# Comparação pixel a pixel
if np.array_equal(frame_longo, frame_original):
posicoes_encontradas.append((index_original, index_frame_longo))
break # Otimização: se encontrou, vai para o próximo frame do vídeo longo
index_frame_longo += 1
cap_longo.release()
except Exception as e:
return None, f"Erro ao processar o vídeo gerado: {e}"
# --- 3. Gerar o gráfico e o relatório ---
fig = create_plot(posicoes_encontradas)
report = create_report(posicoes_encontradas, len(frames_originais), total_frames_longo)
return fig, report
def create_plot(results):
"""Cria a figura do Matplotlib para exibir no Gradio."""
fig, ax = plt.subplots(figsize=(10, 6))
if not results:
ax.text(0.5, 0.5, "Nenhum frame correspondente foi encontrado.",
ha='center', va='center', fontsize=12, color='orange')
else:
indices_originais, posicoes_encontradas = zip(*results)
# Gráfico de "pirulito" (stem plot)
ax.stem(posicoes_encontradas, indices_originais, linefmt='--g', markerfmt='ob', basefmt=" ")
ax.set_title("Posição dos Frames Originais no Vídeo Gerado", color='white', fontsize=16)
ax.set_xlabel("Índice do Frame no Vídeo Longo", color='white', fontsize=12)
ax.set_ylabel("Índice do Frame Original", color='white', fontsize=12)
ax.grid(True, linestyle='--', alpha=0.5)
ax.tick_params(axis='x', colors='white')
ax.tick_params(axis='y', colors='white')
fig.tight_layout()
return fig
def create_report(results, total_original, total_longo):
"""Cria um relatório em texto formatado com Markdown."""
if not results:
return "## Relatório de Análise\n\nNenhuma correspondência encontrada. Verifique se o vídeo gerado realmente contém os frames do vídeo original."
report_md = f"""
## Relatório de Análise
**Análise Concluída com Sucesso!**
- **Vídeo Original:** {total_original} frames.
- **Vídeo Gerado:** {total_longo} frames.
- **Correspondências Encontradas:** {len(results)} frames.
### Detalhes das Posições:
"""
for idx_original, idx_longo in results:
report_md += f"- O **Frame Original #{idx_original}** foi encontrado na **Posição #{idx_longo}** do vídeo gerado.\n"
return report_md
# --- Interface Gradio ---
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown(
"""
# 📊 Analisador de Frames de Vídeo
Esta ferramenta compara dois vídeos para encontrar onde os frames de um vídeo original (curto) aparecem em um vídeo gerado (longo/interpolado).
1. Suba o vídeo original (ex: 10 frames).
2. Suba o vídeo gerado a partir do original (ex: 100 frames).
3. Clique em "Analisar" e veja o gráfico e o relatório.
"""
)
with gr.Row():
video_original_input = gr.Video(label="1. Vídeo Original (Curto)")
video_interpolado_input = gr.Video(label="2. Vídeo Gerado (Longo/Interpolado)")
btn_analisar = gr.Button("Analisar Vídeos", variant="primary")
gr.Markdown("---")
gr.Markdown("## Resultados")
plot_output = gr.Plot(label="Gráfico de Comparação")
report_output = gr.Markdown(label="Relatório Detalhado")
btn_analisar.click(
fn=analyze_videos,
inputs=[video_original_input, video_interpolado_input],
outputs=[plot_output, report_output]
)
if __name__ == "__main__":
demo.launch() |