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