nam_nguyenhoai_AI
update src
4808241
raw
history blame
5.62 kB
import gradio as gr
import cv2
import os
import tempfile
import numpy as np
from utils import *
from algorithm import *
def make_video(video_path, outdir='./summarized_video', algorithm='Offline (KMeans)'):
if algorithm not in ["Offline (KMeans)", "Online (Sum of Squared Difference)"]:
algorithm = "Offline (KMeans)"
# nen them vao cac truong hop mo hinh khac
model, processor, device = load_model()
# total_params = sum(param.numel() for param in model.parameters())
# print('Total parameters: {:.2f}M'.format(total_params / 1e6))
if os.path.isfile(video_path):
if video_path.endswith('txt'):
with open(video_path, 'r') as f:
lines = f.read().splitlines()
else:
filenames = [video_path]
else:
filenames = os.listdir(video_path)
filenames = [os.path.join(video_path, filename) for filename in filenames if not filename.startswith('.')]
filenames.sort()
for k, filename in enumerate(filenames):
print('Progress {:}/{:},'.format(k+1, len(filenames)), 'Processing', filename)
raw_video = cv2.VideoCapture(filename)
frame_rate = int(raw_video.get(cv2.CAP_PROP_FPS))
#length = int(raw_video.get(cv2.CAP_PROP_FRAME_COUNT))
filename = os.path.basename(filename)
# Find the size to resize
if "shortest_edge" in processor.size:
height = width = processor.size["shortest_edge"]
else:
height = processor.size["height"]
width = processor.size["width"]
resize_to = (height, width)
# F/Fs
clip_sample_rate = 1
# F
num_frames = 8
original_frames = []
frames = []
features = []
with tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') as tmpfile:
output_path = tmpfile.name
while raw_video.isOpened():
ret, raw_frame = raw_video.read()
if not ret:
break
# use the original frames to write the output video if you want
#original_frames.append(raw_frame)
raw_frame = cv2.resize(raw_frame, resize_to)
# use the resized frames to extract features
frames.append(raw_frame)
# Find key frames by selecting frames with clip_sample_rate
key_frames = frames[::clip_sample_rate]
#print('total of frames after sample:', len(selected_frames))
# Remove redundant frames to make the number of frames can be divided by num_frames
num_redudant_frames = len(key_frames) - (len(key_frames) % num_frames)
# Final key frames
final_key_frames = key_frames[:num_redudant_frames]
#print('total of frames after remove redundant frames:', len(selected_frames))
for i in range(0, len(final_key_frames), num_frames):
if i % num_frames*50 == 0:
print(f"Loading {i}/{len(final_key_frames)}")
# Input clip to the model
input_frames = final_key_frames[i:i+num_frames]
# Extract features
batch_features = extract_features(input_frames, device, model, processor)
# Convert to numpy array to decrease the memory usage
batch_features = np.array(batch_features.cpu().detach().numpy())
features.extend(batch_features)
number_of_clusters = round(len(features)*0.15)
print("Total of frames: ", len(final_key_frames))
print("Shape of each frame: ", frames[0].shape)
print("Total of clips: ", len(features))
print("Shape of each clip: ", features[0].shape)
selected_frames = []
if algorithm == "Offline (KMeans)":
selected_frames = offline(number_of_clusters, features)
else:
selected_frames = online(features, 400)
print("Selected frame: ", selected_frames)
video_writer = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'mp4v'), frame_rate, (frames[0].shape[1], frames[0].shape[0]))
for idx in selected_frames:
video_writer.write(frames[idx])
# video_writer.write(original_frames[idx]) if you want to write the original frames
raw_video.release()
video_writer.release()
print("Completed summarizing the video (wait for a moment to load).")
return output_path
css = """
#img-display-container {
max-height: 100vh;
}
#img-display-input {
max-height: 80vh;
}
#img-display-output {
max-height: 80vh;
}
"""
title = "# Video Summarization Demo"
description = """Video Summarization using Timesformer.
Author: Nguyen Hoai Nam.
"""
with gr.Blocks(css=css) as demo:
gr.Markdown(title)
gr.Markdown(description)
gr.Markdown("### Video Summarization demo")
with gr.Row():
input_video = gr.Video(label="Input Video")
algorithm_type = gr.Dropdown(["Offline (KMeans)", "Online (Sum of Squared Difference)"], type="value", label='Algorithm')
submit = gr.Button("Submit")
processed_video = gr.Video(label="Summarized Video")
def on_submit(uploaded_video, algorithm_type):
print("Algorithm: ", algorithm_type)
# Process the video and get the path of the output video
output_video_path = make_video(uploaded_video, algorithm=algorithm_type)
return output_video_path
submit.click(on_submit, inputs=[input_video, algorithm_type], outputs=processed_video)
if __name__ == '__main__':
demo.queue().launch(share=True)