File size: 2,650 Bytes
6ab21ce
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53ae0ea
6ab21ce
 
 
 
 
 
 
 
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
import cv2
import numpy as np

import gradio as gr
import os
import shutil
import spaces

class PanoramaGenerator:
    def __init__(self, video_path):
        self.video_path = video_path
        self.frames = []

    def extract_frames(self, frame_interval=10):
        cap = cv2.VideoCapture(self.video_path)

        if not cap.isOpened():
            raise ValueError("Error opening video file")

        frame_count = 0
        while True:
            ret, frame = cap.read()

            if not ret:
                break

            # Extract frame
            if frame_count % frame_interval == 0:
                # Resize frame
                resized_frame = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5)
                self.frames.append(resized_frame)

            frame_count += 1

        cap.release()
        return self.frames

    def create_panorama(self):
        if len(self.frames) < 2:
            raise ValueError("Not enough frames to create panorama")

        stitcher = cv2.Stitcher_create(mode=cv2.Stitcher_PANORAMA)

        # Attempt to stitch frames
        status, panorama = stitcher.stitch(self.frames)

        # Check if stitching was successful
        if status != cv2.Stitcher_OK:
            raise RuntimeError(f"Stitching failed with error code {status}")

        return panorama

    def save_panorama(self, output_path="panorama.jpg"):
        panorama = self.create_panorama()
        cv2.imwrite(output_path, panorama)
        return output_path




def process_video(video_file):
    # Save the uploaded video to a temporary file
    temp_video_path = "temp_video.mp4"
    shutil.copy(video_file.name, temp_video_path)

    # Generate the panorama
    panorama_gen = PanoramaGenerator(temp_video_path)
    panorama_gen.extract_frames()
    panorama_path = panorama_gen.save_panorama()

    # Clean up the temporary video file
    os.remove(temp_video_path)

    return panorama_path

@spaces.GPU
def generate_and_display(video_file):
    panorama_path = process_video(video_file)
    return panorama_path, panorama_path

with gr.Blocks() as demo:
    gr.Markdown("# Video to Panorama Generator")

    with gr.Row():
        with gr.Column():
            video_input = gr.File(label="Upload Video", file_types=["video"])
            generate_button = gr.Button("Generate Panorama")
        with gr.Column():
            panorama_output = gr.Image(label="Generated Panorama")
            download_button = gr.DownloadButton("Download Panorama")

    generate_button.click(
        fn=generate_and_display,
        inputs=video_input,
        outputs=[panorama_output, download_button]
    )

demo.launch()