dc086989 commited on
Commit
a05511c
1 Parent(s): c9dfb92

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +339 -0
app.py ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import requests
4
+ import base64
5
+ import io
6
+ import cv2 as cv
7
+ import numpy as np
8
+
9
+ from PIL import Image
10
+
11
+ def face_compare(frame1, frame2):
12
+ url = "https://faceapi.miniai.live/face_compare"
13
+ files = {'file1': open(frame1, 'rb'), 'file2': open(frame2, 'rb')}
14
+
15
+ r = requests.post(url=url, files=files)
16
+
17
+ html = None
18
+ faces = None
19
+
20
+ compare_result = r.json().get('compare_result')
21
+ compare_similarity = r.json().get('compare_similarity')
22
+
23
+ html = ("<table>"
24
+ "<tr>"
25
+ "<th>State</th>"
26
+ "<th>Value</th>"
27
+ "</tr>"
28
+ "<tr>"
29
+ "<td>Is same person? </td>"
30
+ "<td>{compare_result}</td>"
31
+ "</tr>"
32
+ "<tr>"
33
+ "<td>Similarity</td>"
34
+ "<td>{compare_similarity}</td>"
35
+ "</tr>"
36
+ "</table>".format(compare_result=compare_result, compare_similarity=compare_similarity))
37
+
38
+ try:
39
+ image1 = Image.open(frame1)
40
+ image2 = Image.open(frame2)
41
+
42
+ face1 = None
43
+ face2 = None
44
+
45
+ if r.json().get('face1') is not None:
46
+ face = r.json().get('face1')
47
+ x1 = face.get('x1')
48
+ y1 = face.get('y1')
49
+ x2 = face.get('x2')
50
+ y2 = face.get('y2')
51
+
52
+ if x1 < 0:
53
+ x1 = 0
54
+ if y1 < 0:
55
+ y1 = 0
56
+ if x2 >= image1.width:
57
+ x2 = image1.width - 1
58
+ if y2 >= image1.height:
59
+ y2 = image1.height - 1
60
+
61
+ face1 = image1.crop((x1, y1, x2, y2))
62
+ face_image_ratio = face1.width / float(face1.height)
63
+ resized_w = int(face_image_ratio * 150)
64
+ resized_h = 150
65
+
66
+ face1 = face1.resize((int(resized_w), int(resized_h)))
67
+
68
+ if r.json().get('face2') is not None:
69
+ face = r.json().get('face2')
70
+ x1 = face.get('x1')
71
+ y1 = face.get('y1')
72
+ x2 = face.get('x2')
73
+ y2 = face.get('y2')
74
+
75
+ if x1 < 0:
76
+ x1 = 0
77
+ if y1 < 0:
78
+ y1 = 0
79
+ if x2 >= image2.width:
80
+ x2 = image2.width - 1
81
+ if y2 >= image2.height:
82
+ y2 = image2.height - 1
83
+
84
+ face2 = image2.crop((x1, y1, x2, y2))
85
+ face_image_ratio = face2.width / float(face2.height)
86
+ resized_w = int(face_image_ratio * 150)
87
+ resized_h = 150
88
+
89
+ face2 = face2.resize((int(resized_w), int(resized_h)))
90
+
91
+ if face1 is not None and face2 is not None:
92
+ new_image = Image.new('RGB',(face1.width + face2.width + 10, 150), (80,80,80))
93
+
94
+ new_image.paste(face1,(0,0))
95
+ new_image.paste(face2,(face1.width + 10, 0))
96
+ faces = new_image.copy()
97
+ elif face1 is not None and face2 is None:
98
+ new_image = Image.new('RGB',(face1.width + face1.width + 10, 150), (80,80,80))
99
+
100
+ new_image.paste(face1,(0,0))
101
+ faces = new_image.copy()
102
+ elif face1 is None and face2 is not None:
103
+ new_image = Image.new('RGB',(face2.width + face2.width + 10, 150), (80,80,80))
104
+
105
+ new_image.paste(face2,(face2.width + 10, 0))
106
+ faces = new_image.copy()
107
+
108
+ except:
109
+ pass
110
+
111
+ return [faces, html]
112
+
113
+ def check_liveness(frame):
114
+ url = "https://faceapi.miniai.live/face_liveness_check"
115
+ file = {'file': open(frame, 'rb')}
116
+
117
+ r = requests.post(url=url, files=file)
118
+
119
+ faceCount = None
120
+
121
+ response_data = r.json()
122
+
123
+ for item in response_data.get('face_state', []):
124
+ if 'faceCount' in item:
125
+ faceCount = item['faceCount']
126
+ break
127
+
128
+ faces = None
129
+ live_result = []
130
+ live_result.append(f"<table><tr><th>FaceID</th><th>Age</th><th>Gender</th><th>Liveness</th></tr>")
131
+
132
+ for item in response_data.get('face_state', []):
133
+ if item.get('FaceID'):
134
+ faceID = item.get('FaceID')
135
+ result = item.get('LivenessCheck')
136
+ age = item.get('Age')
137
+ gender = item.get('Gender')
138
+ live_result.append(f"<tr><td>{faceID}</td><td>{age}</td><td>{gender}</td><td>{result}</td></tr>")
139
+ live_result.append(f"</table>")
140
+ live_result = ''.join(live_result)
141
+
142
+ try:
143
+ image = Image.open(frame)
144
+
145
+ for face in r.json().get('faces'):
146
+ x1 = face.get('x1')
147
+ y1 = face.get('y1')
148
+ x2 = face.get('x2')
149
+ y2 = face.get('y2')
150
+
151
+ if x1 < 0:
152
+ x1 = 0
153
+ if y1 < 0:
154
+ y1 = 0
155
+ if x2 >= image.width:
156
+ x2 = image.width - 1
157
+ if y2 >= image.height:
158
+ y2 = image.height - 1
159
+
160
+ face_image = image.crop((x1, y1, x2, y2))
161
+ face_image_ratio = face_image.width / float(face_image.height)
162
+ resized_w = int(face_image_ratio * 150)
163
+ resized_h = 150
164
+
165
+ face_image = face_image.resize((int(resized_w), int(resized_h)))
166
+
167
+ if faces is None:
168
+ faces = face_image
169
+ else:
170
+ new_image = Image.new('RGB',(faces.width + face_image.width + 10, 150), (80,80,80))
171
+
172
+ new_image.paste(faces,(0,0))
173
+ new_image.paste(face_image,(faces.width + 10, 0))
174
+ faces = new_image.copy()
175
+ except:
176
+ pass
177
+
178
+ return [faces, live_result]
179
+
180
+ def face_emotion(frame):
181
+ url = "https://faceapi.miniai.live/face_emotion"
182
+ file = {'file': open(frame, 'rb')}
183
+
184
+ r = requests.post(url=url, files=file)
185
+
186
+ emotion_result = []
187
+ emotion_result.append(f"<table><tr><td>Emotional Result : </td><td>{r.json().get('emotion_result')}</td></tr>")
188
+ emotion_result.append(f"</table>")
189
+ emotion_result = ''.join(emotion_result)
190
+
191
+ faces = None
192
+
193
+ try:
194
+ image = Image.open(frame)
195
+
196
+ for face in r.json().get('faces'):
197
+ x1 = face.get('x1')
198
+ y1 = face.get('y1')
199
+ x2 = face.get('x2')
200
+ y2 = face.get('y2')
201
+
202
+ if x1 < 0:
203
+ x1 = 0
204
+ if y1 < 0:
205
+ y1 = 0
206
+ if x2 >= image.width:
207
+ x2 = image.width - 1
208
+ if y2 >= image.height:
209
+ y2 = image.height - 1
210
+
211
+ face_image = image.crop((x1, y1, x2, y2))
212
+ face_image_ratio = face_image.width / float(face_image.height)
213
+ resized_w = int(face_image_ratio * 150)
214
+ resized_h = 150
215
+
216
+ face_image = face_image.resize((int(resized_w), int(resized_h)))
217
+
218
+ if faces is None:
219
+ faces = face_image
220
+ else:
221
+ new_image = Image.new('RGB',(faces.width + face_image.width + 10, 150), (80,80,80))
222
+
223
+ new_image.paste(faces,(0,0))
224
+ new_image.paste(face_image,(faces.width + 10, 0))
225
+ faces = new_image.copy()
226
+ except:
227
+ pass
228
+
229
+ return [faces, emotion_result]
230
+
231
+ # APP Interface
232
+ with gr.Blocks() as MiniAIdemo:
233
+ gr.Markdown(
234
+ """
235
+ <a href="https://miniai.live" style="display: flex; align-items: center;">
236
+ <img src="https://miniai.live/wp-content/uploads/2024/02/logo_name-1-768x426-1.png" style="width: 18%; margin-right: 15px;"/>
237
+ <div>
238
+ <p style="font-size: 50px; font-weight: bold; margin-right: 20px;">FaceSDK Web Online Demo</p>
239
+ <p style="font-size: 20px; margin-right: 0;">Experience our NIST FRVT Top Ranked FaceRecognition, iBeta 2 Certified Face Liveness Detection Engine</p>
240
+ </div>
241
+ </a>
242
+
243
+ <br/>
244
+ <ul>
245
+ <li style="font-size: 18px;">Visit and learn more about our Service : <a href="https://miniai.live" target="_blank" style="font-size: 18px;">https://www.miniai.live</a></li>
246
+ <li style="font-size: 18px;">Check our SDK for cross-platform from Github : <a href="https://github.com/MiniAiLive" target="_blank" style="font-size: 18px;">https://github.com/MiniAiLive</a></li>
247
+ <li style="font-size: 18px;">Quick view our Youtube Demo Video : <a href="https://www.youtube.com/@miniailive" target="_blank" style="font-size: 18px;">MiniAiLive Youtube Channel</a></li>
248
+ <li style="font-size: 18px;">Demo with Android device from Google Play : <a href="https://play.google.com/store/apps/dev?id=5831076207730531667" target="_blank" style="font-size: 18px;">MiniAiLive Google Play</a></li>
249
+ </ul>
250
+ <br/>
251
+ """
252
+ )
253
+ with gr.Tabs():
254
+ with gr.Tab("Face Recognition"):
255
+ with gr.Row():
256
+ with gr.Column():
257
+ im_match_in1 = gr.Image(type='filepath', height=300)
258
+ gr.Examples(
259
+ [
260
+ os.path.join(os.path.dirname(__file__), "images/compare/demo-pic22.jpg"),
261
+ os.path.join(os.path.dirname(__file__), "images/compare/demo-pic60.jpg"),
262
+ os.path.join(os.path.dirname(__file__), "images/compare/demo-pic35.jpg"),
263
+ os.path.join(os.path.dirname(__file__), "images/compare/demo-pic33.jpg"),
264
+ os.path.join(os.path.dirname(__file__), "images/compare/demo-pic34.jpg"),
265
+ ],
266
+ inputs=im_match_in1
267
+ )
268
+ with gr.Column():
269
+ im_match_in2 = gr.Image(type='filepath', height=300)
270
+ gr.Examples(
271
+ [
272
+ os.path.join(os.path.dirname(__file__), "images/compare/demo-pic41.jpg"),
273
+ os.path.join(os.path.dirname(__file__), "images/compare/demo-pic32.jpg"),
274
+ os.path.join(os.path.dirname(__file__), "images/compare/demo-pic39.jpg"),
275
+ os.path.join(os.path.dirname(__file__), "images/compare/demo-pic61.jpg"),
276
+ os.path.join(os.path.dirname(__file__), "images/compare/demo-pic40.jpg"),
277
+ ],
278
+ inputs=im_match_in2
279
+ )
280
+ with gr.Column():
281
+ im_match_crop = gr.Image(type="pil", height=256)
282
+ txt_compare_out = gr.HTML()
283
+ btn_f_match = gr.Button("Check Comparing!", variant='primary')
284
+ btn_f_match.click(face_compare, inputs=[im_match_in1, im_match_in2], outputs=[im_match_crop, txt_compare_out])
285
+ with gr.Tab("Face Liveness Detection"):
286
+ with gr.Row():
287
+ with gr.Column(scale=1):
288
+ im_liveness_in = gr.Image(type='filepath', height=300)
289
+ gr.Examples(
290
+ [
291
+ # os.path.join(os.path.dirname(__file__), "data/images/liveness/f_fake_andr_mask.jpg"),
292
+ os.path.join(os.path.dirname(__file__), "images/liveness/f_real_andr.jpg"),
293
+ os.path.join(os.path.dirname(__file__), "images/liveness/f_fake_andr_mask3d.jpg"),
294
+ os.path.join(os.path.dirname(__file__), "images/liveness/f_fake_andr_monitor.jpg"),
295
+ os.path.join(os.path.dirname(__file__), "images/liveness/f_fake_andr_outline.jpg"),
296
+ os.path.join(os.path.dirname(__file__), "images/liveness/f_fake_andr_outline3d.jpg"),
297
+ os.path.join(os.path.dirname(__file__), "images/liveness/1.jpg"),
298
+ # os.path.join(os.path.dirname(__file__), "data/images/liveness/2.jpg"),
299
+ os.path.join(os.path.dirname(__file__), "images/liveness/3.png"),
300
+ os.path.join(os.path.dirname(__file__), "images/liveness/4.jpg"),
301
+ ],
302
+ inputs=im_liveness_in
303
+ )
304
+ btn_f_liveness = gr.Button("Check Liveness!", variant='primary')
305
+ with gr.Blocks():
306
+ with gr.Row():
307
+ with gr.Column():
308
+ im_liveness_out = gr.Image(label="Croped Face", type="pil", scale=1)
309
+ with gr.Column():
310
+ livness_result_output = gr.HTML()
311
+ btn_f_liveness.click(check_liveness, inputs=im_liveness_in, outputs=[im_liveness_out, livness_result_output])
312
+ with gr.Tab("Face Emotional Recognition"):
313
+ with gr.Row():
314
+ with gr.Column():
315
+ im_emotion_in = gr.Image(type='filepath', height=300)
316
+ gr.Examples(
317
+ [
318
+ os.path.join(os.path.dirname(__file__), "images/emotion/1.jpg"),
319
+ os.path.join(os.path.dirname(__file__), "images/emotion/2.jpg"),
320
+ os.path.join(os.path.dirname(__file__), "images/emotion/3.jpg"),
321
+ os.path.join(os.path.dirname(__file__), "images/emotion/4.jpg"),
322
+ os.path.join(os.path.dirname(__file__), "images/emotion/5.jpg"),
323
+ os.path.join(os.path.dirname(__file__), "images/emotion/6.jpg"),
324
+ ],
325
+ inputs=im_emotion_in
326
+ )
327
+ btn_f_emotion = gr.Button("Check Emotion!", variant='primary')
328
+ with gr.Blocks():
329
+ with gr.Row():
330
+ with gr.Column():
331
+ im_emotion_out = gr.Image(label="Result Image", type="pil", scale=1)
332
+ with gr.Column():
333
+ txt_emotion_out = gr.HTML()
334
+ btn_f_emotion.click(face_emotion, inputs=im_emotion_in, outputs=[im_emotion_out, txt_emotion_out])
335
+
336
+ gr.HTML('<a href="https://visitorbadge.io/status?path=demo.miniai.live"><img src="https://api.visitorbadge.io/api/combined?path=demo.miniai.live&label=Visitors&labelColor=%2337d67a&countColor=%23697689&style=plastic&labelStyle=upper" /></a>')
337
+
338
+ if __name__ == "__main__":
339
+ MiniAIdemo.launch()