SS8297 commited on
Commit
5dff1b6
·
1 Parent(s): 344ab1a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +138 -12
app.py CHANGED
@@ -7,20 +7,146 @@ from streamlit_image_select import image_select
7
  import cv2 as cv
8
  import numpy as np
9
  import math
10
- from feat import Detector
11
- from feat.utils import FEAT_EMOTION_COLUMNS
12
  import torch
13
  from PIL import Image
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
- def get_book_variable_module_name(module_name):
16
- module = globals().get(module_name, None)
17
- book = {}
18
- if module:
19
- book = {key: value for key, value in module.__dict__.items() if not (key.startswith('__') or key.startswith('_'))}
20
- return book
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
- import config
23
 
24
- book = get_book_variable_module_name('config')
25
- for key, value in book.items():
26
- print "{:<30}{:<100}".format(key, value)
 
7
  import cv2 as cv
8
  import numpy as np
9
  import math
 
 
10
  import torch
11
  from PIL import Image
12
+ from feat import Detector
13
+ from feat.utils import FEAT_EMOTION_COLUMNS
14
+ from feat.utils.io import get_resource_path
15
+
16
+ def _get_resource_path():
17
+ return "/home/user/app/resources"
18
+
19
+ get_resource_path = _get_resource_path
20
+
21
+
22
+
23
+ os.environ["TWILIO_ACCOUNT_SID"] = "ACf1e76f3fd6e9cbca940decc4ed443c20"
24
+ os.environ["TWILIO_AUTH_TOKEN"] = "56a1d1ee494933269fe042706392ac9f"
25
+
26
+
27
+ def get_ice_servers():
28
+ try:
29
+ account_sid = os.environ["TWILIO_ACCOUNT_SID"]
30
+ auth_token = os.environ["TWILIO_AUTH_TOKEN"]
31
+ except KeyError:
32
+ logger.warning("TURN credentials are not set. Fallback to a free STUN server from Google.")
33
+ return [{"urls": ["stun:stun.l.google.com:19302"]}]
34
+
35
+ client = Client(account_sid, auth_token)
36
+
37
+ token = client.tokens.create()
38
+
39
+ return token.ice_servers
40
+
41
+ def eye_aspect_ratio(eye):
42
+
43
+ A = math.dist(eye[1], eye[5])
44
+ B = math.dist(eye[2], eye[4])
45
+
46
+ C = math.dist(eye[0], eye[3])
47
+
48
+ ear = (A + B) / (2.0 * C)
49
+
50
+ return ear
51
+
52
+ def detect_eyes(landmarks, img, threshold):
53
+ lm = landmarks
54
+ eyes = np.array(lm[36:48], np.int32)
55
+
56
+ left_eye = eyes[0:6]
57
+ right_eye = eyes[6:12]
58
+ ear = max(eye_aspect_ratio(left_eye), eye_aspect_ratio(right_eye))
59
+ left_eye = left_eye.reshape((-1,1,2))
60
+ right_eye = right_eye.reshape((-1,1,2))
61
+ cv.polylines(img, [left_eye], True, (0, 255, 255))
62
+ cv.polylines(img, [right_eye], True, (255, 0, 255))
63
+
64
+ if (ear > threshold):
65
+ return True
66
+ else:
67
+ return False
68
+
69
+ def proc_image(img, detector):
70
+ detected_faces = detector.detect_faces(img)
71
+ faces_detected = len(detected_faces[0])
72
+ if ( faces_detected < 1):
73
+ return img
74
+
75
+ detected_landmarks = detector.detect_landmarks(img, detected_faces)
76
+ assert len(detected_landmarks[0]) == faces_detected, "Number of faces and landsmarks are mismatched!"
77
+
78
+ is_eye_open = [detect_eyes(face, img, 0.20) for face in detected_landmarks[0]]
79
+ eye_dict = {True: "eyes open", False: "eyes closed"}
80
+
81
+ detected_emotions = detector.detect_emotions(img, detected_faces, detected_landmarks)
82
+ assert len(detected_emotions[0]) == faces_detected, "Number of faces and emotions are mismatched!"
83
+
84
+ em = detected_emotions[0]
85
+ em_labels = em.argmax(axis=1)
86
+
87
+
88
+
89
+ for face, has_open_eyes, label in zip(detected_faces[0], (eye_dict[eyes] for eyes in is_eye_open), em_labels):
90
+ (x0, y0, x1, y1, p) = face
91
+ res_scale = img.shape[0]/704
92
+ cv.rectangle(img, (int(x0), int(y0)), (int(x1), int(y1)), color = (0, 0, 255), thickness = 3)
93
+ cv.putText(img, FEAT_EMOTION_COLUMNS[label], (int(x0)-10, int(y1+25*res_scale*1.5)), fontFace = 0, color = (0, 255, 0), thickness = 2, fontScale = res_scale)
94
+ cv.putText(img, f"{faces_detected } face(s) found", (0, int(25*res_scale*1.5)), fontFace = 0, color = (0, 255, 0), thickness = 2, fontScale = res_scale)
95
+ cv.putText(img, has_open_eyes, (int(x0)-10, int(y0)-10), fontFace = 0, color = (0, 255, 0), thickness = 2, fontScale = res_scale)
96
+ return img
97
+
98
+ def extract_feat():
99
+ return [1,2,3,4,5]
100
+
101
+ def image_processing(frame):
102
+ return proc_image(img, detector) if recog else img
103
+
104
+ def video_frame_callback(frame):
105
+ img = frame.to_ndarray(format="bgr24")
106
+
107
+ ann = proc_image(img, detector) if recog else img
108
+
109
+ return av.VideoFrame.from_ndarray(ann, format="bgr24")
110
+
111
+ detector = Detector(face_model="retinaface", landmark_model= "pfld", au_model = "xgb", emotion_model="resmasknet")
112
+ source = "Webcam"
113
+ recog = True
114
+
115
+ source = st.radio(
116
+ label = "Image source for emotion recognition",
117
+ options = ["Webcam", "Images"],
118
+ horizontal = True,
119
+ label_visibility = "collapsed",
120
+ args = (source, )
121
+ )
122
+
123
+ has_cam = True if (source == "Webcam") else False
124
 
125
+ stream = st.container()
126
+ with stream:
127
+ if has_cam:
128
+ webrtc_streamer(
129
+ key="example",
130
+ mode=WebRtcMode.SENDRECV,
131
+ video_frame_callback=video_frame_callback,
132
+ rtc_configuration={ "iceServers": get_ice_servers() },
133
+ media_stream_constraints={"video": True, "audio": False},
134
+ async_processing=True,
135
+ )
136
+ else:
137
+ pic = st.container()
138
+ frame = image_select(
139
+ label="Try the classifier on one of the provided examples!",
140
+ images=[
141
+ "ex1.jpg",
142
+ "ex4.jpg",
143
+ "ex5.jpg",
144
+ "ex6.jpg",
145
+ ],
146
+ use_container_width= False
147
+ )
148
+ img = np.array(Image.open(frame))
149
+ pic.image(image_processing(img), width = 704)
150
 
 
151
 
152
+ recog = st.toggle(":green[Emotion recogntion]", key = "stream", value = True)