Spaces:
Sleeping
Sleeping
MohamedMotaz
commited on
Commit
•
6f351c2
1
Parent(s):
fa0c77d
V2
Browse files- face_emotion_pipeline.py +110 -25
face_emotion_pipeline.py
CHANGED
@@ -3,11 +3,12 @@ import os
|
|
3 |
import numpy as np
|
4 |
from moviepy.editor import VideoFileClip
|
5 |
from retinaface import RetinaFace
|
6 |
-
from
|
7 |
|
8 |
-
# Initialize Py-Feat detector
|
9 |
-
detector = Detector(au_model='xgb')
|
10 |
|
|
|
|
|
|
|
11 |
# Face Detection Function
|
12 |
def detect_faces(frame):
|
13 |
""" Detect faces in the frame using RetinaFace """
|
@@ -23,37 +24,36 @@ def detect_faces(frame):
|
|
23 |
face_list.append(face_dict)
|
24 |
return face_list
|
25 |
return []
|
26 |
-
|
27 |
# Annotation Function
|
28 |
def annotate_frame(frame, faces):
|
29 |
-
""" Annotate the frame with recognized emotions using
|
30 |
for face in faces:
|
31 |
x, y, w, h = face['box']
|
32 |
face_image = frame[y:y+h, x:x+w] # Extract face region from frame
|
33 |
emotion = classify_emotions(face_image)
|
34 |
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
|
35 |
cv2.putText(frame, emotion, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 0, 0), 2)
|
36 |
-
|
37 |
# Emotion Classification Function
|
38 |
def classify_emotions(face_image):
|
39 |
-
""" Classify emotions for the given face image using
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
emotion = result.emotions.idxmax(axis=1).values[0] # Get the most likely emotion
|
44 |
else:
|
45 |
emotion = 'Unknown'
|
46 |
return emotion
|
47 |
-
|
48 |
# Process Video Frames
|
49 |
def process_video_frames(video_path, temp_output_path, frame_skip=5):
|
50 |
# Load the video
|
51 |
video_clip = VideoFileClip(video_path)
|
52 |
fps = video_clip.fps
|
53 |
-
|
54 |
# Initialize output video writer
|
55 |
out = cv2.VideoWriter(temp_output_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (int(video_clip.size[0]), int(video_clip.size[1])))
|
56 |
-
|
57 |
# Iterate through frames, detect faces, and annotate emotions
|
58 |
frame_count = 0
|
59 |
for frame in video_clip.iter_frames():
|
@@ -64,12 +64,12 @@ def process_video_frames(video_path, temp_output_path, frame_skip=5):
|
|
64 |
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # Convert RGB to BGR for OpenCV RGB2BGR
|
65 |
out.write(frame)
|
66 |
frame_count += 1
|
67 |
-
|
68 |
# Release resources and cleanup
|
69 |
out.release()
|
70 |
cv2.destroyAllWindows()
|
71 |
video_clip.close()
|
72 |
-
|
73 |
# Add Audio to Processed Video
|
74 |
def add_audio_to_video(original_video_path, processed_video_path, output_path):
|
75 |
try:
|
@@ -82,42 +82,127 @@ def add_audio_to_video(original_video_path, processed_video_path, output_path):
|
|
82 |
finally:
|
83 |
original_clip.close()
|
84 |
processed_clip.close()
|
85 |
-
|
86 |
# Process Video
|
87 |
def process_video(video_path, output_path):
|
88 |
temp_output_path = 'temp_output_video.mp4'
|
89 |
-
|
90 |
# Process video frames and save to a temporary file
|
91 |
process_video_frames(video_path, temp_output_path, frame_skip=5) # Adjust frame_skip as needed
|
92 |
-
|
93 |
# Add audio to the processed video
|
94 |
add_audio_to_video(video_path, temp_output_path, output_path)
|
95 |
-
|
96 |
# Process Image
|
97 |
def process_image(input_path, output_path):
|
98 |
# Ensure output path has a valid extension
|
99 |
if not output_path.lower().endswith(('.jpg', '.jpeg', '.png')):
|
100 |
output_path += '.jpg' # Default to .jpg if no valid extension is found
|
101 |
-
|
102 |
# Step 1: Read input image
|
103 |
image = cv2.imread(input_path)
|
104 |
if image is None:
|
105 |
print(f"Error: Unable to read image at '{input_path}'")
|
106 |
return
|
107 |
-
|
108 |
# Step 2: Detect faces and annotate emotions
|
109 |
faces = detect_faces(image)
|
110 |
annotate_frame(image, faces)
|
111 |
-
|
112 |
# Step 3: Write annotated image to output path
|
113 |
cv2.imwrite(output_path, image)
|
114 |
-
|
115 |
# Step 4: Combine input and output images horizontally
|
116 |
input_image = cv2.imread(input_path)
|
117 |
combined_image = cv2.hconcat([input_image, image])
|
118 |
combined_image = cv2.cvtColor(combined_image, cv2.COLOR_BGR2RGB)
|
119 |
-
|
120 |
# Step 5: Save the combined image
|
121 |
combined_output_path = os.path.splitext(output_path)[0] + '_combined.jpg'
|
122 |
|
123 |
cv2.imwrite(combined_output_path, combined_image)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
import numpy as np
|
4 |
from moviepy.editor import VideoFileClip
|
5 |
from retinaface import RetinaFace
|
6 |
+
from hsemotion.facial_emotions import HSEmotionRecognizer
|
7 |
|
|
|
|
|
8 |
|
9 |
+
# Initialize recognizer
|
10 |
+
recognizer = HSEmotionRecognizer(model_name='enet_b0_8_best_vgaf', device='cpu')
|
11 |
+
|
12 |
# Face Detection Function
|
13 |
def detect_faces(frame):
|
14 |
""" Detect faces in the frame using RetinaFace """
|
|
|
24 |
face_list.append(face_dict)
|
25 |
return face_list
|
26 |
return []
|
27 |
+
|
28 |
# Annotation Function
|
29 |
def annotate_frame(frame, faces):
|
30 |
+
""" Annotate the frame with recognized emotions using global recognizer """
|
31 |
for face in faces:
|
32 |
x, y, w, h = face['box']
|
33 |
face_image = frame[y:y+h, x:x+w] # Extract face region from frame
|
34 |
emotion = classify_emotions(face_image)
|
35 |
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
|
36 |
cv2.putText(frame, emotion, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 0, 0), 2)
|
37 |
+
|
38 |
# Emotion Classification Function
|
39 |
def classify_emotions(face_image):
|
40 |
+
""" Classify emotions for the given face image using global recognizer """
|
41 |
+
results = recognizer.predict_emotions(face_image)
|
42 |
+
if results:
|
43 |
+
emotion = results[0] # Get the most likely emotion
|
|
|
44 |
else:
|
45 |
emotion = 'Unknown'
|
46 |
return emotion
|
47 |
+
|
48 |
# Process Video Frames
|
49 |
def process_video_frames(video_path, temp_output_path, frame_skip=5):
|
50 |
# Load the video
|
51 |
video_clip = VideoFileClip(video_path)
|
52 |
fps = video_clip.fps
|
53 |
+
|
54 |
# Initialize output video writer
|
55 |
out = cv2.VideoWriter(temp_output_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (int(video_clip.size[0]), int(video_clip.size[1])))
|
56 |
+
|
57 |
# Iterate through frames, detect faces, and annotate emotions
|
58 |
frame_count = 0
|
59 |
for frame in video_clip.iter_frames():
|
|
|
64 |
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # Convert RGB to BGR for OpenCV RGB2BGR
|
65 |
out.write(frame)
|
66 |
frame_count += 1
|
67 |
+
|
68 |
# Release resources and cleanup
|
69 |
out.release()
|
70 |
cv2.destroyAllWindows()
|
71 |
video_clip.close()
|
72 |
+
|
73 |
# Add Audio to Processed Video
|
74 |
def add_audio_to_video(original_video_path, processed_video_path, output_path):
|
75 |
try:
|
|
|
82 |
finally:
|
83 |
original_clip.close()
|
84 |
processed_clip.close()
|
85 |
+
|
86 |
# Process Video
|
87 |
def process_video(video_path, output_path):
|
88 |
temp_output_path = 'temp_output_video.mp4'
|
89 |
+
|
90 |
# Process video frames and save to a temporary file
|
91 |
process_video_frames(video_path, temp_output_path, frame_skip=5) # Adjust frame_skip as needed
|
92 |
+
|
93 |
# Add audio to the processed video
|
94 |
add_audio_to_video(video_path, temp_output_path, output_path)
|
95 |
+
|
96 |
# Process Image
|
97 |
def process_image(input_path, output_path):
|
98 |
# Ensure output path has a valid extension
|
99 |
if not output_path.lower().endswith(('.jpg', '.jpeg', '.png')):
|
100 |
output_path += '.jpg' # Default to .jpg if no valid extension is found
|
101 |
+
|
102 |
# Step 1: Read input image
|
103 |
image = cv2.imread(input_path)
|
104 |
if image is None:
|
105 |
print(f"Error: Unable to read image at '{input_path}'")
|
106 |
return
|
107 |
+
|
108 |
# Step 2: Detect faces and annotate emotions
|
109 |
faces = detect_faces(image)
|
110 |
annotate_frame(image, faces)
|
111 |
+
|
112 |
# Step 3: Write annotated image to output path
|
113 |
cv2.imwrite(output_path, image)
|
114 |
+
|
115 |
# Step 4: Combine input and output images horizontally
|
116 |
input_image = cv2.imread(input_path)
|
117 |
combined_image = cv2.hconcat([input_image, image])
|
118 |
combined_image = cv2.cvtColor(combined_image, cv2.COLOR_BGR2RGB)
|
119 |
+
|
120 |
# Step 5: Save the combined image
|
121 |
combined_output_path = os.path.splitext(output_path)[0] + '_combined.jpg'
|
122 |
|
123 |
cv2.imwrite(combined_output_path, combined_image)
|
124 |
+
|
125 |
+
|
126 |
+
###########################
|
127 |
+
|
128 |
+
# recognizer = HSEmotionRecognizer(model_name='enet_b0_8_best_vgaf', device='cpu')
|
129 |
+
|
130 |
+
# def detect_faces(frame):
|
131 |
+
# faces = RetinaFace.detect_faces(frame)
|
132 |
+
# if isinstance(faces, dict):
|
133 |
+
# face_list = []
|
134 |
+
# for key in faces.keys():
|
135 |
+
# face = faces[key]
|
136 |
+
# facial_area = face['facial_area']
|
137 |
+
# face_dict = {
|
138 |
+
# 'box': (facial_area[0], facial_area[1], facial_area[2] - facial_area[0], facial_area[3] - facial_area[1])
|
139 |
+
# }
|
140 |
+
# face_list.append(face_dict)
|
141 |
+
# return face_list
|
142 |
+
# return []
|
143 |
+
|
144 |
+
# def annotate_frame(frame, faces):
|
145 |
+
# frame_writable = np.copy(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) # Make a writable copy of the frame
|
146 |
+
# for face in faces:
|
147 |
+
# x, y, w, h = face['box']
|
148 |
+
# face_image = frame_writable[y:y+h, x:x+w]
|
149 |
+
# emotion = classify_emotions(face_image)
|
150 |
+
# cv2.rectangle(frame_writable, (x, y), (x+w, y+h), (255, 0, 0), 2)
|
151 |
+
# cv2.putText(frame_writable, emotion, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 0, 0), 2)
|
152 |
+
# return frame_writable
|
153 |
+
|
154 |
+
# def classify_emotions(face_image):
|
155 |
+
# results = recognizer.predict_emotions(face_image)
|
156 |
+
# if results:
|
157 |
+
# emotion = results[0]
|
158 |
+
# else:
|
159 |
+
# emotion = 'Unknown'
|
160 |
+
# return emotion
|
161 |
+
|
162 |
+
# def process_video_frames(video_path, temp_output_path, frame_skip=5):
|
163 |
+
# video_clip = VideoFileClip(video_path)
|
164 |
+
# fps = video_clip.fps
|
165 |
+
# out = cv2.VideoWriter(temp_output_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (int(video_clip.size[0]), int(video_clip.size[1])))
|
166 |
+
# frame_count = 0
|
167 |
+
# for frame in video_clip.iter_frames():
|
168 |
+
# if frame_count % frame_skip == 0:
|
169 |
+
# faces = detect_faces(frame)
|
170 |
+
# annotated_frame = annotate_frame(frame, faces)
|
171 |
+
# frame = cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB)
|
172 |
+
# out.write(frame)
|
173 |
+
# frame_count += 1
|
174 |
+
# out.release()
|
175 |
+
# cv2.destroyAllWindows()
|
176 |
+
# video_clip.close()
|
177 |
+
|
178 |
+
# def add_audio_to_video(original_video_path, processed_video_path, output_path):
|
179 |
+
# try:
|
180 |
+
# original_clip = VideoFileClip(original_video_path)
|
181 |
+
# processed_clip = VideoFileClip(processed_video_path)
|
182 |
+
# final_clip = processed_clip.set_audio(original_clip.audio)
|
183 |
+
# final_clip.write_videofile(output_path, codec='libx264', audio_codec='aac')
|
184 |
+
# except Exception as e:
|
185 |
+
# print(f"Error while combining with audio: {e}")
|
186 |
+
# finally:
|
187 |
+
# original_clip.close()
|
188 |
+
# processed_clip.close()
|
189 |
+
|
190 |
+
# def process_video(video_path, output_path):
|
191 |
+
# temp_output_path = 'temp_output_video.mp4'
|
192 |
+
# process_video_frames(video_path, temp_output_path, frame_skip=5)
|
193 |
+
# add_audio_to_video(video_path, temp_output_path, output_path)
|
194 |
+
|
195 |
+
# def process_image(input_path, output_path):
|
196 |
+
# image = cv2.imread(input_path)
|
197 |
+
# if image is None:
|
198 |
+
# print(f"Error: Unable to read image at '{input_path}'")
|
199 |
+
# return
|
200 |
+
# faces = detect_faces(image)
|
201 |
+
# annotated_image = annotate_frame(image, faces)
|
202 |
+
# cv2.imwrite(output_path, annotated_image)
|
203 |
+
# input_image = cv2.imread(input_path)
|
204 |
+
# combined_image = cv2.hconcat([input_image, annotated_image])
|
205 |
+
# cv2.imwrite(output_path, combined_image)
|
206 |
+
|
207 |
+
|
208 |
+
###################################################
|