hassan526 commited on
Commit
94517a5
·
verified ·
1 Parent(s): 25d0fe8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +294 -190
app.py CHANGED
@@ -89,6 +89,7 @@ root_path = os.path.dirname(file_path)
89
  g_fr_activation_result = -1
90
  g_fl_activation_result = -1
91
  MATCH_THRESHOLD = 0.67
 
92
 
93
  def activate_fr_sdk():
94
  fr_key = os.environ.get("FR_LICENSE_KEY")
@@ -128,200 +129,256 @@ def convert_fun(input_str):
128
  # Remove line breaks and extra whitespaces
129
  return ' '.join(input_str.split())
130
 
131
- def get_attributes(frame):
132
- url = "https://recognito.p.rapidapi.com/api/analyze_face"
133
- try:
134
- files = {'image': open(frame, 'rb')}
135
- headers = {"X-RapidAPI-Key": os.environ.get("API_KEY")}
136
 
137
- r = requests.post(url=url, files=files, headers=headers)
138
- except:
139
- raise gr.Error("Please select images file!")
140
 
141
- faces = None
142
- face_crop, one_line_attribute = None, ""
143
- try:
144
- image = Image.open(frame)
145
 
146
- face = Image.new('RGBA',(150, 150), (80,80,80,0))
147
 
148
- res = r.json().get('image')
149
- if res is not None and res:
150
- face = res.get('detection')
151
- x1 = face.get('x')
152
- y1 = face.get('y')
153
- x2 = x1 + face.get('w')
154
- y2 = y1 + face.get('h')
155
-
156
- if x1 < 0:
157
- x1 = 0
158
- if y1 < 0:
159
- y1 = 0
160
- if x2 >= image.width:
161
- x2 = image.width - 1
162
- if y2 >= image.height:
163
- y2 = image.height - 1
164
-
165
- face_crop = image.crop((x1, y1, x2, y2))
166
- face_image_ratio = face_crop.width / float(face_crop.height)
167
- resized_w = int(face_image_ratio * 150)
168
- resized_h = 150
169
-
170
- face_crop = face_crop.resize((int(resized_w), int(resized_h)))
171
 
172
- attr = res.get('attribute')
173
 
174
- age = attr.get('age')
175
- gender = attr.get('gender')
176
- emotion = attr.get('emotion')
177
- ethnicity = attr.get('ethnicity')
178
-
179
- mask = attr.get('face_mask')
180
- glass = 'No Glasses'
181
- if attr.get('glasses') == 'USUAL':
182
- glass = 'Glasses'
183
- if attr.get('glasses') == 'DARK':
184
- glass = 'Sunglasses'
185
 
