Spaces:
Sleeping
Sleeping
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() |