File size: 5,285 Bytes
a8692b4
 
 
 
 
 
 
 
6e7c0d5
a8692b4
158c296
6e7c0d5
 
 
a8692b4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6e7c0d5
 
f9fd3d3
 
6e7c0d5
 
 
a8692b4
6e7c0d5
 
 
 
 
 
 
 
 
 
 
 
a8692b4
6e7c0d5
 
a8692b4
6e7c0d5
 
 
 
a8692b4
 
 
 
6e7c0d5
a8692b4
6e7c0d5
 
 
 
 
 
 
 
5485495
 
 
6e7c0d5
5485495
 
 
6e7c0d5
a8692b4
10e1832
 
a8692b4
6e7c0d5
a8692b4
 
 
 
 
 
 
 
 
 
6e7c0d5
 
 
 
 
 
 
 
 
 
 
1dee27c
6e7c0d5
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
166
import sys
sys.path.append('../')

import os
import base64
import json
import cv2
import numpy as np
import gradio as gr
from time import gmtime, strftime
from pydantic import BaseModel
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import JSONResponse
from typing import Dict

from engine.header import *

file_path = os.path.abspath(__file__)
dir_path = os.path.dirname(file_path)
root_path = os.path.dirname(dir_path)

MATCH_THRESHOLD = 0.67

version = get_version().decode('utf-8')
print_info('\t <Recognito Face Recognition> \t version {}'.format(version))

device_id = get_deviceid().decode('utf-8')
print_info('\t <Hardware ID> \t\t {}'.format(device_id))

def activate_sdk():
    online_key = os.environ.get("FR_LICENSE_KEY")
    offline_key_path = os.path.join(root_path, "license.txt")
    dict_path = os.path.join(root_path, "engine/bin")

    ret = -1
    if online_key is None:
        print_warning("Recognition online license key not found!")
    else:
        ret = init_sdk(dict_path.encode('utf-8'), online_key.encode('utf-8'))

    if ret == 0:
        print_log("Successfully online init SDK!")
    else:
        print_error(f"Failed to online init SDK, Error code {ret}\n Trying offline init SDK...");
        if os.path.exists(offline_key_path) is False:
            print_warning("Recognition offline license key file not found!")
            print_error(f"Falied to offline init SDK, Error code {ret}")
            return ret
        else:
            ret = init_sdk_offline(dict_path.encode('utf-8'), offline_key_path.encode('utf-8'))
            if ret == 0:
                print_log("Successfully offline init SDK!")
            else:
                print_error(f"Falied to offline init SDK, Error code {ret}")
                return ret
                
    return ret

def generate_response(result, similarity=None, face_bboxes=None, face_features=None):
    status = "ok"
    data = {
        "status": status, 
        "data": {}
    }
    
    data["data"]["result"] = result    
    if similarity is not None:
        data["data"]["similarity"] = float(similarity)    
    images = [{}, {}]
    if face_bboxes is not None:
        for i, bbox in enumerate(face_bboxes):
            box = {
                "x" : int(bbox[0]),
                "y" : int(bbox[1]),
                "width" : int(bbox[2] - bbox[0] + 1),
                "height" : int(bbox[3] - bbox[1] + 1)
            }
            images[i]["detection"] = box
        
    if face_features is not None:
        for i, feat in enumerate(face_features):
            json_string = json.dumps(feat.tolist(), indent=0).replace('\n','')
            images[i]["feature"] = json_string
            
    data["data"]["image1"] = images[0]
    data["data"]["image2"] = images[1]

    return JSONResponse(content=data, status_code=200)

app = FastAPI()

@app.get("/")
def read_root():
    return {"status": "API is running"}

def read_image(file: UploadFile) -> np.ndarray:
    # Read the image file and convert it to OpenCV format
    image_bytes = file.file.read()
    image_np = np.frombuffer(image_bytes, np.uint8)
    image = cv2.imdecode(image_np, cv2.IMREAD_COLOR)
    return image
    
@app.post("/api/compare_face")
async def compare_face_api(
    image1: UploadFile = File(...),
    image2: UploadFile = File(...)
) -> JSONResponse:
    try:
        image_mat1 = read_image(image1)
        image_mat2 = read_image(image2)

    except Exception as e:
        response = generate_response("Failed to open image")
        return response
        
    result, score, face_bboxes, face_features = compare_face(image_mat1, image_mat2, MATCH_THRESHOLD)
    response = generate_response(result, score, face_bboxes, face_features)
    return response

def decode_base64_image(base64_string: str) -> np.ndarray:
    try:
        image_data = base64.b64decode(base64_string)
        image_np = np.frombuffer(image_data, np.uint8)
        image = cv2.imdecode(image_np, cv2.IMREAD_COLOR)
        if image is None:
            raise ValueError("Decoded image is None")
        return image
    except Exception as e:
        raise ValueError(f"Failed to decode base64 image: {str(e)}")

class CompareFaceRequest(BaseModel):
    image1: str
    image2: str
    
@app.post("/api/compare_face_base64")
async def compare_face_base64_api(request: CompareFaceRequest) -> JSONResponse:
    
    try:
        image_mat1 = decode_base64_image(request.image1)
        image_mat2 = decode_base64_image(request.image2)
    except:
        response = generate_response("Failed to open image")
        return response

    result, score, face_bboxes, face_features = compare_face(image_mat1, image_mat2, MATCH_THRESHOLD)
    response = generate_response(result, score, face_bboxes, face_features)
    return response

if __name__ == '__main__':
    ret = activate_sdk()
    if ret != 0:
        exit(-1)

    dummy_interface = gr.Interface(
        fn=lambda x: "API ready.",
        inputs=gr.Textbox(label="Info"),
        outputs=gr.Textbox(label="Response"),
        allow_flagging="never"  # 🚫 disables writing to `flagged/`
    )
    
    gr_app = gr.mount_gradio_app(app, dummy_interface, path="/gradio")
    
    import uvicorn
    uvicorn.run(gr_app, host="0.0.0.0", port=7860)