186
- open_eye_thr = 0.3
187
- left_eye = 'Close'
188
- if attr.get('eye_left') >= open_eye_thr:
189
- left_eye = 'Open'
190
-
191
- right_eye = 'Close'
192
- if attr.get('eye_right') >= open_eye_thr:
193
- right_eye = 'Open'
194
-
195
- facehair = attr.get('facial_hair')
196
- haircolor = attr.get('hair_color')
197
- hairtype = attr.get('hair_type')
198
- headwear = attr.get('headwear')
199
-
200
- pitch = attr.get('pitch')
201
- roll = attr.get('roll')
202
- yaw = attr.get('yaw')
203
- quality = attr.get('quality')
204
-
205
- attribute = f"""
206
- <br/>
207
- <div class="markdown-attribute-container">
208
- <table>
209
- <tr>
210
- <th style="text-align: center;">Attribute</th>
211
- <th style="text-align: center;">Result</th>
212
- <th style="text-align: center;">Score</th>
213
- <th style="text-align: center;">Threshold</th>
214
- </tr>
215
- <tr>
216
- <td>Gender</td>
217
- <td>{gender}</td>
218
- <td></td><td></td>
219
- </tr>
220
- <tr>
221
- <td>Age</td>
222
- <td>{int(age)}</td>
223
- <td></td><td></td>
224
- </tr>
225
- <tr>
226
- <td>Pitch</td>
227
- <td>{"{:.4f}".format(pitch)}</td>
228
- <td></td><td></td>
229
- </tr>
230
- <tr>
231
- <td>Yaw</td>
232
- <td>{"{:.4f}".format(yaw)}</td>
233
- <td></td><td></td>
234
- </tr>
235
- <tr>
236
- <td>Roll</td>
237
- <td>{"{:.4f}".format(roll)}</td>
238
- <td></td><td></td>
239
- </tr>
240
- <tr>
241
- <td>Emotion</td>
242
- <td>{emotion}</td>
243
- <td></td><td></td>
244
- </tr>
245
- <tr>
246
- <td>Left Eye</td>
247
- <td>{left_eye}</td>
248
- <td>{"{:.4f}".format(attr.get('eye_left'))}</td>
249
- <td>{open_eye_thr}</td>
250
- </tr>
251
- <tr>
252
- <td>Right Eye</td>
253
- <td>{right_eye}</td>
254
- <td>{"{:.4f}".format(attr.get('eye_right'))}</td>
255
- <td>{open_eye_thr}</td>
256
- </tr>
257
- <tr>
258
- <td>Mask</td>
259
- <td>{mask}</td>
260
- <td></td><td></td>
261
- </tr>
262
- <tr>
263
- <td>Glass</td>
264
- <td>{glass}</td>
265
- <td></td><td></td>
266
- </tr>
267
- <tr>
268
- <td>FaceHair</td>
269
- <td>{facehair}</td>
270
- <td></td><td></td>
271
- </tr>
272
- <tr>
273
- <td>HairColor</td>
274
- <td>{haircolor}</td>
275
- <td></td><td></td>
276
- </tr>
277
- <tr>
278
- <td>HairType</td>
279
- <td>{hairtype}</td>
280
- <td></td><td></td>
281
- </tr>
282
- <tr>
283
- <td>HeadWear</td>
284
- <td>{headwear}</td>
285
- <td></td><td></td>
286
- </tr>
287
- <tr>
288
- <td>Image Quality</td>
289
- <td>{"{:.4f}".format(quality)}</td>
290
- <td></td><td></td>
291
- </tr>
292
- </table>
293
- </div>
294
- """
295
- one_line_attribute = convert_fun(attribute)
296
- except:
297
- pass
298
 
299
- return face_crop, one_line_attribute
300
 
301
  def check_liveness(frame):
302
- url = "https://recognito-faceliveness.p.rapidapi.com/api/check_liveness"
303
- try:
304
- files = {'image': open(frame, 'rb')}
305
- headers = {"X-RapidAPI-Key": os.environ.get("API_KEY")}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
 
307
- r = requests.post(url=url, files=files, headers=headers)
 
308
  except:
309
- raise gr.Error("Please select images file!")
310
-
311
- faces = None
 
 
 
 
312
 
313
- face_crop, liveness_result, liveness_score = None, "", -200
314
  try:
315
  image = Image.open(frame)
316
 
317
  face = Image.new('RGBA',(150, 150), (80,80,80,0))
318
- res = r.json().get('data')
319
- if res is not None and res:
320
- face = res.get('face_rect')
321
- x1 = face.get('x')
322
- y1 = face.get('y')
323
- x2 = x1 + face.get('w')
324
- y2 = y1 + face.get('h')
325
 
326
  if x1 < 0:
327
  x1 = 0
@@ -338,24 +395,71 @@ def check_liveness(frame):
338
  resized_h = 150
339
 
340
  face_crop = face_crop.resize((int(resized_w), int(resized_h)))
341
- liveness_score = res.get('liveness_score')
342
- liveness = res.get('result')
343
-
344
- if liveness == 'REAL':
345
- liveness_result = f"""<br/><div class="markdown-success-container"><p style="text-align: center; font-size: 20px; color: green;">Liveness Check: REAL<br/>Score: {liveness_score}</p></div>"""
346
- else:
347
- liveness_result = f"""<br/><div class="markdown-fail-container"><p style="text-align: center; font-size: 20px; color: red;">Liveness Check: {liveness}<br/>Score: {liveness_score}</p></div>"""
348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  except:
350
  pass
351
-
352
- return face_crop, liveness_result, liveness_score
353
 
354
- def analyze_face(frame):
355
- face_crop_1, liveness_result, liveness_score = check_liveness(frame)
356
- face_crop_2, attribute = get_attributes(frame)
 
 
 
 
357
 
358
- face_crop = face_crop_1 if (face_crop_1 is not None) else face_crop_2
 
 
 
 
359
  return [face_crop, liveness_result, attribute]
360
 
361
 
 
89
  g_fr_activation_result = -1
90
  g_fl_activation_result = -1
91
  MATCH_THRESHOLD = 0.67
