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