nam_nguyenhoai_AI
commited on
Commit
•
6802355
1
Parent(s):
64a17a1
update src
Browse files- __pycache__/algorithm.cpython-38.pyc +0 -0
- __pycache__/utils.cpython-38.pyc +0 -0
- algorithm.py +4 -4
- app.py +60 -20
__pycache__/algorithm.cpython-38.pyc
CHANGED
Binary files a/__pycache__/algorithm.cpython-38.pyc and b/__pycache__/algorithm.cpython-38.pyc differ
|
|
__pycache__/utils.cpython-38.pyc
CHANGED
Binary files a/__pycache__/utils.cpython-38.pyc and b/__pycache__/utils.cpython-38.pyc differ
|
|
algorithm.py
CHANGED
@@ -32,7 +32,7 @@ def offline(number_of_clusters, features):
|
|
32 |
|
33 |
return closest_clips_frames
|
34 |
|
35 |
-
def online(features, threshold):
|
36 |
|
37 |
i = 0
|
38 |
previous = i
|
@@ -48,7 +48,7 @@ def online(features, threshold):
|
|
48 |
clip.append(b)
|
49 |
|
50 |
# randomly select 15% of the frames from the clip list
|
51 |
-
random_num = round(len(clip)*
|
52 |
# sort the frames in the clip list to ensure the order of the frames
|
53 |
random_Frames = sorted(random.sample(clip, random_num))
|
54 |
i = j
|
@@ -61,13 +61,13 @@ def online(features, threshold):
|
|
61 |
if i==j:
|
62 |
for c in range(j*8, j*8+8):
|
63 |
clip.append(c)
|
64 |
-
random_num = round(len(clip)*
|
65 |
random_Frames = sorted(random.sample(clip, random_num))
|
66 |
|
67 |
else: # (i<j)
|
68 |
for c in range(i*8, (j+1)*8):
|
69 |
clip.append(c)
|
70 |
-
random_num = round(len(clip)*
|
71 |
random_Frames = sorted(random.sample(clip, random_num))
|
72 |
|
73 |
clips.extend(random_Frames)
|
|
|
32 |
|
33 |
return closest_clips_frames
|
34 |
|
35 |
+
def online(features, threshold, ratio):
|
36 |
|
37 |
i = 0
|
38 |
previous = i
|
|
|
48 |
clip.append(b)
|
49 |
|
50 |
# randomly select 15% of the frames from the clip list
|
51 |
+
random_num = round(len(clip)*ratio/100)
|
52 |
# sort the frames in the clip list to ensure the order of the frames
|
53 |
random_Frames = sorted(random.sample(clip, random_num))
|
54 |
i = j
|
|
|
61 |
if i==j:
|
62 |
for c in range(j*8, j*8+8):
|
63 |
clip.append(c)
|
64 |
+
random_num = round(len(clip)*ratio/100)
|
65 |
random_Frames = sorted(random.sample(clip, random_num))
|
66 |
|
67 |
else: # (i<j)
|
68 |
for c in range(i*8, (j+1)*8):
|
69 |
clip.append(c)
|
70 |
+
random_num = round(len(clip)*ratio/100)
|
71 |
random_Frames = sorted(random.sample(clip, random_num))
|
72 |
|
73 |
clips.extend(random_Frames)
|
app.py
CHANGED
@@ -5,11 +5,23 @@ import tempfile
|
|
5 |
import numpy as np
|
6 |
from utils import *
|
7 |
from algorithm import *
|
|
|
8 |
|
9 |
-
def make_video(video_path, outdir='./summarized_video', algorithm='Offline (KMeans)'):
|
10 |
if algorithm not in ["Offline (KMeans)", "Online (Sum of Squared Difference)"]:
|
11 |
algorithm = "Offline (KMeans)"
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
# nen them vao cac truong hop mo hinh khac
|
14 |
model, processor, device = load_model()
|
15 |
|
@@ -32,10 +44,15 @@ def make_video(video_path, outdir='./summarized_video', algorithm='Offline (KMea
|
|
32 |
|
33 |
raw_video = cv2.VideoCapture(filename)
|
34 |
frame_rate = int(raw_video.get(cv2.CAP_PROP_FPS))
|
|
|
|
|
|
|
|
|
35 |
#length = int(raw_video.get(cv2.CAP_PROP_FRAME_COUNT))
|
36 |
-
|
37 |
filename = os.path.basename(filename)
|
38 |
-
|
|
|
39 |
# Find the size to resize
|
40 |
if "shortest_edge" in processor.size:
|
41 |
height = width = processor.size["shortest_edge"]
|
@@ -90,7 +107,7 @@ def make_video(video_path, outdir='./summarized_video', algorithm='Offline (KMea
|
|
90 |
batch_features = np.array(batch_features.cpu().detach().numpy())
|
91 |
features.extend(batch_features)
|
92 |
|
93 |
-
number_of_clusters = round(len(features)*
|
94 |
|
95 |
print("Total of frames: ", len(final_key_frames))
|
96 |
print("Shape of each frame: ", frames[0].shape)
|
@@ -101,7 +118,7 @@ def make_video(video_path, outdir='./summarized_video', algorithm='Offline (KMea
|
|
101 |
if algorithm == "Offline (KMeans)":
|
102 |
selected_frames = offline(number_of_clusters, features)
|
103 |
else:
|
104 |
-
selected_frames = online(features,
|
105 |
|
106 |
print("Selected frame: ", selected_frames)
|
107 |
|
@@ -110,10 +127,16 @@ def make_video(video_path, outdir='./summarized_video', algorithm='Offline (KMea
|
|
110 |
video_writer.write(frames[idx])
|
111 |
# video_writer.write(original_frames[idx]) if you want to write the original frames
|
112 |
|
|
|
|
|
|
|
|
|
113 |
raw_video.release()
|
114 |
video_writer.release()
|
115 |
print("Completed summarizing the video (wait for a moment to load).")
|
116 |
-
|
|
|
|
|
117 |
|
118 |
css = """
|
119 |
#img-display-container {
|
@@ -127,31 +150,48 @@ css = """
|
|
127 |
}
|
128 |
"""
|
129 |
|
130 |
-
|
131 |
-
|
132 |
|
|
|
133 |
Author: Nguyen Hoai Nam.
|
134 |
-
|
135 |
|
136 |
with gr.Blocks(css=css) as demo:
|
137 |
-
gr.Markdown(
|
138 |
-
gr.Markdown(description)
|
139 |
-
gr.Markdown("### Video Summarization demo")
|
140 |
|
141 |
with gr.Row():
|
142 |
-
|
143 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
|
145 |
-
|
146 |
-
|
|
|
|
|
147 |
|
148 |
-
def on_submit(uploaded_video, algorithm_type):
|
149 |
-
print("
|
|
|
|
|
150 |
# Process the video and get the path of the output video
|
151 |
-
output_video_path = make_video(uploaded_video, algorithm=algorithm_type)
|
152 |
return output_video_path
|
153 |
|
154 |
-
submit.click(on_submit, inputs=[input_video, algorithm_type], outputs=processed_video)
|
155 |
|
156 |
if __name__ == '__main__':
|
157 |
demo.queue().launch(share=True)
|
|
|
5 |
import numpy as np
|
6 |
from utils import *
|
7 |
from algorithm import *
|
8 |
+
import time
|
9 |
|
10 |
+
def make_video(video_path, outdir='./summarized_video', algorithm='Offline (KMeans)', ratio=15, threshold_type='Average'):
|
11 |
if algorithm not in ["Offline (KMeans)", "Online (Sum of Squared Difference)"]:
|
12 |
algorithm = "Offline (KMeans)"
|
13 |
|
14 |
+
if threshold_type not in ["Small", "Average", "Large"]:
|
15 |
+
threshold_type = "Average"
|
16 |
+
|
17 |
+
if threshold_type == "Small":
|
18 |
+
threshold = 100
|
19 |
+
elif threshold_type == "Average":
|
20 |
+
threshold = 400
|
21 |
+
else:
|
22 |
+
threshold = 800
|
23 |
+
|
24 |
+
|
25 |
# nen them vao cac truong hop mo hinh khac
|
26 |
model, processor, device = load_model()
|
27 |
|
|
|
44 |
|
45 |
raw_video = cv2.VideoCapture(filename)
|
46 |
frame_rate = int(raw_video.get(cv2.CAP_PROP_FPS))
|
47 |
+
frame_count = int(raw_video.get(cv2.CAP_PROP_FRAME_COUNT))
|
48 |
+
duration_seconds = frame_count / frame_rate
|
49 |
+
width = int(raw_video.get(cv2.CAP_PROP_FRAME_WIDTH))
|
50 |
+
height = int(raw_video.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
51 |
#length = int(raw_video.get(cv2.CAP_PROP_FRAME_COUNT))
|
52 |
+
start_time = time.time()
|
53 |
filename = os.path.basename(filename)
|
54 |
+
in_width = width
|
55 |
+
in_height = height
|
56 |
# Find the size to resize
|
57 |
if "shortest_edge" in processor.size:
|
58 |
height = width = processor.size["shortest_edge"]
|
|
|
107 |
batch_features = np.array(batch_features.cpu().detach().numpy())
|
108 |
features.extend(batch_features)
|
109 |
|
110 |
+
number_of_clusters = round(len(features)*ratio/100)
|
111 |
|
112 |
print("Total of frames: ", len(final_key_frames))
|
113 |
print("Shape of each frame: ", frames[0].shape)
|
|
|
118 |
if algorithm == "Offline (KMeans)":
|
119 |
selected_frames = offline(number_of_clusters, features)
|
120 |
else:
|
121 |
+
selected_frames = online(features, threshold, ratio)
|
122 |
|
123 |
print("Selected frame: ", selected_frames)
|
124 |
|
|
|
127 |
video_writer.write(frames[idx])
|
128 |
# video_writer.write(original_frames[idx]) if you want to write the original frames
|
129 |
|
130 |
+
out_duration_seconds = len(selected_frames) / frame_rate
|
131 |
+
out_width = frames[0].shape[1]
|
132 |
+
out_height = frames[0].shape[0]
|
133 |
+
|
134 |
raw_video.release()
|
135 |
video_writer.release()
|
136 |
print("Completed summarizing the video (wait for a moment to load).")
|
137 |
+
end_time = time.time()
|
138 |
+
process_time = round(end_time - start_time, 2)
|
139 |
+
return output_path, duration_seconds, frame_rate, f"{in_width} x {in_height}", process_time, out_duration_seconds, frame_rate, f"{out_width} x {out_height}"
|
140 |
|
141 |
css = """
|
142 |
#img-display-container {
|
|
|
150 |
}
|
151 |
"""
|
152 |
|
153 |
+
_HEADER_ = '''
|
154 |
+
<h2><b>Video summarization 🤗 Gradio Demo</b></h2><h2><a href='https://github.com/youneedyourself/Video-Summarization_Timesformer target='_blank'><b>Video Summarization Using Timesformer Modal and K-means, SSD</b></a></h2>
|
155 |
|
156 |
+
Code: <a href='https://github.com/youneedyourself/Video-Summarization_Timesformer' target='_blank'>GitHub</a>.
|
157 |
Author: Nguyen Hoai Nam.
|
158 |
+
'''
|
159 |
|
160 |
with gr.Blocks(css=css) as demo:
|
161 |
+
gr.Markdown(_HEADER_)
|
|
|
|
|
162 |
|
163 |
with gr.Row():
|
164 |
+
with gr.Column():
|
165 |
+
input_video = gr.Video(label="Input Video (Required Duration > 5s)")
|
166 |
+
with gr.Column():
|
167 |
+
# Thêm thông tin về video
|
168 |
+
algorithm_type = gr.Dropdown(["Offline (KMeans)", "Online (Sum of Squared Difference)"], type="value", label='Algorithm')
|
169 |
+
ratio = gr.Slider(15, 80, label="Summarization Ratio (%) (Recommend: 15)")
|
170 |
+
threshold = gr.Dropdown(["Small", "Average", "Large"], type="value", label='Difference Threshold for Online Algorithm (Recommend: Average)')
|
171 |
+
submit = gr.Button("Summarize")
|
172 |
+
with gr.Row():
|
173 |
+
processed_video = gr.Video(label="Summarized Video")
|
174 |
+
with gr.Column():
|
175 |
+
input_video_duration = gr.Text(label="Input Video Duration (s)")
|
176 |
+
input_video_FPS = gr.Text(label="Input Video FPS")
|
177 |
+
input_video_resolution = gr.Text(label="Input Video Resolution")
|
178 |
+
|
179 |
+
time_process = gr.Text(label="Time Process (s)")
|
180 |
|
181 |
+
with gr.Column():
|
182 |
+
output_video_duration = gr.Text(label="Output Video Duration (s)")
|
183 |
+
output_video_FPS = gr.Text(label="Output Video FPS")
|
184 |
+
output_video_resolution = gr.Text(label="Output Video Resolution")
|
185 |
|
186 |
+
def on_submit(uploaded_video, algorithm_type, ratio, threshold):
|
187 |
+
print("Ratio:", ratio)
|
188 |
+
print("Algorithm:", algorithm_type)
|
189 |
+
print("Threshold:", threshold)
|
190 |
# Process the video and get the path of the output video
|
191 |
+
output_video_path = make_video(uploaded_video, algorithm=algorithm_type, ratio=ratio, threshold_type=threshold)
|
192 |
return output_video_path
|
193 |
|
194 |
+
submit.click(on_submit, inputs=[input_video, algorithm_type, ratio, threshold], outputs=[processed_video, input_video_duration, input_video_FPS, input_video_resolution, time_process, output_video_duration, output_video_FPS, output_video_resolution])
|
195 |
|
196 |
if __name__ == '__main__':
|
197 |
demo.queue().launch(share=True)
|