92
+ SPOOF_THRESHOLD = 0.5
93
 
94
  def activate_fr_sdk():
95
  fr_key = os.environ.get("FR_LICENSE_KEY")
 
129
  # Remove line breaks and extra whitespaces
130
  return ' '.join(input_str.split())
131
 
132
+ # def get_attributes(frame):
133
+ # url = "https://recognito.p.rapidapi.com/api/analyze_face"
134
+ # try:
135
+ # files = {'image': open(frame, 'rb')}
136
+ # headers = {"X-RapidAPI-Key": os.environ.get("API_KEY")}
137
 
138
+ # r = requests.post(url=url, files=files, headers=headers)
139
+ # except:
140
+ # raise gr.Error("Please select images file!")
141
 
142
+ # faces = None
143
+ # face_crop, one_line_attribute = None, ""
144
+ # try:
145
+ # image = Image.open(frame)
146
 
147
+ # face = Image.new('RGBA',(150, 150), (80,80,80,0))
148
 
149
+ # res = r.json().get('image')
150
+ # if res is not None and res:
151
+ # face = res.get('detection')
152
+ # x1 = face.get('x')
153
+ # y1 = face.get('y')
154
+ # x2 = x1 + face.get('w')
155
+ # y2 = y1 + face.get('h')
156
+
157
+ # if x1 < 0:
158
+ # x1 = 0
159
+ # if y1 < 0:
160
+ # y1 = 0
161
+ # if x2 >= image.width:
162
+ # x2 = image.width - 1
163
+ # if y2 >= image.height:
164
+ # y2 = image.height - 1
165
+
166
+ # face_crop = image.crop((x1, y1, x2, y2))
167
+ # face_image_ratio = face_crop.width / float(face_crop.height)
168
+ # resized_w = int(face_image_ratio * 150)
169
+ # resized_h = 150
170
+
171
+ # face_crop = face_crop.resize((int(resized_w), int(resized_h)))
172
 
173
+ # attr = res.get('attribute')
174
 
175
+ # age = attr.get('age')
176
+ # gender = attr.get('gender')
177
+ # emotion = attr.get('emotion')
178
+ # ethnicity = attr.get('ethnicity')
179
+
180
+ # mask = attr.get('face_mask')
181
+ # glass = 'No Glasses'
182
+ # if attr.get('glasses') == 'USUAL':
183
+ # glass = 'Glasses'
184
+ # if attr.get('glasses') == 'DARK':
185
+ # glass = 'Sunglasses'
186
 
