MohamedMotaz commited on
Commit
6f351c2
1 Parent(s): fa0c77d
Files changed (1) hide show
  1. 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 feat import Detector
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 Py-Feat """
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 Py-Feat """
40
- face_image_rgb = cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB)
41
- result = detector.detect_image(face_image_rgb)
42
- if result is not None and len(result) > 0:
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
+ ###################################################