Rahulk2197 commited on
Commit
24b6b17
1 Parent(s): 240753e

Upload 8 files

Browse files
Files changed (4) hide show
  1. .gitattributes +1 -0
  2. app.py +281 -131
  3. functions.py +3 -9
  4. incept_v3_10fps_full_0.4.keras +3 -0
.gitattributes CHANGED
@@ -36,3 +36,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
36
  incept_v3_10fps_full_dp0.4.keras filter=lfs diff=lfs merge=lfs -text
37
  res10_300x300_ssd_iter_140000.caffemodel filter=lfs diff=lfs merge=lfs -text
38
  shape_predictor_68_face_landmarks.dat filter=lfs diff=lfs merge=lfs -text
 
 
36
  incept_v3_10fps_full_dp0.4.keras filter=lfs diff=lfs merge=lfs -text
37
  res10_300x300_ssd_iter_140000.caffemodel filter=lfs diff=lfs merge=lfs -text
38
  shape_predictor_68_face_landmarks.dat filter=lfs diff=lfs merge=lfs -text
39
+ incept_v3_10fps_full_0.4.keras filter=lfs diff=lfs merge=lfs -text
app.py CHANGED
@@ -1,131 +1,281 @@
1
-
2
- import os
3
- os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
4
-
5
- import streamlit as st
6
- import cv2
7
- from tqdm import tqdm
8
- import numpy as np
9
- import tensorflow as tf
10
- import pandas as pd
11
- from tempfile import NamedTemporaryFile
12
- from functions import *
13
-
14
- threshold = [
15
- 0.6827917, 0.7136434, 0.510756, 0.56771123, 0.49417764, 0.45892453,
16
- 0.32996163, 0.5038406, 0.44855, 0.32959282, 0.45619836, 0.4969851
17
- ]
18
-
19
- au_to_movements = {
20
- 'au1': 'inner brow raiser',
21
- 'au2': 'outer brow raiser',
22
- 'au4': 'brow lowerer',
23
- 'au5': 'upper lid raiser',
24
- 'au6': 'cheek raiser',
25
- 'au9': 'nose wrinkler',
26
- 'au12': 'lip corner puller',
27
- 'au15': 'lip corner depressor',
28
- 'au17': 'chin raiser',
29
- 'au20': 'lip stretcher',
30
- 'au25': 'lips part',
31
- 'au26': 'jaw drop'
32
- }
33
-
34
- au_labels = [
35
- "au1", "au12", "au15", "au17", "au2", "au20",
36
- "au25", "au26", "au4", "au5", "au6", "au9"
37
- ]
38
-
39
- col = [au_to_movements[i] for i in au_labels]
40
-
41
- def binary_focal_loss(gamma=2.0, alpha=0.25):
42
- def focal_loss(y_true, y_pred):
43
- epsilon = tf.keras.backend.epsilon()
44
- y_pred = tf.clip_by_value(y_pred, epsilon, 1.0 - epsilon)
45
- fl = - alpha * (y_true * (1 - y_pred)**gamma * tf.math.log(y_pred)
46
- + (1 - y_true) * (y_pred**gamma) * tf.math.log(1 - y_pred))
47
- return tf.reduce_mean(fl, axis=-1)
48
- return focal_loss
49
-
50
- loss = binary_focal_loss(gamma=2.0, alpha=0.25)
51
-
52
- # Function to read video frames into a list and get timestamps
53
- def read_video_frames(video_path):
54
- cap = cv2.VideoCapture(video_path)
55
- frames = []
56
- faces=[]
57
- timestamps = []
58
- fps = cap.get(cv2.CAP_PROP_FPS)
59
- while True:
60
- ret, frame = cap.read()
61
- if not ret:
62
- break
63
- face=get_face(frame)
64
- if face is not None:
65
- faces.append(face)
66
- frames.append(frame)
67
- timestamps.append(cap.get(cv2.CAP_PROP_POS_MSEC) / 1000.0) # Time in seconds
68
-
69
- cap.release()
70
- return frames,faces, timestamps
71
-
72
- # Function to process frames and make predictions
73
- def process_frames(frames, model):
74
- frame_array = np.array(frames)
75
- preds = model.predict(frame_array)
76
- predicted_labels = np.zeros_like(preds, dtype='int')
77
- for i in range(12):
78
- predicted_labels[:, i] = (preds[:, i] > threshold[i]).astype(int)
79
- return preds
80
-
81
- # Function to save predictions to a CSV file with timestamps
82
- def save_predictions_to_csv(predictions, timestamps, filename="predictions.csv"):
83
- df = pd.DataFrame(predictions, columns=col)
84
- df['timestamp'] = timestamps
85
- df.set_index('timestamp', inplace=True)
86
- df.to_csv(filename)
87
- return filename
88
-
89
- # Load your Keras model
90
- def load_model():
91
- model = tf.keras.models.load_model('incept_v3_10fps_full_dp0.4.keras',
92
- custom_objects={'binary_focal_loss': binary_focal_loss})
93
- return model
94
-
95
- # Streamlit app
96
- def main():
97
- st.title("Facial action unit detection")
98
-
99
- uploaded_file = st.file_uploader("Upload a video file", type=["mp4", "avi", "mov"])
100
-
101
- if uploaded_file is not None:
102
- with NamedTemporaryFile(delete=False) as tmp_file:
103
- tmp_file.write(uploaded_file.read())
104
- video_path = tmp_file.name
105
-
106
- model = load_model()
107
-
108
- if st.button("Predict"):
109
- st.text("Reading video frames...")
110
- frames,faces, timestamps = read_video_frames(video_path)
111
- st.text(f"Total frames in which faces found: {len(faces)}")
112
-
113
- st.text("Processing frames and making predictions...")
114
- predictions = process_frames(faces, model)
115
- st.text("Predictions completed!")
116
-
117
- csv_file_path = save_predictions_to_csv(predictions, timestamps)
118
- st.text("Predictions saved to CSV!")
119
-
120
- with open(csv_file_path, "rb") as f:
121
- st.download_button(
122
- label="Download CSV",
123
- data=f,
124
- file_name="predictions.csv",
125
- mime="text/csv"
126
- )
127
-
128
- os.remove(video_path)
129
-
130
- if __name__ == "__main__":
131
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import os
2
+ # os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
3
+
4
+ # import streamlit as st
5
+ # import cv2
6
+ # from tqdm import tqdm
7
+ # import numpy as np
8
+ # import tensorflow as tf
9
+ # import pandas as pd
10
+ # from tempfile import NamedTemporaryFile
11
+ # from functions import *
12
+
13
+ # threshold=[0.6827917,
14
+ # 0.7136434,
15
+ # 0.510756,
16
+ # 0.56771123,
17
+ # 0.49417764,
18
+ # 0.45892453,
19
+ # 0.32996163,
20
+ # 0.5038406,
21
+ # 0.44855,
22
+ # 0.32959282,
23
+ # 0.45619836,
24
+ # 0.4969851]
25
+ # au_to_movements= {
26
+ # 'au1': 'inner brow raiser',
27
+ # 'au2': 'outer brow raiser',
28
+ # 'au4': 'brow lowerer',
29
+ # 'au5': 'upper lid raiser',
30
+ # 'au6': 'cheek raiser',
31
+ # 'au9': 'nose wrinkler',
32
+ # 'au12': 'lip corner puller',
33
+ # 'au15': 'lip corner depressor',
34
+ # 'au17': 'chin raiser',
35
+ # 'au20': 'lip stretcher',
36
+ # 'au25': 'lips part',
37
+ # 'au26': 'jaw drop'
38
+ # }
39
+ # au_labels = [
40
+ # "au1",
41
+ # "au12",
42
+ # "au15",
43
+ # "au17",
44
+ # "au2",
45
+ # "au20",
46
+ # "au25",
47
+ # "au26",
48
+ # "au4",
49
+ # "au5",
50
+ # "au6",
51
+ # "au9"
52
+ # ]
53
+ # col=[au_to_movements[i] for i in au_labels]
54
+ # def binary_focal_loss(gamma=2.0, alpha=0.25):
55
+ # def focal_loss(y_true, y_pred):
56
+ # # Define epsilon to avoid log(0)
57
+ # epsilon = tf.keras.backend.epsilon()
58
+ # # Clip predictions to prevent log(0) and log(1 - 0)
59
+ # y_pred = tf.clip_by_value(y_pred, epsilon, 1.0 - epsilon)
60
+ # # Compute the focal loss
61
+ # fl = - alpha * (y_true * (1 - y_pred)**gamma * tf.math.log(y_pred)
62
+ # + (1 - y_true) * (y_pred**gamma) * tf.math.log(1 - y_pred))
63
+ # return tf.reduce_mean(fl, axis=-1)
64
+ # return focal_loss
65
+
66
+ # loss = binary_focal_loss(gamma=2.0, alpha=0.25)
67
+
68
+ # # Function to read video frames into a list
69
+ # def read_video_frames(video_path):
70
+ # cap = cv2.VideoCapture(video_path)
71
+ # frames = []
72
+ # while True:
73
+ # ret, frame = cap.read()
74
+ # if not ret:
75
+ # break
76
+ # frames.append(frame)
77
+
78
+ # cap.release()
79
+ # return frames
80
+
81
+ # # Function to process frames and make predictions
82
+ # def process_frames(frames, model):
83
+ # frames = [get_face(frame) for frame in tqdm(frames[:len(frames)-1])]
84
+ # st.text(f"face shape : {frames[0].shape}")
85
+ # frame_array = np.array(frames)
86
+ # preds = model.predict(frame_array)
87
+ # print(preds[0])
88
+ # predicted_labels = np.zeros_like(preds,dtype='int')
89
+ # for i in range(12):
90
+ # predicted_labels[:, i] = (preds[:, i] > threshold[i]).astype(int)
91
+ # return predicted_labels
92
+
93
+ # # Function to save predictions to a CSV file
94
+ # def save_predictions_to_csv(predictions, filename="predictions.csv"):
95
+ # df = pd.DataFrame(predictions,columns=col)
96
+ # df.to_csv(filename, index=False)
97
+ # return filename
98
+
99
+ # # Load your Keras model
100
+ # def load_model():
101
+ # model = tf.keras.models.load_model('incept_v3_10fps_full_0.4.keras',
102
+ # custom_objects={'binary_focal_loss': binary_focal_loss})
103
+ # return model
104
+
105
+ # # Streamlit app
106
+ # def main():
107
+ # st.title("Video Frame Prediction App")
108
+
109
+ # # Upload video file
110
+ # uploaded_file = st.file_uploader("Upload a video file", type=["mp4", "avi", "mov"])
111
+
112
+ # if uploaded_file is not None:
113
+ # with NamedTemporaryFile(delete=False) as tmp_file:
114
+ # tmp_file.write(uploaded_file.read())
115
+ # video_path = tmp_file.name
116
+
117
+ # # Load the model
118
+ # model = load_model()
119
+
120
+ # # Predict button
121
+ # if st.button("Predict"):
122
+ # # Read frames from video
123
+ # st.text("Reading video frames...")
124
+ # frames = read_video_frames(video_path)
125
+ # st.text(f"Total frames read: {len(frames)}")
126
+
127
+ # # Process frames and make predictions
128
+ # st.text("Processing frames and making predictions...")
129
+ # predictions = process_frames(frames, model)
130
+ # st.text("Predictions completed!")
131
+
132
+ # # Save predictions to CSV
133
+ # csv_file_path = save_predictions_to_csv(predictions)
134
+ # st.text("Predictions saved to CSV!")
135
+
136
+ # # Make CSV downloadable
137
+ # with open(csv_file_path, "rb") as f:
138
+ # st.download_button(
139
+ # label="Download CSV",
140
+ # data=f,
141
+ # file_name="predictions.csv",
142
+ # mime="text/csv"
143
+ # )
144
+
145
+ # # Clean up the temporary file
146
+ # os.remove(video_path)
147
+
148
+ # if __name__ == "__main__":
149
+ # main()
150
+
151
+
152
+ import os
153
+ os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
154
+
155
+ import streamlit as st
156
+ import cv2
157
+ from tqdm import tqdm
158
+ import numpy as np
159
+ import tensorflow as tf
160
+ import pandas as pd
161
+ from tempfile import NamedTemporaryFile
162
+ from functions import *
163
+
164
+ threshold = [
165
+ 0.6827917, 0.7136434, 0.510756, 0.56771123, 0.49417764, 0.45892453,
166
+ 0.32996163, 0.5038406, 0.44855, 0.32959282, 0.45619836, 0.4969851
167
+ ]
168
+
169
+ au_to_movements = {
170
+ 'au1': 'inner brow raiser',
171
+ 'au2': 'outer brow raiser',
172
+ 'au4': 'brow lowerer',
173
+ 'au5': 'upper lid raiser',
174
+ 'au6': 'cheek raiser',
175
+ 'au9': 'nose wrinkler',
176
+ 'au12': 'lip corner puller',
177
+ 'au15': 'lip corner depressor',
178
+ 'au17': 'chin raiser',
179
+ 'au20': 'lip stretcher',
180
+ 'au25': 'lips part',
181
+ 'au26': 'jaw drop'
182
+ }
183
+
184
+ au_labels = [
185
+ "au1", "au12", "au15", "au17", "au2", "au20",
186
+ "au25", "au26", "au4", "au5", "au6", "au9"
187
+ ]
188
+
189
+ col = [au_to_movements[i] for i in au_labels]
190
+
191
+ def binary_focal_loss(gamma=2.0, alpha=0.25):
192
+ def focal_loss(y_true, y_pred):
193
+ epsilon = tf.keras.backend.epsilon()
194
+ y_pred = tf.clip_by_value(y_pred, epsilon, 1.0 - epsilon)
195
+ fl = - alpha * (y_true * (1 - y_pred)**gamma * tf.math.log(y_pred)
196
+ + (1 - y_true) * (y_pred**gamma) * tf.math.log(1 - y_pred))
197
+ return tf.reduce_mean(fl, axis=-1)
198
+ return focal_loss
199
+
200
+ loss = binary_focal_loss(gamma=2.0, alpha=0.25)
201
+
202
+ # Function to read video frames into a list and get timestamps
203
+ def read_video_frames(video_path):
204
+ cap = cv2.VideoCapture(video_path)
205
+ frames = []
206
+ faces=[]
207
+ timestamps = []
208
+ fps = cap.get(cv2.CAP_PROP_FPS)
209
+ while True:
210
+ ret, frame = cap.read()
211
+ if not ret:
212
+ break
213
+ face=get_face(frame)
214
+ if face is not None:
215
+ faces.append(face)
216
+ frames.append(frame)
217
+ timestamps.append(cap.get(cv2.CAP_PROP_POS_MSEC) / 1000.0) # Time in seconds
218
+
219
+ cap.release()
220
+ return frames,faces, timestamps
221
+
222
+ # Function to process frames and make predictions
223
+ def process_frames(frames, model):
224
+ frame_array = np.array(frames)
225
+ preds = model.predict(frame_array)
226
+ predicted_labels = np.zeros_like(preds, dtype='int')
227
+ for i in range(12):
228
+ predicted_labels[:, i] = (preds[:, i] > threshold[i]).astype(int)
229
+ return preds
230
+
231
+ # Function to save predictions to a CSV file with timestamps
232
+ def save_predictions_to_csv(predictions, timestamps, filename="predictions.csv"):
233
+ df = pd.DataFrame(predictions, columns=col)
234
+ df['timestamp'] = timestamps
235
+ df.set_index('timestamp', inplace=True)
236
+ df.to_csv(filename)
237
+ return filename
238
+
239
+ # Load your Keras model
240
+ def load_model():
241
+ model = tf.keras.models.load_model('incept_v3_10fps_full_0.4.keras',
242
+ custom_objects={'binary_focal_loss': binary_focal_loss})
243
+ return model
244
+
245
+ # Streamlit app
246
+ def main():
247
+ st.title("Facial action unit detection")
248
+
249
+ uploaded_file = st.file_uploader("Upload a video file", type=["mp4", "avi", "mov"])
250
+
251
+ if uploaded_file is not None:
252
+ with NamedTemporaryFile(delete=False) as tmp_file:
253
+ tmp_file.write(uploaded_file.read())
254
+ video_path = tmp_file.name
255
+
256
+ model = load_model()
257
+
258
+ if st.button("Predict"):
259
+ st.text("Reading video frames...")
260
+ frames,faces, timestamps = read_video_frames(video_path)
261
+ st.text(f"Total frames in which faces found: {len(faces)}")
262
+
263
+ st.text("Processing frames and making predictions...")
264
+ predictions = process_frames(faces, model)
265
+ st.text("Predictions completed!")
266
+
267
+ csv_file_path = save_predictions_to_csv(predictions, timestamps)
268
+ st.text("Predictions saved to CSV!")
269
+
270
+ with open(csv_file_path, "rb") as f:
271
+ st.download_button(
272
+ label="Download CSV",
273
+ data=f,
274
+ file_name="predictions.csv",
275
+ mime="text/csv"
276
+ )
277
+
278
+ os.remove(video_path)
279
+
280
+ if __name__ == "__main__":
281
+ main()
functions.py CHANGED
@@ -7,11 +7,6 @@ dnn_net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "res10_300x300_ssd_iter_14
7
  # Initialize dlib's facial landmark predictor
