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_"):
|