Spaces:
Runtime error
Runtime error
Update video_processing.py
Browse files- video_processing.py +18 -40
video_processing.py
CHANGED
|
@@ -47,7 +47,6 @@ def process_frames(frames_folder, aligned_faces_folder, frame_count, progress):
|
|
| 47 |
embeddings_by_frame = {}
|
| 48 |
posture_scores_by_frame = {}
|
| 49 |
posture_landmarks_by_frame = {}
|
| 50 |
-
facial_landmarks_by_frame = {}
|
| 51 |
aligned_face_paths = []
|
| 52 |
frame_files = sorted([f for f in os.listdir(frames_folder) if f.endswith('.jpg')])
|
| 53 |
|
|
@@ -68,23 +67,16 @@ def process_frames(frames_folder, aligned_faces_folder, frame_count, progress):
|
|
| 68 |
face = frame[y1:y2, x1:x2]
|
| 69 |
if face.size > 0:
|
| 70 |
face_rgb = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
if aligned_face is not None:
|
| 78 |
-
aligned_face_resized = cv2.resize(aligned_face, (160, 160))
|
| 79 |
-
output_path = os.path.join(aligned_faces_folder, f"frame_{frame_num}_face.jpg")
|
| 80 |
-
cv2.imwrite(output_path, aligned_face_resized)
|
| 81 |
-
aligned_face_paths.append(output_path)
|
| 82 |
-
embedding = get_face_embedding(aligned_face_resized)
|
| 83 |
-
embeddings_by_frame[frame_num] = embedding
|
| 84 |
|
| 85 |
progress((i + 1) / len(frame_files), f"Processing frame {i + 1} of {len(frame_files)}")
|
| 86 |
|
| 87 |
-
return embeddings_by_frame, posture_scores_by_frame, posture_landmarks_by_frame, aligned_face_paths
|
| 88 |
|
| 89 |
|
| 90 |
def process_video(video_path, anomaly_threshold, desired_fps, progress=None):
|
|
@@ -93,9 +85,9 @@ def process_video(video_path, anomaly_threshold, desired_fps, progress=None):
|
|
| 93 |
os.makedirs(output_folder, exist_ok=True)
|
| 94 |
|
| 95 |
with tempfile.TemporaryDirectory() as temp_dir:
|
| 96 |
-
|
| 97 |
organized_faces_folder = os.path.join(temp_dir, 'organized_faces')
|
| 98 |
-
os.makedirs(
|
| 99 |
os.makedirs(organized_faces_folder, exist_ok=True)
|
| 100 |
|
| 101 |
clip = VideoFileClip(video_path)
|
|
@@ -112,12 +104,12 @@ def process_video(video_path, anomaly_threshold, desired_fps, progress=None):
|
|
| 112 |
|
| 113 |
progress(1, "Frame extraction complete")
|
| 114 |
progress(0.3, "Processing frames")
|
| 115 |
-
embeddings_by_frame, posture_scores_by_frame, posture_landmarks_by_frame,
|
| 116 |
-
frames_folder,
|
| 117 |
frame_count,
|
| 118 |
progress)
|
| 119 |
|
| 120 |
-
if not
|
| 121 |
raise ValueError("No faces were extracted from the video.")
|
| 122 |
|
| 123 |
progress(0.6, "Clustering faces")
|
|
@@ -129,10 +121,10 @@ def process_video(video_path, anomaly_threshold, desired_fps, progress=None):
|
|
| 129 |
cluster_by_frame = {frame_num: cluster for frame_num, cluster in zip(embeddings_by_frame.keys(), clusters)}
|
| 130 |
|
| 131 |
progress(0.65, "Organizing faces")
|
| 132 |
-
organize_faces_by_person(embeddings_by_frame, clusters,
|
| 133 |
|
| 134 |
progress(0.7, "Saving person data")
|
| 135 |
-
df, largest_cluster =
|
| 136 |
original_fps, temp_dir, video_duration)
|
| 137 |
|
| 138 |
df['Seconds'] = df['Timecode'].apply(
|
|
@@ -223,7 +215,7 @@ def process_video(video_path, anomaly_threshold, desired_fps, progress=None):
|
|
| 223 |
|
| 224 |
anomaly_faces_embeddings = []
|
| 225 |
for frame in anomaly_frames_embeddings:
|
| 226 |
-
face_path = os.path.join(
|
| 227 |
if os.path.exists(face_path):
|
| 228 |
face_img = cv2.imread(face_path)
|
| 229 |
if face_img is not None:
|
|
@@ -265,28 +257,14 @@ def process_video(video_path, anomaly_threshold, desired_fps, progress=None):
|
|
| 265 |
face_samples["most_frequent"],
|
| 266 |
anomaly_faces_embeddings,
|
| 267 |
anomaly_frames_posture_images,
|
| 268 |
-
|
| 269 |
frames_folder,
|
| 270 |
stacked_heatmap
|
| 271 |
|
| 272 |
)
|
| 273 |
|
| 274 |
|
| 275 |
-
def
|
| 276 |
-
nose_tip = landmarks[4]
|
| 277 |
-
left_chin = landmarks[234]
|
| 278 |
-
right_chin = landmarks[454]
|
| 279 |
-
nose_to_left = [left_chin.x - nose_tip.x, left_chin.y - nose_tip.y]
|
| 280 |
-
nose_to_right = [right_chin.x - nose_tip.x, right_chin.y - nose_tip.y]
|
| 281 |
-
dot_product = nose_to_left[0] * nose_to_right[0] + nose_to_left[1] * nose_to_right[1]
|
| 282 |
-
magnitude_left = math.sqrt(nose_to_left[0] ** 2 + nose_to_left[1] ** 2)
|
| 283 |
-
magnitude_right = math.sqrt(nose_to_right[0] ** 2 + nose_to_right[1] ** 2)
|
| 284 |
-
cos_angle = dot_product / (magnitude_left * magnitude_right)
|
| 285 |
-
angle = math.acos(cos_angle)
|
| 286 |
-
angle_degrees = math.degrees(angle)
|
| 287 |
-
return abs(180 - angle_degrees) < threshold
|
| 288 |
-
|
| 289 |
-
def save_person_data_to_csv(embeddings_by_frame, clusters, desired_fps, original_fps, output_folder, video_duration):
|
| 290 |
person_data = {}
|
| 291 |
|
| 292 |
for (frame_num, embedding), cluster in zip(embeddings_by_frame.items(), clusters):
|
|
@@ -319,7 +297,7 @@ def save_person_data_to_csv(embeddings_by_frame, clusters, desired_fps, original
|
|
| 319 |
|
| 320 |
return df, largest_cluster
|
| 321 |
|
| 322 |
-
def get_all_face_samples(organized_faces_folder, output_folder, largest_cluster, max_samples=
|
| 323 |
face_samples = {"most_frequent": [], "others": []}
|
| 324 |
for cluster_folder in sorted(os.listdir(organized_faces_folder)):
|
| 325 |
if cluster_folder.startswith("person_"):
|
|
|
|
| 47 |
embeddings_by_frame = {}
|
| 48 |
posture_scores_by_frame = {}
|
| 49 |
posture_landmarks_by_frame = {}
|
|
|
|
| 50 |
aligned_face_paths = []
|
| 51 |
frame_files = sorted([f for f in os.listdir(frames_folder) if f.endswith('.jpg')])
|
| 52 |
|
|
|
|
| 67 |
face = frame[y1:y2, x1:x2]
|
| 68 |
if face.size > 0:
|
| 69 |
face_rgb = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)
|
| 70 |
+
face_resized = cv2.resize(face_rgb, (160, 160))
|
| 71 |
+
output_path = os.path.join(faces_folder, f"frame_{frame_num}_face.jpg")
|
| 72 |
+
cv2.imwrite(output_path, face_resized_resized)
|
| 73 |
+
face_paths.append(output_path)
|
| 74 |
+
embedding = get_face_embedding(face_resized)
|
| 75 |
+
embeddings_by_frame[frame_num] = embedding
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
|
| 77 |
progress((i + 1) / len(frame_files), f"Processing frame {i + 1} of {len(frame_files)}")
|
| 78 |
|
| 79 |
+
return embeddings_by_frame, posture_scores_by_frame, posture_landmarks_by_frame, aligned_face_paths
|
| 80 |
|
| 81 |
|
| 82 |
def process_video(video_path, anomaly_threshold, desired_fps, progress=None):
|
|
|
|
| 85 |
os.makedirs(output_folder, exist_ok=True)
|
| 86 |
|
| 87 |
with tempfile.TemporaryDirectory() as temp_dir:
|
| 88 |
+
faces_folder = os.path.join(temp_dir, 'faces')
|
| 89 |
organized_faces_folder = os.path.join(temp_dir, 'organized_faces')
|
| 90 |
+
os.makedirs(faces_folder, exist_ok=True)
|
| 91 |
os.makedirs(organized_faces_folder, exist_ok=True)
|
| 92 |
|
| 93 |
clip = VideoFileClip(video_path)
|
|
|
|
| 104 |
|
| 105 |
progress(1, "Frame extraction complete")
|
| 106 |
progress(0.3, "Processing frames")
|
| 107 |
+
embeddings_by_frame, posture_scores_by_frame, posture_landmarks_by_frame, face_paths = process_frames(
|
| 108 |
+
frames_folder, faces_folder,
|
| 109 |
frame_count,
|
| 110 |
progress)
|
| 111 |
|
| 112 |
+
if not face_paths:
|
| 113 |
raise ValueError("No faces were extracted from the video.")
|
| 114 |
|
| 115 |
progress(0.6, "Clustering faces")
|
|
|
|
| 121 |
cluster_by_frame = {frame_num: cluster for frame_num, cluster in zip(embeddings_by_frame.keys(), clusters)}
|
| 122 |
|
| 123 |
progress(0.65, "Organizing faces")
|
| 124 |
+
organize_faces_by_person(embeddings_by_frame, clusters, faces_folder, organized_faces_folder)
|
| 125 |
|
| 126 |
progress(0.7, "Saving person data")
|
| 127 |
+
df, largest_cluster = save_person_data(embeddings_by_frame, clusters, desired_fps,
|
| 128 |
original_fps, temp_dir, video_duration)
|
| 129 |
|
| 130 |
df['Seconds'] = df['Timecode'].apply(
|
|
|
|
| 215 |
|
| 216 |
anomaly_faces_embeddings = []
|
| 217 |
for frame in anomaly_frames_embeddings:
|
| 218 |
+
face_path = os.path.join(faces_folder, f"frame_{frame}_face.jpg")
|
| 219 |
if os.path.exists(face_path):
|
| 220 |
face_img = cv2.imread(face_path)
|
| 221 |
if face_img is not None:
|
|
|
|
| 257 |
face_samples["most_frequent"],
|
| 258 |
anomaly_faces_embeddings,
|
| 259 |
anomaly_frames_posture_images,
|
| 260 |
+
faces_folder,
|
| 261 |
frames_folder,
|
| 262 |
stacked_heatmap
|
| 263 |
|
| 264 |
)
|
| 265 |
|
| 266 |
|
| 267 |
+
def save_person_data(embeddings_by_frame, clusters, desired_fps, original_fps, output_folder, video_duration):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 268 |
person_data = {}
|
| 269 |
|
| 270 |
for (frame_num, embedding), cluster in zip(embeddings_by_frame.items(), clusters):
|
|
|
|
| 297 |
|
| 298 |
return df, largest_cluster
|
| 299 |
|
| 300 |
+
def get_all_face_samples(organized_faces_folder, output_folder, largest_cluster, max_samples=200):
|
| 301 |
face_samples = {"most_frequent": [], "others": []}
|
| 302 |
for cluster_folder in sorted(os.listdir(organized_faces_folder)):
|
| 303 |
if cluster_folder.startswith("person_"):
|