187
+ # open_eye_thr = 0.3
188
+ # left_eye = 'Close'
189
+ # if attr.get('eye_left') >= open_eye_thr:
190
+ # left_eye = 'Open'
191
+
192
+ # right_eye = 'Close'
193
+ # if attr.get('eye_right') >= open_eye_thr:
194
+ # right_eye = 'Open'
195
+
196
+ # facehair = attr.get('facial_hair')
197
+ # haircolor = attr.get('hair_color')
198
+ # hairtype = attr.get('hair_type')
199
+ # headwear = attr.get('headwear')
200
+
201
+ # pitch = attr.get('pitch')
202
+ # roll = attr.get('roll')
203
+ # yaw = attr.get('yaw')
204
+ # quality = attr.get('quality')
205
+
206
+ # attribute = f"""
207
+ # <br/>
208
+ # <div class="markdown-attribute-container">
209
+ # <table>
210
+ # <tr>
211
+ # <th style="text-align: center;">Attribute</th>
212
+ # <th style="text-align: center;">Result</th>
213
+ # <th style="text-align: center;">Score</th>
214
+ # <th style="text-align: center;">Threshold</th>
215
+ # </tr>
216
+ # <tr>
217
+ # <td>Gender</td>
218
+ # <td>{gender}</td>
219
+ # <td></td><td></td>
220
+ # </tr>
221
+ # <tr>
222
+ # <td>Age</td>
223
+ # <td>{int(age)}</td>
224
+ # <td></td><td></td>
225
+ # </tr>
226
+ # <tr>
227
+ # <td>Pitch</td>
228
+ # <td>{"{:.4f}".format(pitch)}</td>
229
+ # <td></td><td></td>
230
+ # </tr>
231
+ # <tr>
232
+ # <td>Yaw</td>
233
+ # <td>{"{:.4f}".format(yaw)}</td>
234
+ # <td></td><td></td>
235
+ # </tr>
236
+ # <tr>
237
+ # <td>Roll</td>
238
+ # <td>{"{:.4f}".format(roll)}</td>
239
+ # <td></td><td></td>
240
+ # </tr>
241
+ # <tr>
242
+ # <td>Emotion</td>
243
+ # <td>{emotion}</td>
244
+ # <td></td><td></td>
245
+ # </tr>
246
+ # <tr>
247
+ # <td>Left Eye</td>
248
+ # <td>{left_eye}</td>
249
+ # <td>{"{:.4f}".format(attr.get('eye_left'))}</td>
250
+ # <td>{open_eye_thr}</td>
251
+ # </tr>
252
+ # <tr>
253
+ # <td>Right Eye</td>
254
+ # <td>{right_eye}</td>
255
+ # <td>{"{:.4f}".format(attr.get('eye_right'))}</td>
256
+ # <td>{open_eye_thr}</td>
257
+ # </tr>
258
+ # <tr>
259
+ # <td>Mask</td>
260
+ # <td>{mask}</td>
261
+ # <td></td><td></td>
262
+ # </tr>
263
+ # <tr>
264
+ # <td>Glass</td>
265
+ # <td>{glass}</td>
266
+ # <td></td><td></td>
267
+ # </tr>
268
+ # <tr>
269
+ # <td>FaceHair</td>
270
+ # <td>{facehair}</td>
271
+ # <td></td><td></td>
272
+ # </tr>
273
+ # <tr>
274
+ # <td>HairColor</td>
275
+ # <td>{haircolor}</td>
276
+ # <td></td><td></td>
277
+ # </tr>
278
+ # <tr>
279
+ # <td>HairType</td>
280
+ # <td>{hairtype}</td>
281
+ # <td></td><td></td>
282
+ # </tr>
283
+ # <tr>
284
+ # <td>HeadWear</td>
285
+ # <td>{headwear}</td>
286
+ # <td></td><td></td>
287
+ # </tr>
288
+ # <tr>
289
+ # <td>Image Quality</td>
290
+ # <td>{"{:.4f}".format(quality)}</td>
291
+ # <td></td><td></td>
292
+ # </tr>
293
+ # </table>
294
+ # </div>
295
+ # """
296
+ # one_line_attribute = convert_fun(attribute)
297
+ # except:
298
+ # pass
299
 
300
+ # return face_crop, one_line_attribute
301
 
302
  def check_liveness(frame):
303
+ # url = "https://recognito-faceliveness.p.rapidapi.com/api/check_liveness"
304
+ # try:
305
+ # files = {'image': open(frame, 'rb')}
306
+ # headers = {"X-RapidAPI-Key": os.environ.get("API_KEY")}
307
+
308
+ # r = requests.post(url=url, files=files, headers=headers)
309
+ # except:
310
+ # raise gr.Error("Please select images file!")
311
+
312
+ # faces = None
313
+
314
+ # face_crop, liveness_result, liveness_score = None, "", -200
315
+ # try:
316
+ # image = Image.open(frame)
317
+
318
+ # face = Image.new('RGBA',(150, 150), (80,80,80,0))
319
+ # res = r.json().get('data')
320
+ # if res is not None and res:
321
+ # face = res.get('face_rect')
322
+ # x1 = face.get('x')
323
+ # y1 = face.get('y')
324
+ # x2 = x1 + face.get('w')
325
+ # y2 = y1 + face.get('h')
326
+
327
+ # if x1 < 0:
328
+ # x1 = 0
329
+ # if y1 < 0:
330
+ # y1 = 0
331
+ # if x2 >= image.width:
332
+ # x2 = image.width - 1
333
+ # if y2 >= image.height:
334
+ # y2 = image.height - 1
335
+
336
+ # face_crop = image.crop((x1, y1, x2, y2))
337
+ # face_image_ratio = face_crop.width / float(face_crop.height)
338
+ # resized_w = int(face_image_ratio * 150)
339
+ # resized_h = 150
340
+
341
+ # face_crop = face_crop.resize((int(resized_w), int(resized_h)))
342
+ # liveness_score = res.get('liveness_score')
343
+ # liveness = res.get('result')
344
+
345
+ # if liveness == 'REAL':
346
+ # liveness_result = f"""<br/><div class="markdown-success-container"><p style="text-align: center; font-size: 20px; color: green;">Liveness Check: REAL<br/>Score: {liveness_score}</p></div>"""
347
+ # else:
348
+ # liveness_result = f"""<br/><div class="markdown-fail-container"><p style="text-align: center; font-size: 20px; color: red;">Liveness Check: {liveness}<br/>Score: {liveness_score}</p></div>"""
349
+
350
+ # except:
351
+ # pass
352
+
353
+ # return face_crop, liveness_result, liveness_score
354
+
355
+ global g_fl_activation_result
356
+ if g_fl_activation_result != 0:
357
+ gr.Warning("FL SDK Activation Failed!")
358
+ return None, None, None
359
 
