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()