ds-ekaterina commited on
Commit
9e15820
·
1 Parent(s): b1fabaf

added face comparison

Browse files
app.py CHANGED
@@ -75,8 +75,29 @@ HTML_SUCCESSFUL_PRECHECKS = """
75
  </ul>
76
  """
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
- def main(file_path):
 
80
  if file_path:
81
  url = "https://api.dataspike.io/api/v4/upload/liveness-demo"
82
  headers = {"ds-api-token": os.getenv("API_KEY")}
@@ -107,38 +128,118 @@ def main(file_path):
107
  return liveness_result, "", False
108
 
109
 
110
- with gr.Blocks() as LivenessDemo:
111
- header_box = gr.HTML(HTML_HEADER)
112
- with gr.Row():
113
- with gr.Column(scale=1):
114
- input_img_path = gr.Image(label="Input Image", type="filepath", height=300)
115
- gr.Examples(
116
- [
117
- "images/real_client054_android_SD_scene01.jpg",
118
- "images/attack_client006_android_SD_ipad_video_scene01.jpg",
119
- "images/attack_client055_android_SD_iphone_video_scene01.jpg",
120
- "images/attack_client026_android_SD_printed_photo_scene01.jpg",
121
- "images/attack_deepfake_1.jpg",
122
- "images/attack_deepfake_3.jpg",
123
- "images/attack_mask.jpg",
124
- ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  inputs=input_img_path,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  )
127
- check_button = gr.Button("Check Liveness!", variant="primary")
128
- with gr.Column():
129
- liveness_result = gr.JSON(label="Liveness Result")
130
- explanation_box = gr.HTML("", visible=False)
131
-
132
- state = gr.State(False)
133
- check_button.click(
134
- main,
135
- inputs=input_img_path,
136
- outputs=[liveness_result, explanation_box, state],
137
- )
138
- state.change(
139
- lambda show: gr.update(visible=show), inputs=state, outputs=explanation_box
140
- )
141
 
142
 
143
  if __name__ == "__main__":
144
- LivenessDemo.launch()
 
75
  </ul>
76
  """
77
 
78
+ HTML_FACE_COMPARISON_HEADER = """
79
+ <header style="text-align: center; padding: 20px; border-bottom: 2px solid #cc3300;">
80
+ <h1>Demo of Face Comparison</h1>
81
+ <p style="font-size: 18px;">
82
+ To learn more, visit our website: <a href="https://dataspike.io/" target="_blank" style="font-size: 20px; text-decoration: none;">
83
+ https://dataspike.io/ </a>
84
+ </p>
85
+ </header>
86
+ """
87
+
88
+ HTML_FACE_COMPARISON_EXPLANATION = """
89
+ <h3 style="color:#2E86C1;">🔍 Face Comparison Results Explanation</h3>
90
+ <p>The system compares two photos and provides one of four results:</p>
91
+ <ul>
92
+ <li><strong style="color:#28A745;">Same Person</strong>: The same person appears in both photos.</li>
93
+ <li><strong style="color:#DC3545;">Different Person</strong>: The photos show different individuals.</li>
94
+ <li><strong style="color:#F39C12;">Same Photo</strong>: Identical faces detected, possibly indicating a duplicate or edited image.</li>
95
+ <li><strong style="color:#6C757D;">Failure</strong>: Face comparison failed due to undetected or unclear faces.</li>
96
+ </ul>
97
+ """
98
 
99
+
100
+ def check_liveness(file_path):
101
  if file_path:
102
  url = "https://api.dataspike.io/api/v4/upload/liveness-demo"
103
  headers = {"ds-api-token": os.getenv("API_KEY")}
 
128
  return liveness_result, "", False
129
 
130
 
131
+ def map_fc_result(api_status: str):
132
+ mapping = {
133
+ "FaceComparisonVerified": {"label": "Same Person", "color": "green"},
134
+ "FaceComparisonUnknown": {"label": "Failure", "color": "gray"},
135
+ "FaceComparisonFailedDifferentFaces": {
136
+ "label": "Different Person",
137
+ "color": "red",
138
+ },
139
+ "FaceComparisonFailedSamePhotos": {"label": "Same Photo", "color": "#F39C12"},
140
+ }
141
+ status = api_status["status"] if "status" in api_status.keys() else ""
142
+ return mapping.get(status, {"label": "Unknown", "color": "gray"})
143
+
144
+
145
+ def compare_faces(image1_path, image2_path):
146
+ if image1_path and image2_path:
147
+ url = "https://api.dataspike.io/api/v4/upload/face-comparison-demo"
148
+ headers = {"ds-api-token": os.getenv("API_KEY")}
149
+ files = {"left": open(image1_path, "rb"), "right": open(image2_path, "rb")}
150
+ response = requests.post(url, headers=headers, files=files)
151
+ comparison_result = response.json()
152
+ result = map_fc_result(comparison_result)
153
+ return gr.Label(value=result["label"], color=result["color"]), True
154
+ # return comparison_result, True
155
+ else:
156
+ comparison_result = {
157
+ "overallStatus": "Failure",
158
+ "errors": ["Please submit both images before comparing"],
159
+ }
160
+ return comparison_result, "", False
161
+
162
+
163
+ with gr.Blocks() as Demo:
164
+ with gr.Tabs():
165
+ with gr.Tab("Liveness Detection"):
166
+ header_box = gr.HTML(HTML_HEADER)
167
+ with gr.Row():
168
+ with gr.Column(scale=1):
169
+ input_img_path = gr.Image(
170
+ label="Input Image", type="filepath", height=300
171
+ )
172
+ gr.Examples(
173
+ [
174
+ "images/real_client054_android_SD_scene01.jpg",
175
+ "images/attack_client006_android_SD_ipad_video_scene01.jpg",
176
+ "images/attack_client055_android_SD_iphone_video_scene01.jpg",
177
+ "images/attack_client026_android_SD_printed_photo_scene01.jpg",
178
+ "images/attack_deepfake_1.jpeg",
179
+ "images/attack_deepfake_2.png",
180
+ "images/attack_deepfake_3.jpeg",
181
+ "images/tiktok_3d_mask.jpeg",
182
+ ],
183
+ inputs=input_img_path,
184
+ )
185
+ check_button = gr.Button("Check Liveness!", variant="primary")
186
+ with gr.Column():
187
+ liveness_result = gr.JSON(label="Liveness Result")
188
+ explanation_box = gr.HTML("", visible=False)
189
+
190
+ state = gr.State(False)
191
+ check_button.click(
192
+ check_liveness,
193
  inputs=input_img_path,
194
+ outputs=[liveness_result, explanation_box, state],
195
+ )
196
+ state.change(
197
+ lambda show: gr.update(visible=show),
198
+ inputs=state,
199
+ outputs=explanation_box,
200
+ )
201
+
202
+ with gr.Tab("Face Comparison"):
203
+ gr.HTML(HTML_FACE_COMPARISON_HEADER)
204
+ with gr.Row():
205
+ with gr.Column():
206
+ image1_input = gr.Image(
207
+ label="First Image", type="filepath", height=300
208
+ )
209
+ gr.Examples(
210
+ [
211
+ "images/brad_pitt_1.jpeg",
212
+ "images/brad_pitt_2.jpeg",
213
+ "images/angelina-jolie-1.jpeg",
214
+ "images/angelina-jolie-2.jpeg",
215
+ ],
216
+ inputs=image1_input,
217
+ )
218
+ with gr.Column():
219
+ image2_input = gr.Image(
220
+ label="Second Image", type="filepath", height=300
221
+ )
222
+ gr.Examples(
223
+ [
224
+ "images/brad_pitt_1.jpeg",
225
+ "images/brad_pitt_2.jpeg",
226
+ "images/angelina-jolie-1.jpeg",
227
+ "images/angelina-jolie-2.jpeg",
228
+ ],
229
+ inputs=image2_input,
230
+ )
231
+
232
+ compare_button = gr.Button("Compare Faces!", variant="primary")
233
+ comparison_result = gr.Label(label="Comparison Result")
234
+ gr.HTML(HTML_FACE_COMPARISON_EXPLANATION)
235
+
236
+ comparison_state = gr.State(False)
237
+ compare_button.click(
238
+ compare_faces,
239
+ inputs=[image1_input, image2_input],
240
+ outputs=[comparison_result, comparison_state],
241
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
 
243
 
244
  if __name__ == "__main__":
245
+ Demo.launch()
images/angelina-jolie-1.jpeg ADDED
images/angelina-jolie-2.jpeg ADDED
images/brad_pitt_1.jpeg ADDED
images/brad_pitt_2.jpeg ADDED
images/tiktok_3d_mask.jpeg ADDED