File size: 7,034 Bytes
c88be80
 
 
b0f434e
2912dde
 
c88be80
74d9a64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c88be80
 
 
 
74d9a64
 
c88be80
74d9a64
c88be80
74d9a64
c88be80
74d9a64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c88be80
 
 
 
ad55b16
28dcf2b
4acc4e1
70df087
 
 
 
 
 
28dcf2b
 
 
c88be80
 
 
28dcf2b
 
 
 
 
 
 
 
 
7aa1468
 
 
 
 
 
 
 
 
 
 
 
 
74d9a64
 
fecade2
c88be80
0273261
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import gradio as gr
import requests
import datadog_api_client
from gradio.components import Image
from PIL import Image as PILImage, ImageDraw, ImageFont  # This import may be needed if you're processing images
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:
    gr.Markdown(
        """
    # KBY-AI - Face Recognition
    We offer SDKs for face recognition, liveness detection(anti-spoofing) and ID card recognition.
    <h4 style="display: flex; align-items: center;">
        ID Document Liveness Detection - Linux - <a href="https://web.kby-ai.com">https://web.kby-ai.com</a>
        <span>
            <img src="https://github.com/kby-ai/.github/assets/125717930/bcf351c5-8b7a-496e-a8f9-c236eb8ad59e" style="margin: 4px; width: 36px; height: 20px">
        </span>
    </h4>
    
    ##### KYC Verification Demo - https://github.com/kby-ai/KYC-Verification-Demo-Android
    ##### ID Capture Web Demo - https://id-document-recognition-react-alpha.vercel.app
    ##### Documentation - Help Center - https://docs.kby-ai.com
    """
    )
    with gr.TabItem("Face Recognition"):
        gr.Markdown(
            """
        ##### Docker Hub - https://hub.docker.com/r/kbyai/face-recognition
        ```bash
        sudo docker pull kbyai/face-recognition:latest
        sudo docker run -e LICENSE="xxxxx" -p 8081:8080 -p 9001:9000 kbyai/face-recognition:latest
        ```
        """
        )
        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/5.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/6.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)
    gr.HTML('<a href="https://visitorbadge.io/status?path=https%3A%2F%2Fhuggingface.co%2Fspaces%2Fkby-ai%2FFaceRecognition"><img src="https://api.visitorbadge.io/api/combined?path=https%3A%2F%2Fhuggingface.co%2Fspaces%2Fkby-ai%2FFaceRecognition&countColor=%23263759" /></a>')

demo.launch(server_name="0.0.0.0", server_port=7860, share=True)