8
  predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
9
 
10
- dnn_net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "res10_300x300_ssd_iter_140000.caffemodel")
11
-
12
- # Initialize dlib's facial landmark predictor
13
- predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
14
-
15
  def get_face(image, net=dnn_net, predictor=predictor):
16
  # Prepare the image for DNN face detection
17
  (h, w) = image.shape[:2]
@@ -34,8 +29,8 @@ def get_face(image, net=dnn_net, predictor=predictor):
34
  landmarks = predictor(gray, dlib_rect)
35
 
36
  # Visualize landmarks
37
- for p in landmarks.parts():
38
- cv2.circle(image, (p.x, p.y), 2, (0, 255, 0), -1)
39
 
40
  # Get the bounding box for the face based on landmarks
41
  landmarks_np = np.array([[p.x, p.y] for p in landmarks.parts()])
@@ -49,9 +44,8 @@ def get_face(image, net=dnn_net, predictor=predictor):
49
  y = max(0, y)
50
  w = min(w, image.shape[1] - x)
51
  h = min(h, image.shape[0] - y)
52
-
53
  # Crop and resize the face
54
- face_crop = image[y-h//2:y+h, x:x+w]
55
  face_crop = cv2.resize(face_crop, (224, 224))
56
  return face_crop
57
 
 
7
  # Initialize dlib's facial landmark predictor
8
  predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
9
 
 
 
 
 
 
10
  def get_face(image, net=dnn_net, predictor=predictor):
11
  # Prepare the image for DNN face detection
12
  (h, w) = image.shape[:2]
 
29
  landmarks = predictor(gray, dlib_rect)
30
 
31
  # Visualize landmarks
32
+ # for p in landmarks.parts():
33
+ # cv2.circle(image, (p.x, p.y), 2, (0, 255, 0), -1)
34
 
35
  # Get the bounding box for the face based on landmarks
36
  landmarks_np = np.array([[p.x, p.y] for p in landmarks.parts()])
 
44
  y = max(0, y)
45
  w = min(w, image.shape[1] - x)
46
  h = min(h, image.shape[0] - y)
 
47
  # Crop and resize the face
48
+ face_crop = image[max(y-h//2,0):y+h, x:x+w]
49
  face_crop = cv2.resize(face_crop, (224, 224))
50
  return face_crop
51
 
incept_v3_10fps_full_0.4.keras ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c76de29d4085ca4b5f903e7a24c9afe8e836e0b125cc2ae39e6dc59a214ed800
3
+ size 296199144