360
+ try:
361
+ image = open(frame, 'rb')
362
  except:
363
+ raise gr.Error("Please select image file!")
364
+
365
+ image_mat = cv2.imdecode(np.frombuffer(image.read(), np.uint8), cv2.IMREAD_COLOR)
366
+ start_time = time.time()
367
+ result, face_rect, score, angles = fl_header.check_liveness(image_mat, SPOOF_THRESHOLD)
368
+ end_time = time.time()
369
+ process_time = (end_time - start_time) * 1000
370
 
371
+ face_crop, one_line_attribute = None, ""
372
  try:
373
  image = Image.open(frame)
374
 
375
  face = Image.new('RGBA',(150, 150), (80,80,80,0))
376
+
377
+ if face_rect is not None:
378
+ x1 = int(face_rect[0])
379
+ y1 = int(face_rect[1])
380
+ x2 = int(face_rect[2])
381
+ y2 = int(face_rect[3])
 
382
 
383
  if x1 < 0:
384
  x1 = 0
 
395
  resized_h = 150
396
 
397
  face_crop = face_crop.resize((int(resized_w), int(resized_h)))
 
 
 
 
 
 
 
398
 
399
+ if angles is not None:
400
+ yaw = angles[0]
401
+ roll = angles[1]
402
+ pitch = angles[2]
403
+
404
+ attribute = f"""
405
+ <br/>
406
+ <div class="markdown-attribute-container">
407
+ <table>
408
+ <tr>
409
+ <th>Field</th>
410
+ <th colspan="2">Value</th>
411
+ </tr>
412
+ <tr>
413
+ <th rowspan="4">Face Rect</th>
414
+ <td>x</td>
415
+ <td>{x1}</td>
416
+ </tr>
417
+ <tr>
418
+ <td>y</td>
419
+ <td>{y1}</td>
420
+ </tr>
421
+ <tr>
422
+ <td>width</td>
423
+ <td>{x2 - x1 + 1}</td>
424
+ </tr>
425
+ <tr>
426
+ <td>height</td>
427
+ <td>{y2 - y1 + 1}</td>
428
+ </tr>
429
+ <tr>
430
+ <th rowspan="3">Face Angle</th>
431
+ <td>Pitch</td>
432
+ <td>{"{:.4f}".format(pitch)}</td>
433
+ </tr>
434
+ <tr>
435
+ <td>Yaw</td>
436
+ <td>{"{:.4f}".format(yaw)}</td>
437
+ </tr>
438
+ <tr>
439
+ <td>Roll</td>
440
+ <td>{"{:.4f}".format(roll)}</td>
441
+ </tr>
442
+ </table>
443
+ </div>
444
+ """
445
+
446
+ one_line_attribute = convert_fun(attribute)
447
  except:
448
  pass
 
 
449
 
450
+ str_score = str("{:.4f}".format(score))
451
+ if result == "REAL":
452
+ liveness_result = f"""<br/><div class="markdown-success-container"><p style="text-align: center; font-size: 20px; color: green;">Liveness Check: REAL<br/>Score: {str_score}</p></div>"""
453
+ else:
454
+ liveness_result = f"""<br/><div class="markdown-fail-container"><p style="text-align: center; font-size: 20px; color: red;">Liveness Check: {result}<br/>Score: {str_score}</p></div>"""
455
+
456
+ return face_crop, liveness_result, one_line_attribute
457
 
458
+ def analyze_face(frame):
459
+ # face_crop_1, liveness_result, liveness_score = check_liveness(frame)
460
+ # face_crop_2, attribute = get_attributes(frame)
461
+ # face_crop = face_crop_1 if (face_crop_1 is not None) else face_crop_2
462
+ face_crop, liveness_result, attribute = check_liveness(frame)
463
  return [face_crop, liveness_result, attribute]
464
 
465