Spaces:
Running
Running
| import gradio as gr | |
| import requests | |
| import datadog_api_client | |
| import json | |
| import io | |
| import base64 | |
| from PIL import Image | |
| def face_crop(image, face_rect): | |
| x1 = face_rect.get('x1') | |
| y1 = face_rect.get('y1') | |
| x2 = face_rect.get('x2') | |
| y2 = face_rect.get('y2') | |
| width = x2 - x1 + 1 | |
| height = y2 - y1 + 1 | |
| if x1 < 0: | |
| x1 = 0 | |
| if y1 < 0: | |
| y1 = 0 | |
| if x2 >= image.width: | |
| x2 = image.width - 1 | |
| if y2 >= image.height: | |
| y2 = image.height - 1 | |
| face_image = image.crop((x1, y1, x2, y2)) | |
| face_image_ratio = face_image.width / float(face_image.height) | |
| resized_w = int(face_image_ratio * 150) | |
| resized_h = 150 | |
| face_image = face_image.resize((int(resized_w), int(resized_h))) | |
| return face_image | |
| def pil_image_to_base64(image, format="PNG"): | |
| """ | |
| Converts a PIL.Image object to a Base64-encoded string. | |
| :param image: PIL.Image object | |
| :param format: Format to save the image, e.g., "PNG", "JPEG" | |
| :return: Base64-encoded string | |
| """ | |
| # Save the image to a BytesIO buffer | |
| buffer = io.BytesIO() | |
| image.save(buffer, format=format) | |
| buffer.seek(0) # Rewind the buffer | |
| # Convert the buffer's contents to a Base64 string | |
| base64_string = base64.b64encode(buffer.getvalue()).decode('utf-8') | |
| return base64_string | |
| def compare_face(frame1, frame2): | |
| url = "http://127.0.0.1:8080/compare_face" | |
| files = {'file1': open(frame1, 'rb'), 'file2': open(frame2, 'rb')} | |
| file1 = None | |
| file2 = None | |
| try: | |
| file1 = open(frame1, 'rb') | |
| except: | |
| return "Failed to open image1" | |
| try: | |
| file2 = open(frame2, 'rb') | |
| except: | |
| return "Failed to open image2" | |
| url = "http://127.0.0.1:8080/compare_face" | |
| files = {'file1': file1, 'file2': file2} | |
| result = requests.post(url=url, files=files) | |
| if result.ok: | |
| json_result = result.json() | |
| if json_result.get("resultCode") != "Ok": | |
| return json_result.get("resultCode") | |
| try: | |
| image1 = Image.open(frame1) | |
| image2 = Image.open(frame2) | |
| html = "" | |
| faces1 = json_result.get("faces1", {}) | |
| faces2 = json_result.get("faces2", {}) | |
| results = json_result.get("results", {}) | |
| for result in results: | |
| similarity = result.get('similarity') | |
| face1_idx = result.get('face1') | |
| face2_idx = result.get('face2') | |
| face_image1 = face_crop(image1, faces1[face1_idx]) | |
| face_value1 = ('<img src="data:image/png;base64,{base64_image}" style="width: 100px; height: auto; object-fit: contain;"/>').format(base64_image=pil_image_to_base64(face_image1, format="PNG")) | |
| face_image2 = face_crop(image2, faces2[face2_idx]) | |
| face_value2 = ('<img src="data:image/png;base64,{base64_image}" style="width: 100px; height: auto; object-fit: contain;"/>').format(base64_image=pil_image_to_base64(face_image2, format="PNG")) | |
| match_icon = '<svg fill="red" width="19" height="32" viewBox="0 0 19 32"><path d="M0 13.92V10.2H19V13.92H0ZM0 21.64V17.92H19V21.64H0Z"></path><path d="M14.08 0H18.08L5.08 32H1.08L14.08 0Z"></path></svg>' | |
| if similarity > 0.67: | |
| match_icon = '<svg fill="green" width="19" height="32" viewBox="0 0 19 32"><path d="M0 13.9202V10.2002H19V13.9202H0ZM0 21.6402V17.9202H19V21.6402H0Z"></path></svg>' | |
| item_value = ('<div style="align-items: center; gap: 10px; display: flex; flex-direction: column;">' | |
| '<div style="display: flex; align-items: center; gap: 20px;">' | |
| '{face_value1}' | |
| '{match_icon}' | |
| '{face_value2}' | |
| '</div>' | |
| '<div style="text-align: center; margin-top: 10px;">' | |
| 'Similarity: {similarity}' | |
| '</div>' | |
| '</div>' | |
| ).format(face_value1=face_value1, face_value2=face_value2, match_icon=match_icon, similarity=f"{similarity:.2f}") | |
| html += item_value | |
| html += '<hr style="border: 1px solid #C0C0C0; margin: 10px 0;"/>' | |
| return html | |
| except: | |
| return "Processing failed" | |
| else: | |
| return result.text | |
| with gr.Blocks() as demo: | |
| with gr.Row(): | |
| with gr.Column(scale=7): | |
| with gr.Row(): | |
| with gr.Column(): | |
| image_input1 = gr.Image(type='filepath') | |
| gr.Examples(['face_examples/1.jpg', 'face_examples/3.jpg', 'face_examples/7.jpg', 'face_examples/9.jpg'], | |
| inputs=image_input1) | |
| with gr.Column(): | |
| image_input2 = gr.Image(type='filepath') | |
| gr.Examples(['face_examples/2.jpg', 'face_examples/4.jpg', 'face_examples/8.jpg', 'face_examples/10.jpg'], | |
| inputs=image_input2) | |
| face_recog_button = gr.Button("Compare Face", variant="primary", size="lg") | |
| with gr.Column(scale=3): | |
| recog_html_output = gr.HTML() | |
| face_recog_button.click(compare_face, inputs=[image_input1, image_input2], outputs=recog_html_output) | |
| demo.launch(server_name="0.0.0.0", server_port=7860) |