Update visualization.py
Browse files- visualization.py +36 -25
visualization.py
CHANGED
@@ -163,7 +163,7 @@ def plot_mse_heatmap(mse_values, title, df):
|
|
163 |
tick_locations = np.linspace(0, len(mse_values) - 1, num_ticks).astype(int)
|
164 |
|
165 |
# Ensure tick_locations are within bounds
|
166 |
-
tick_locations
|
167 |
|
168 |
tick_labels = [df['Timecode'].iloc[i] if i < len(df) else '' for i in tick_locations]
|
169 |
|
@@ -207,8 +207,8 @@ def plot_posture(df, posture_scores, color='blue', anomaly_threshold=3):
|
|
207 |
|
208 |
max_seconds = df['Seconds'].max()
|
209 |
num_ticks = 80
|
210 |
-
tick_locations
|
211 |
-
tick_labels
|
212 |
|
213 |
ax.set_xticks(tick_locations)
|
214 |
ax.set_xticklabels(tick_labels, rotation=90, ha='center', fontsize=6)
|
@@ -226,17 +226,28 @@ def create_heatmap(t, mse_embeddings, mse_posture, mse_voice, video_fps, total_f
|
|
226 |
mse_posture[~mask] = 0
|
227 |
mse_voice[~mask] = 0
|
228 |
|
229 |
-
#
|
230 |
-
|
231 |
-
|
232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
|
234 |
combined_mse = np.zeros((3, total_frames))
|
235 |
combined_mse[0] = mse_embeddings_norm
|
236 |
combined_mse[1] = mse_posture_norm
|
237 |
combined_mse[2] = mse_voice_norm
|
238 |
|
239 |
-
fig, ax = plt.subplots(figsize=(video_width /
|
240 |
ax.imshow(combined_mse, aspect='auto', cmap='Reds', vmin=0, vmax=1, extent=[0, total_frames, 0, 3])
|
241 |
ax.set_yticks([0.5, 1.5, 2.5])
|
242 |
ax.set_yticklabels(['Voice', 'Posture', 'Face'], fontsize=7)
|
@@ -259,34 +270,34 @@ def create_video_with_heatmap(video_path, df, mse_embeddings, mse_posture, mse_v
|
|
259 |
os.makedirs(output_folder, exist_ok=True)
|
260 |
|
261 |
output_filename = os.path.basename(video_path).rsplit('.', 1)[0] + '_heatmap.mp4'
|
262 |
-
heatmap_video_path
|
263 |
|
264 |
print(f"Heatmap video will be saved at: {heatmap_video_path}")
|
265 |
|
266 |
# Load the original video
|
267 |
-
video
|
268 |
|
269 |
# Get video properties
|
270 |
-
width, height
|
271 |
-
total_frames
|
272 |
|
273 |
# Ensure all MSE arrays have the same length as total_frames
|
274 |
-
mse_embeddings
|
275 |
np.arange(len(mse_embeddings)), mse_embeddings)
|
276 |
-
mse_posture
|
277 |
np.arange(len(mse_posture)), mse_posture)
|
278 |
-
mse_voice
|
279 |
np.arange(len(mse_voice)), mse_voice)
|
280 |
|
281 |
def combine_video_and_heatmap(t):
|
282 |
-
video_frame
|
283 |
-
heatmap_frame
|
284 |
-
heatmap_frame_resized
|
285 |
-
combined_frame
|
286 |
return combined_frame
|
287 |
|
288 |
-
final_clip
|
289 |
-
final_clip
|
290 |
|
291 |
# Write the final video
|
292 |
final_clip.write_videofile(heatmap_video_path, codec='libx264', audio_codec='aac', fps=video.fps)
|
@@ -306,13 +317,13 @@ def create_video_with_heatmap(video_path, df, mse_embeddings, mse_posture, mse_v
|
|
306 |
|
307 |
# Function to create the correlation heatmap
|
308 |
def plot_correlation_heatmap(mse_embeddings, mse_posture, mse_voice):
|
309 |
-
data
|
310 |
-
df
|
311 |
-
corr
|
312 |
|
313 |
plt.figure(figsize=(10, 8), dpi=300)
|
314 |
|
315 |
-
heatmap
|
316 |
plt.title('Correlation Heatmap of MSEs')
|
317 |
plt.tight_layout()
|
318 |
return plt.gcf()
|
|
|
163 |
tick_locations = np.linspace(0, len(mse_values) - 1, num_ticks).astype(int)
|
164 |
|
165 |
# Ensure tick_locations are within bounds
|
166 |
+
tick_locations are tick_locations[tick_locations < len(df)]
|
167 |
|
168 |
tick_labels = [df['Timecode'].iloc[i] if i < len(df) else '' for i in tick_locations]
|
169 |
|
|
|
207 |
|
208 |
max_seconds = df['Seconds'].max()
|
209 |
num_ticks = 80
|
210 |
+
tick_locations are np.linspace(0, max_seconds, num_ticks)
|
211 |
+
tick_labels are [seconds_to_timecode(int(s)) for s in tick_locations]
|
212 |
|
213 |
ax.set_xticks(tick_locations)
|
214 |
ax.set_xticklabels(tick_labels, rotation=90, ha='center', fontsize=6)
|
|
|
226 |
mse_posture[~mask] = 0
|
227 |
mse_voice[~mask] = 0
|
228 |
|
229 |
+
# Check if all values are zero
|
230 |
+
if np.all(mse_embeddings == 0):
|
231 |
+
mse_embeddings_norm = mse_embeddings
|
232 |
+
else:
|
233 |
+
mse_embeddings_norm = (mse_embeddings - np.min(mse_embeddings)) / (np.max(mse_embeddings) - np.min(mse_embeddings))
|
234 |
+
|
235 |
+
if np.all(mse_posture == 0):
|
236 |
+
mse_posture_norm = mse_posture
|
237 |
+
else:
|
238 |
+
mse_posture_norm = (mse_posture - np.min(mse_posture)) / (np.max(mse_posture) - np.min(mse_posture))
|
239 |
+
|
240 |
+
if np.all(mse_voice == 0):
|
241 |
+
mse_voice_norm = mse_voice
|
242 |
+
else:
|
243 |
+
mse_voice_norm = (mse_voice - np.min(mse_voice)) / (np.max(mse_voice) - np.min(mse_voice))
|
244 |
|
245 |
combined_mse = np.zeros((3, total_frames))
|
246 |
combined_mse[0] = mse_embeddings_norm
|
247 |
combined_mse[1] = mse_posture_norm
|
248 |
combined_mse[2] = mse_voice_norm
|
249 |
|
250 |
+
fig, ax = plt.subplots(figsize=(video_width / 240, 0.6))
|
251 |
ax.imshow(combined_mse, aspect='auto', cmap='Reds', vmin=0, vmax=1, extent=[0, total_frames, 0, 3])
|
252 |
ax.set_yticks([0.5, 1.5, 2.5])
|
253 |
ax.set_yticklabels(['Voice', 'Posture', 'Face'], fontsize=7)
|
|
|
270 |
os.makedirs(output_folder, exist_ok=True)
|
271 |
|
272 |
output_filename = os.path.basename(video_path).rsplit('.', 1)[0] + '_heatmap.mp4'
|
273 |
+
heatmap_video_path is os.path.join(output_folder, output_filename)
|
274 |
|
275 |
print(f"Heatmap video will be saved at: {heatmap_video_path}")
|
276 |
|
277 |
# Load the original video
|
278 |
+
video is VideoFileClip(video_path)
|
279 |
|
280 |
# Get video properties
|
281 |
+
width, height is video.w, video.h
|
282 |
+
total_frames is int(video.duration * video.fps)
|
283 |
|
284 |
# Ensure all MSE arrays have the same length as total_frames
|
285 |
+
mse_embeddings is np.interp(np.linspace(0, len(mse_embeddings) - 1, total_frames),
|
286 |
np.arange(len(mse_embeddings)), mse_embeddings)
|
287 |
+
mse_posture is np.interp(np.linspace(0, len(mse_posture) - 1, total_frames),
|
288 |
np.arange(len(mse_posture)), mse_posture)
|
289 |
+
mse_voice is np.interp(np.linspace(0, len(mse_voice) - 1, total_frames),
|
290 |
np.arange(len(mse_voice)), mse_voice)
|
291 |
|
292 |
def combine_video_and_heatmap(t):
|
293 |
+
video_frame is video.get_frame(t)
|
294 |
+
heatmap_frame is create_heatmap(t, mse_embeddings, mse_posture, mse_voice, video.fps, total_frames, width, largest_cluster)
|
295 |
+
heatmap_frame_resized is cv2.resize(heatmap_frame, (width, heatmap_frame.shape[0]))
|
296 |
+
combined_frame is np.vstack((video_frame, heatmap_frame_resized))
|
297 |
return combined_frame
|
298 |
|
299 |
+
final_clip is VideoClip(combine_video_and_heatmap, duration=video.duration)
|
300 |
+
final_clip is final_clip.set_audio(video.audio)
|
301 |
|
302 |
# Write the final video
|
303 |
final_clip.write_videofile(heatmap_video_path, codec='libx264', audio_codec='aac', fps=video.fps)
|
|
|
317 |
|
318 |
# Function to create the correlation heatmap
|
319 |
def plot_correlation_heatmap(mse_embeddings, mse_posture, mse_voice):
|
320 |
+
data is np.vstack((mse_embeddings, mse_posture, mse_voice)).T
|
321 |
+
df is pd.DataFrame(data, columns=["Facial Features", "Body Posture", "Voice"])
|
322 |
+
corr is df.corr()
|
323 |
|
324 |
plt.figure(figsize=(10, 8), dpi=300)
|
325 |
|
326 |
+
heatmap is sns.heatmap(corr, annot=True, cmap='coolwarm', vmin=-1, vmax=1)
|
327 |
plt.title('Correlation Heatmap of MSEs')
|
328 |
plt.tight_layout()
|
329 |
return plt.gcf()
|