Update visualization.py
Browse files- visualization.py +18 -15
visualization.py
CHANGED
@@ -6,7 +6,7 @@ import seaborn as sns
|
|
6 |
import numpy as np
|
7 |
import pandas as pd
|
8 |
import cv2
|
9 |
-
from moviepy.editor import VideoFileClip, AudioFileClip, CompositeVideoClip
|
10 |
from moviepy.video.fx.all import resize
|
11 |
from matplotlib.patches import Rectangle
|
12 |
from utils import seconds_to_timecode
|
@@ -267,11 +267,9 @@ def create_video_with_heatmap(video_path, df, mse_embeddings, mse_posture, mse_v
|
|
267 |
ax.set_xticks([])
|
268 |
plt.tight_layout()
|
269 |
|
270 |
-
def
|
271 |
-
t = frame / video.fps if isinstance(frame, np.ndarray) else frame
|
272 |
frame_count = int(t * video.fps)
|
273 |
|
274 |
-
# Update heatmap
|
275 |
if hasattr(ax, 'line'):
|
276 |
ax.lines.pop(0)
|
277 |
ax.axvline(x=frame_count, color='r', linewidth=2)
|
@@ -280,28 +278,33 @@ def create_video_with_heatmap(video_path, df, mse_embeddings, mse_posture, mse_v
|
|
280 |
canvas.draw()
|
281 |
heatmap_img = np.frombuffer(canvas.tostring_rgb(), dtype='uint8')
|
282 |
heatmap_img = heatmap_img.reshape(canvas.get_width_height()[::-1] + (3,))
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
combined_frame = np.vstack((frame, heatmap_img))
|
287 |
-
|
288 |
-
# Add timecode
|
289 |
seconds = t
|
290 |
timecode = f"{int(seconds//3600):02d}:{int((seconds%3600)//60):02d}:{int(seconds%60):02d}"
|
291 |
|
292 |
-
pil_img = Image.fromarray(
|
293 |
draw = ImageDraw.Draw(pil_img)
|
294 |
font = ImageFont.load_default()
|
295 |
draw.text((10, 30), f"Time: {timecode}", font=font, fill=(255, 255, 255))
|
296 |
|
297 |
return np.array(pil_img)
|
298 |
|
299 |
-
|
300 |
-
|
301 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
302 |
|
303 |
# Write the final video
|
304 |
-
final_clip.write_videofile(heatmap_video_path, codec='libx264', audio_codec='aac')
|
305 |
|
306 |
# Close the video clips
|
307 |
video.close()
|
|
|
6 |
import numpy as np
|
7 |
import pandas as pd
|
8 |
import cv2
|
9 |
+
from moviepy.editor import VideoFileClip, AudioFileClip, CompositeVideoClip, ImageClip
|
10 |
from moviepy.video.fx.all import resize
|
11 |
from matplotlib.patches import Rectangle
|
12 |
from utils import seconds_to_timecode
|
|
|
267 |
ax.set_xticks([])
|
268 |
plt.tight_layout()
|
269 |
|
270 |
+
def create_heatmap(t):
|
|
|
271 |
frame_count = int(t * video.fps)
|
272 |
|
|
|
273 |
if hasattr(ax, 'line'):
|
274 |
ax.lines.pop(0)
|
275 |
ax.axvline(x=frame_count, color='r', linewidth=2)
|
|
|
278 |
canvas.draw()
|
279 |
heatmap_img = np.frombuffer(canvas.tostring_rgb(), dtype='uint8')
|
280 |
heatmap_img = heatmap_img.reshape(canvas.get_width_height()[::-1] + (3,))
|
281 |
+
return heatmap_img
|
282 |
+
|
283 |
+
def add_timecode(frame, t):
|
|
|
|
|
|
|
284 |
seconds = t
|
285 |
timecode = f"{int(seconds//3600):02d}:{int((seconds%3600)//60):02d}:{int(seconds%60):02d}"
|
286 |
|
287 |
+
pil_img = Image.fromarray(frame.astype('uint8'))
|
288 |
draw = ImageDraw.Draw(pil_img)
|
289 |
font = ImageFont.load_default()
|
290 |
draw.text((10, 30), f"Time: {timecode}", font=font, fill=(255, 255, 255))
|
291 |
|
292 |
return np.array(pil_img)
|
293 |
|
294 |
+
heatmap_clip = VideoClip(create_heatmap, duration=video.duration)
|
295 |
+
heatmap_clip = heatmap_clip.resize(height=200)
|
296 |
+
|
297 |
+
def combine_video_and_heatmap(t):
|
298 |
+
video_frame = video.get_frame(t)
|
299 |
+
heatmap_frame = heatmap_clip.get_frame(t)
|
300 |
+
combined_frame = np.vstack((video_frame, heatmap_frame))
|
301 |
+
return add_timecode(combined_frame, t)
|
302 |
+
|
303 |
+
final_clip = VideoClip(combine_video_and_heatmap, duration=video.duration)
|
304 |
+
final_clip = final_clip.set_audio(video.audio)
|
305 |
|
306 |
# Write the final video
|
307 |
+
final_clip.write_videofile(heatmap_video_path, codec='libx264', audio_codec='aac', fps=video.fps)
|
308 |
|
309 |
# Close the video clips
|
310 |
video.close()
|