Update app.py
Browse files
app.py
CHANGED
@@ -245,6 +245,29 @@ def determine_optimal_anomalies(anomaly_scores, z_threshold=3):
|
|
245 |
anomalies = anomaly_scores > threshold
|
246 |
return anomalies, np.where(anomalies)[0]
|
247 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
248 |
class LSTMAutoencoder(nn.Module):
|
249 |
def __init__(self, input_size, hidden_size=64, num_layers=2):
|
250 |
super(LSTMAutoencoder, self).__init__()
|
@@ -349,7 +372,6 @@ def normalize_scores(scores):
|
|
349 |
return np.full_like(scores, 100)
|
350 |
return ((scores - min_score) / (max_score - min_score)) * 100
|
351 |
|
352 |
-
|
353 |
def plot_anomaly_scores(df, anomaly_scores, top_indices, title, timecodes):
|
354 |
plt.figure(figsize=(16, 8), dpi=500)
|
355 |
fig, ax = plt.subplots(figsize=(16, 8))
|
@@ -371,10 +393,16 @@ def plot_anomaly_scores(df, anomaly_scores, top_indices, title, timecodes):
|
|
371 |
top_indices = [idx for idx in top_indices if idx > 0]
|
372 |
ax.scatter(df['Seconds'].iloc[top_indices], normalized_scores[top_indices], color='red', s=50, zorder=5)
|
373 |
|
374 |
-
#
|
375 |
-
for idx
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
ax.annotate(timecode,
|
377 |
-
(df['Seconds'].iloc[idx],
|
378 |
xytext=(5, 5), textcoords='offset points',
|
379 |
fontsize=6, color='red')
|
380 |
|
@@ -411,10 +439,16 @@ def plot_emotion(df, emotion, anomaly_scores, top_indices, color, timecodes):
|
|
411 |
top_indices = [idx for idx in top_indices if idx > 0]
|
412 |
ax.scatter(df['Seconds'].iloc[top_indices], anomaly_scores[top_indices], color='red', s=50, zorder=5)
|
413 |
|
414 |
-
#
|
415 |
-
for idx
|
|
|
|
|
|
|
|
|
|
|
|
|
416 |
ax.annotate(timecode,
|
417 |
-
(df['Seconds'].iloc[idx],
|
418 |
xytext=(5, 5), textcoords='offset points',
|
419 |
fontsize=6, color='red')
|
420 |
|
@@ -534,9 +568,9 @@ def process_video(video_path, num_components, desired_fps, batch_size, progress=
|
|
534 |
|
535 |
progress(0.95, "Generating plots")
|
536 |
try:
|
537 |
-
anomaly_plot_all = plot_anomaly_scores(df, anomaly_scores_all, top_indices_all, "
|
538 |
df['Timecode'].iloc[top_indices_all].values)
|
539 |
-
anomaly_plot_comp = plot_anomaly_scores(df, anomaly_scores_comp, top_indices_comp, "
|
540 |
df['Timecode'].iloc[top_indices_comp].values)
|
541 |
emotion_plots = [
|
542 |
plot_emotion(df, emotion,
|
@@ -596,7 +630,7 @@ iface = gr.Interface(
|
|
596 |
gr.Plot(label="Happy Anomalies"),
|
597 |
gr.Plot(label="Surprise Anomalies"),
|
598 |
gr.Plot(label="Neutral Anomalies"),
|
599 |
-
gr.Gallery(label="Detected Persons", columns=[5], rows=[2], height="auto")
|
600 |
],
|
601 |
title="Facial Expressions Anomaly Detection",
|
602 |
description="""
|
|
|
245 |
anomalies = anomaly_scores > threshold
|
246 |
return anomalies, np.where(anomalies)[0]
|
247 |
|
248 |
+
|
249 |
+
def timecode_to_seconds(timecode):
|
250 |
+
h, m, s = map(float, timecode.split(':'))
|
251 |
+
return h * 3600 + m * 60 + s
|
252 |
+
|
253 |
+
|
254 |
+
def group_similar_timecodes(timecodes, scores, threshold_seconds=5):
|
255 |
+
grouped = []
|
256 |
+
current_group = []
|
257 |
+
|
258 |
+
for i, (timecode, score) in enumerate(zip(timecodes, scores)):
|
259 |
+
if not current_group or abs(
|
260 |
+
timecode_to_seconds(timecode) - timecode_to_seconds(current_group[0][0])) <= threshold_seconds:
|
261 |
+
current_group.append((timecode, score, i))
|
262 |
+
else:
|
263 |
+
grouped.append(current_group)
|
264 |
+
current_group = [(timecode, score, i)]
|
265 |
+
|
266 |
+
if current_group:
|
267 |
+
grouped.append(current_group)
|
268 |
+
|
269 |
+
return grouped
|
270 |
+
|
271 |
class LSTMAutoencoder(nn.Module):
|
272 |
def __init__(self, input_size, hidden_size=64, num_layers=2):
|
273 |
super(LSTMAutoencoder, self).__init__()
|
|
|
372 |
return np.full_like(scores, 100)
|
373 |
return ((scores - min_score) / (max_score - min_score)) * 100
|
374 |
|
|
|
375 |
def plot_anomaly_scores(df, anomaly_scores, top_indices, title, timecodes):
|
376 |
plt.figure(figsize=(16, 8), dpi=500)
|
377 |
fig, ax = plt.subplots(figsize=(16, 8))
|
|
|
393 |
top_indices = [idx for idx in top_indices if idx > 0]
|
394 |
ax.scatter(df['Seconds'].iloc[top_indices], normalized_scores[top_indices], color='red', s=50, zorder=5)
|
395 |
|
396 |
+
# Group similar timecodes
|
397 |
+
grouped_timecodes = group_similar_timecodes([df['Timecode'].iloc[idx] for idx in top_indices],
|
398 |
+
normalized_scores[top_indices])
|
399 |
+
|
400 |
+
# Add timecode annotations for grouped timecodes
|
401 |
+
for group in grouped_timecodes:
|
402 |
+
max_score_idx = max(range(len(group)), key=lambda i: group[i][1])
|
403 |
+
timecode, score, idx = group[max_score_idx]
|
404 |
ax.annotate(timecode,
|
405 |
+
(df['Seconds'].iloc[top_indices[idx]], score),
|
406 |
xytext=(5, 5), textcoords='offset points',
|
407 |
fontsize=6, color='red')
|
408 |
|
|
|
439 |
top_indices = [idx for idx in top_indices if idx > 0]
|
440 |
ax.scatter(df['Seconds'].iloc[top_indices], anomaly_scores[top_indices], color='red', s=50, zorder=5)
|
441 |
|
442 |
+
# Group similar timecodes
|
443 |
+
grouped_timecodes = group_similar_timecodes([df['Timecode'].iloc[idx] for idx in top_indices],
|
444 |
+
anomaly_scores[top_indices])
|
445 |
+
|
446 |
+
# Add timecode annotations for grouped timecodes
|
447 |
+
for group in grouped_timecodes:
|
448 |
+
max_score_idx = max(range(len(group)), key=lambda i: group[i][1])
|
449 |
+
timecode, score, idx = group[max_score_idx]
|
450 |
ax.annotate(timecode,
|
451 |
+
(df['Seconds'].iloc[top_indices[idx]], score),
|
452 |
xytext=(5, 5), textcoords='offset points',
|
453 |
fontsize=6, color='red')
|
454 |
|
|
|
568 |
|
569 |
progress(0.95, "Generating plots")
|
570 |
try:
|
571 |
+
anomaly_plot_all = plot_anomaly_scores(df, anomaly_scores_all, top_indices_all, "Facial Features + Emotions",
|
572 |
df['Timecode'].iloc[top_indices_all].values)
|
573 |
+
anomaly_plot_comp = plot_anomaly_scores(df, anomaly_scores_comp, top_indices_comp, "Facial Features",
|
574 |
df['Timecode'].iloc[top_indices_comp].values)
|
575 |
emotion_plots = [
|
576 |
plot_emotion(df, emotion,
|
|
|
630 |
gr.Plot(label="Happy Anomalies"),
|
631 |
gr.Plot(label="Surprise Anomalies"),
|
632 |
gr.Plot(label="Neutral Anomalies"),
|
633 |
+
gr.Gallery(label="Random Samples of Detected Persons", columns=[5], rows=[2], height="auto")
|
634 |
],
|
635 |
title="Facial Expressions Anomaly Detection",
|
636 |
description="""
|