Turing311 commited on
Commit
2cbace0
1 Parent(s): c0c35ea

Upload 33 files

Browse files
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ /data
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.8-slim
2
+ RUN apt-get update -y
3
+ RUN apt-get install -y libpcsclite-dev psmisc
4
+ RUN mkdir -p /root/kby-ai-idcard
5
+ WORKDIR /root/kby-ai-idcard
6
+ COPY ./libidsdk.so .
7
+ COPY ./idsdk.py .
8
+ COPY ./app.py .
9
+ COPY ./requirements.txt .
10
+ COPY ./data ./data
11
+ RUN pip3 install -r requirements.txt
12
+ CMD [ "python3", "app.py"]
13
+ EXPOSE 8080
README.md CHANGED
@@ -1,11 +1,187 @@
1
- ---
2
- title: Test1
3
- emoji: 🏆
4
- colorFrom: green
5
- colorTo: blue
6
- sdk: docker
7
- pinned: false
8
- license: mit
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <p align="center">
2
+ <a href="https://play.google.com/store/apps/dev?id=7086930298279250852" target="_blank">
3
+ <img alt="" src="https://github-production-user-asset-6210df.s3.amazonaws.com/125717930/246971879-8ce757c3-90dc-438d-807f-3f3d29ddc064.png" width=500/>
4
+ </a>
5
+ </p>
6
+
7
+ 👏 Product List
8
+
9
+ https://github.com/kby-ai/Product
10
+
11
+ 👏 We have published the Face Liveness Detection, Face Recognition SDK and ID Card Recognition SDK for the server.
12
+
13
+ - [FaceLivenessDetection-Docker](https://github.com/kby-ai/FaceLivenessDetection-Docker)
14
+
15
+ - [FaceRecognition-Docker](https://github.com/kby-ai/FaceRecognition-Docker)
16
+
17
+ - [IDCardRecognition-Docker](https://github.com/kby-ai/IDCardRecognition-Docker)
18
+
19
+ # IDCardRecognition-Docker
20
+
21
+ ## Introduction
22
+
23
+ The demo project demonstrates the server-based recognition capabilities for ID cards, passports, and driver's licenses.
24
+
25
+ At the core of this project lies the ID Card Recognition SDK, which has been developed to provide comprehensive support for recognizing ID cards, passports, and driver's licenses from over 180 countries.
26
+
27
+ > The demo is integrated with KBY-AI's ID Card Recognition Server SDK.
28
+
29
+ > For other solutions, please explore the following:
30
+ >
31
+ > [Face Liveness Detection - Android(Basic SDK)](https://github.com/kby-ai/FaceLivenessDetection-Android)
32
+ >
33
+ > [Face Liveness Detection - iOS(Basic SDK)](https://github.com/kby-ai/FaceLivenessDetection-iOS)
34
+ >
35
+ > [Face Recognition - Android(Stdndard SDK)](https://github.com/kby-ai/FaceRecognition-Android)
36
+ >
37
+ > [Face Recognition - iOS(Standard SDK)](https://github.com/kby-ai/FaceRecognition-iOS)
38
+ >
39
+ > [Face Recognition - Flutter(Standard SDK)](https://github.com/kby-ai/FaceRecognition-Flutter)
40
+ >
41
+ > [Face Recognition - React-Native(Standard SDK)](https://github.com/kby-ai/FaceRecognition-React-Native)
42
+ >
43
+ > [Face Attribute - Android(Premium SDK)](https://github.com/kby-ai/FaceAttribute-Android)
44
+ >
45
+ > [Face Attribute - iOS(Premium SDK)](https://github.com/kby-ai/FaceAttribute-iOS)
46
+
47
+ ## Try the API
48
+ ### Online Demo
49
+ You can test the SDK using images from the following URL:
50
+ https://web.kby-ai.com
51
+
52
+ ![image](https://github.com/kby-ai/IDCardRecognition-Docker/assets/125717930/ff395174-d3e9-4198-bfc8-6024a8c31734)
53
+
54
+ ### Postman
55
+ To test the API, you can use Postman. Here are the endpoints for testing:
56
+ - Test with an image file: Send a POST request to http://18.221.33.238:8082/idcard_recognition
57
+ - Test with a base64-encoded image: Send a POST request to http://18.221.33.238:8082/idcard_recognition_base64
58
+
59
+ You can download the Postman collection to easily access and use these endpoints. [click here](https://github.com/kby-ai/IDCardRecognition-Docker/tree/main/postman/kby-ai-idcard.postman_collection.json)
60
+
61
+ ![image](https://github.com/kby-ai/IDCardRecognition-Docker/assets/125717930/0ec93826-76d7-47a7-9065-6bd353bc79b3)
62
+
63
+ ## SDK License
64
+
65
+ This project uses KBY-AI's Face Recognition Server SDK, which requires a license per machine.
66
+
67
+ - The code below shows how to use the license: https://github.com/kby-ai/IDCardRecognition-Docker/blob/9f8138fa83d39a80a95e71b52048dbfc6579558c/app.py#L14-L25
68
+
69
+ - In order to request the license, please provide us with the machine code obtained from the "getMachineCode" function.
70
+
71
+ Please contact us:
72
+ ```
73
74
+
75
+ Telegram: @kbyai
76
+
77
+ WhatsApp: +19092802609
78
+
79
+ Skype: live:.cid.66e2522354b1049b
80
+
81
+ ## How to run
82
+
83
+ ### 1. System Requirements
84
+ - CPU: 2 cores or more (Recommended: 2 cores)
85
+ - RAM: 4 GB or more (Recommended: 8 GB)
86
+ - HDD: 4 GB or more (Recommended: 8 GB)
87
+ - OS: Ubuntu 20.04 or later
88
+
89
+ ### 2. Setup and Test
90
+ - Clone the project:
91
+ ```
92
+ git clone https://github.com/kby-ai/IDCardRecognition-Docker.git
93
+ ```
94
+ - Download the model from Google Drive: [click here](https://drive.google.com/file/d/19vA7ZOlo19BcW8v4iCoCGahUEbgKCo48/view?usp=sharing)
95
+ ```
96
+ cd IDCardRecognition-Docker
97
+
98
+ wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=1fmTUG7a9IoMA8QiXR9A0xf3Cr6D5UkdC' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=1fmTUG7a9IoMA8QiXR9A0xf3Cr6D5UkdC" -O data.zip && rm -rf /tmp/cookies.txt
99
+
100
+ unzip data.zip
101
+ ```
102
+ - Build the Docker image:
103
+ ```
104
+ sudo docker build --pull --rm -f Dockerfile -t kby-ai-idcard:latest .
105
+ ```
106
+ - Run the Docker container:
107
+ ```
108
+ sudo docker run -v ./license.txt:/root/kby-ai-idcard/license.txt -p 8082:8080 kby-ai-idcard
109
+ ```
110
+ - Send us the machine code and then we will give you a license key.
111
+
112
+ After that, update the license.txt file by overwriting the license key that you received. Then, run the Docker container again.
113
+
114
+ ![image](https://github.com/kby-ai/IDCardRecognition-Docker/assets/125717930/deab4a80-ae99-4646-a37d-b1441cff4dde)
115
+
116
+ ![image](https://github.com/kby-ai/IDCardRecognition-Docker/assets/125717930/7994cecd-05fb-42e7-a21d-986da0e2d796)
117
+
118
+ - To test the API, you can use Postman. Here are the endpoints for testing:
119
+
120
+ Test with an image file: Send a POST request to http://{xx.xx.xx.xx}:8082/idcard_recognition
121
+
122
+ Test with a base64-encoded image: Send a POST request to http://{xx.xx.xx.xx}:8082/idcard_recognition_base64
123
+
124
+ You can download the Postman collection to easily access and use these endpoints. [click here](https://github.com/kby-ai/IDCardRecognition-Docker/tree/main/postman/kby-ai-idcard.postman_collection.json)
125
+
126
+ ### 3. Execute the Gradio demo
127
+ - Setup Gradio
128
+ Ensure that you have the necessary dependencies installed.
129
+
130
+ Gradio requires Python 3.6 or above.
131
+
132
+ You can install Gradio using pip by running the following command:
133
+ ```
134
+ pip install gradio
135
+ ```
136
+ - Run the demo
137
+ Run it using the following command:
138
+ ```
139
+ cd gradio
140
+ python demo.py
141
+ ```
142
+ - You can test within the following URL:
143
+ http://127.0.0.1:9000
144
+
145
+ ## About SDK
146
+
147
+ ### 1. Initializing the SDK
148
+
149
+ - Step One
150
+
151
+ First, obtain the machine code for activation and request a license based on the machine code.
152
+ ```
153
+ machineCode = getMachineCode()
154
+ print("machineCode: ", machineCode.decode('utf-8'))
155
+ ```
156
+
157
+ - Step Two
158
+
159
+ Next, activate the SDK using the received license.
160
+ ```
161
+ setActivation(license.encode('utf-8'))
162
+ ```
163
+ If activation is successful, the return value will be SDK_SUCCESS. Otherwise, an error value will be returned.
164
+
165
+ - Step Three
166
+
167
+ After activation, call the initialization function of the SDK.
168
+ ```
169
+ initSDK()
170
+ ```
171
+ If initialization is successful, the return value will be SDK_SUCCESS. Otherwise, an error value will be returned.
172
+
173
+ ### 2. APIs
174
+
175
+ - ID Card Recognition
176
+
177
+ The SDK provides a single API for ID card recognition.
178
+
179
+ The function can be used as follows:
180
+
181
+ ```
182
+ ret = idcardRecognition(base64_image.encode('utf-8'))
183
+ ```
184
+
185
+ The function accepts only one parameter, which should be the base64-encoded format of the image (e.g., JPG, PNG, etc.).
186
+
187
+ If the recognition is successful, the function will return a JSON-formatted string containing the recognized information. In case of failure, the return value will be NULL.
app.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ sys.path.append('.')
3
+
4
+ import os
5
+ import base64
6
+ import json
7
+
8
+ from flask import Flask, request, jsonify
9
+ from idsdk import getMachineCode
10
+ from idsdk import setActivation
11
+ from idsdk import initSDK
12
+ from idsdk import idcardRecognition
13
+
14
+ licensePath = "license.txt"
15
+ license = ""
16
+
17
+ machineCode = getMachineCode()
18
+ print("machineCode: ", machineCode.decode('utf-8'))
19
+
20
+ try:
21
+ with open(licensePath, 'r') as file:
22
+ license = file.read()
23
+ except IOError as exc:
24
+ print("failed to open license.txt: ", exc.errno)
25
+ print("license: ", license)
26
+
27
+ ret = setActivation(license.encode('utf-8'))
28
+ print("activation: ", ret)
29
+
30
+ ret = initSDK()
31
+ print("init: ", ret)
32
+
33
+ app = Flask(__name__)
34
+
35
+ @app.route('/idcard_recognition', methods=['POST'])
36
+ def idcard_recognition():
37
+ try:
38
+ file = request.files['file']
39
+
40
+ base64_image = base64.b64encode(file.read()).decode('utf-8')
41
+ ret = idcardRecognition(base64_image.encode('utf-8'))
42
+
43
+ if ret != None:
44
+ j = json.loads(ret)
45
+ j.update({"Status": "Ok"})
46
+ response = jsonify(j)
47
+ else:
48
+ response = jsonify({"Status": "Error"})
49
+ except:
50
+ response = jsonify({"Status": "Error"})
51
+
52
+ response.status_code = 200
53
+ response.headers["Content-Type"] = "application/json; charset=utf-8"
54
+ return response
55
+
56
+ @app.route('/idcard_recognition_base64', methods=['POST'])
57
+ def idcard_recognition_base64():
58
+ try:
59
+ content = request.get_json()
60
+ base64_image = content['base64']
61
+
62
+ ret = idcardRecognition(base64_image.encode('utf-8'))
63
+
64
+ if ret != None:
65
+ j = json.loads(ret)
66
+ j.update({"Status": "Ok"})
67
+ response = jsonify(j)
68
+ else:
69
+ response = jsonify({"Status": "Error"})
70
+ except:
71
+ response = jsonify({"Status": "Error"})
72
+
73
+ response.status_code = 200
74
+ response.headers["Content-Type"] = "application/json; charset=utf-8"
75
+ return response
76
+
77
+ if __name__ == '__main__':
78
+ port = int(os.environ.get("PORT", 8080))
79
+ app.run(host='0.0.0.0', port=port)
data/detect.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0b505c320dd8add047f107549849a307d0c6f518f01c1d3402bce9e13a765146
3
+ size 28463173
data/eye.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c8281f9113d6fa4cc2f94ac8f4fdd3dbb7004b27adad39ac7175a802f9aaeed1
3
+ size 2446608
data/landmark.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b95b4e6043add90c16f97f00990973a6f8c6f3511491358772e734aa20f606bd
3
+ size 10828783
data/templates.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9214b2a4e3a83dffd64264e473ca60abe160bc5a4b9362dabc038e4a8618bfcf
3
+ size 87370348
gradio/demo.py ADDED
@@ -0,0 +1,357 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import datadog_api_client
4
+ from PIL import Image
5
+
6
+ def check_liveness(frame):
7
+ url = "http://127.0.0.1:8080/check_liveness"
8
+ file = {'file': open(frame, 'rb')}
9
+
10
+ r = requests.post(url=url, files=file)
11
+ result = r.json().get('face_state').get('result')
12
+
13
+ html = None
14
+ faces = None
15
+ if r.json().get('face_state').get('is_not_front') is not None:
16
+ liveness_score = r.json().get('face_state').get('liveness_score')
17
+ eye_closed = r.json().get('face_state').get('eye_closed')
18
+ is_boundary_face = r.json().get('face_state').get('is_boundary_face')
19
+ is_not_front = r.json().get('face_state').get('is_not_front')
20
+ is_occluded = r.json().get('face_state').get('is_occluded')
21
+ is_small = r.json().get('face_state').get('is_small')
22
+ luminance = r.json().get('face_state').get('luminance')
23
+ mouth_opened = r.json().get('face_state').get('mouth_opened')
24
+ quality = r.json().get('face_state').get('quality')
25
+
26
+ html = ("<table>"
27
+ "<tr>"
28
+ "<th>Face State</th>"
29
+ "<th>Value</th>"
30
+ "</tr>"
31
+ "<tr>"
32
+ "<td>Result</td>"
33
+ "<td>{result}</td>"
34
+ "</tr>"
35
+ "<tr>"
36
+ "<td>Liveness Score</td>"
37
+ "<td>{liveness_score}</td>"
38
+ "</tr>"
39
+ "<tr>"
40
+ "<td>Quality</td>"
41
+ "<td>{quality}</td>"
42
+ "</tr>"
43
+ "<tr>"
44
+ "<td>Luminance</td>"
45
+ "<td>{luminance}</td>"
46
+ "</tr>"
47
+ "<tr>"
48
+ "<td>Is Small</td>"
49
+ "<td>{is_small}</td>"
50
+ "</tr>"
51
+ "<tr>"
52
+ "<td>Is Boundary</td>"
53
+ "<td>{is_boundary_face}</td>"
54
+ "</tr>"
55
+ "<tr>"
56
+ "<td>Is Not Front</td>"
57
+ "<td>{is_not_front}</td>"
58
+ "</tr>"
59
+ "<tr>"
60
+ "<td>Face Occluded</td>"
61
+ "<td>{is_occluded}</td>"
62
+ "</tr>"
63
+ "<tr>"
64
+ "<td>Eye Closed</td>"
65
+ "<td>{eye_closed}</td>"
66
+ "</tr>"
67
+ "<tr>"
68
+ "<td>Mouth Opened</td>"
69
+ "<td>{mouth_opened}</td>"
70
+ "</tr>"
71
+ "</table>".format(liveness_score=liveness_score, quality=quality, luminance=luminance, is_small=is_small, is_boundary_face=is_boundary_face,
72
+ is_not_front=is_not_front, is_occluded=is_occluded, eye_closed=eye_closed, mouth_opened=mouth_opened, result=result))
73
+
74
+ else:
75
+ html = ("<table>"
76
+ "<tr>"
77
+ "<th>Face State</th>"
78
+ "<th>Value</th>"
79
+ "</tr>"
80
+ "<tr>"
81
+ "<td>Result</td>"
82
+ "<td>{result}</td>"
83
+ "</tr>"
84
+ "</table>".format(result=result))
85
+
86
+ try:
87
+ image = Image.open(frame)
88
+
89
+ for face in r.json().get('faces'):
90
+ x1 = face.get('x1')
91
+ y1 = face.get('y1')
92
+ x2 = face.get('x2')
93
+ y2 = face.get('y2')
94
+
95
+ if x1 < 0:
96
+ x1 = 0
97
+ if y1 < 0:
98
+ y1 = 0
99
+ if x2 >= image.width:
100
+ x2 = image.width - 1
101
+ if y2 >= image.height:
102
+ y2 = image.height - 1
103
+
104
+ face_image = image.crop((x1, y1, x2, y2))
105
+ face_image_ratio = face_image.width / float(face_image.height)
106
+ resized_w = int(face_image_ratio * 150)
107
+ resized_h = 150
108
+
109
+ face_image = face_image.resize((int(resized_w), int(resized_h)))
110
+
111
+ if faces is None:
112
+ faces = face_image
113
+ else:
114
+ new_image = Image.new('RGB',(faces.width + face_image.width + 10, 150), (80,80,80))
115
+
116
+ new_image.paste(faces,(0,0))
117
+ new_image.paste(face_image,(faces.width + 10, 0))
118
+ faces = new_image.copy()
119
+ except:
120
+ pass
121
+
122
+ return [faces, html]
123
+
124
+ def compare_face(frame1, frame2):
125
+ url = "http://127.0.0.1:8081/compare_face"
126
+ files = {'file1': open(frame1, 'rb'), 'file2': open(frame2, 'rb')}
127
+
128
+ r = requests.post(url=url, files=files)
129
+
130
+ html = None
131
+ faces = None
132
+
133
+ compare_result = r.json().get('compare_result')
134
+ compare_similarity = r.json().get('compare_similarity')
135
+
136
+ html = ("<table>"
137
+ "<tr>"
138
+ "<th>Compare Result</th>"
139
+ "<th>Value</th>"
140
+ "</tr>"
141
+ "<tr>"
142
+ "<td>Result</td>"
143
+ "<td>{compare_result}</td>"
144
+ "</tr>"
145
+ "<tr>"
146
+ "<td>Similarity</td>"
147
+ "<td>{compare_similarity}</td>"
148
+ "</tr>"
149
+ "</table>".format(compare_result=compare_result, compare_similarity=compare_similarity))
150
+
151
+ try:
152
+ image1 = Image.open(frame1)
153
+ image2 = Image.open(frame2)
154
+
155
+ face1 = None
156
+ face2 = None
157
+
158
+ if r.json().get('face1') is not None:
159
+ face = r.json().get('face1')
160
+ x1 = face.get('x1')
161
+ y1 = face.get('y1')
162
+ x2 = face.get('x2')
163
+ y2 = face.get('y2')
164
+
165
+ if x1 < 0:
166
+ x1 = 0
167
+ if y1 < 0:
168
+ y1 = 0
169
+ if x2 >= image1.width:
170
+ x2 = image1.width - 1
171
+ if y2 >= image1.height:
172
+ y2 = image1.height - 1
173
+
174
+ face1 = image1.crop((x1, y1, x2, y2))
175
+ face_image_ratio = face1.width / float(face1.height)
176
+ resized_w = int(face_image_ratio * 150)
177
+ resized_h = 150
178
+
179
+ face1 = face1.resize((int(resized_w), int(resized_h)))
180
+
181
+ if r.json().get('face2') is not None:
182
+ face = r.json().get('face2')
183
+ x1 = face.get('x1')
184
+ y1 = face.get('y1')
185
+ x2 = face.get('x2')
186
+ y2 = face.get('y2')
187
+
188
+ if x1 < 0:
189
+ x1 = 0
190
+ if y1 < 0:
191
+ y1 = 0
192
+ if x2 >= image2.width:
193
+ x2 = image2.width - 1
194
+ if y2 >= image2.height:
195
+ y2 = image2.height - 1
196
+
197
+ face2 = image2.crop((x1, y1, x2, y2))
198
+ face_image_ratio = face2.width / float(face2.height)
199
+ resized_w = int(face_image_ratio * 150)
200
+ resized_h = 150
201
+
202
+ face2 = face2.resize((int(resized_w), int(resized_h)))
203
+
204
+ if face1 is not None and face2 is not None:
205
+ new_image = Image.new('RGB',(face1.width + face2.width + 10, 150), (80,80,80))
206
+
207
+ new_image.paste(face1,(0,0))
208
+ new_image.paste(face2,(face1.width + 10, 0))
209
+ faces = new_image.copy()
210
+ elif face1 is not None and face2 is None:
211
+ new_image = Image.new('RGB',(face1.width + face1.width + 10, 150), (80,80,80))
212
+
213
+ new_image.paste(face1,(0,0))
214
+ faces = new_image.copy()
215
+ elif face1 is None and face2 is not None:
216
+ new_image = Image.new('RGB',(face2.width + face2.width + 10, 150), (80,80,80))
217
+
218
+ new_image.paste(face2,(face2.width + 10, 0))
219
+ faces = new_image.copy()
220
+
221
+ except:
222
+ pass
223
+
224
+ return [faces, html]
225
+
226
+ def idcard_recognition(frame):
227
+ url = "http://127.0.0.1:8082/idcard_recognition"
228
+ files = {'file': open(frame, 'rb')}
229
+
230
+ r = requests.post(url=url, files=files)
231
+
232
+ html = None
233
+ images = None
234
+ mrz = None
235
+
236
+ status = r.json().get('Status')
237
+ table_value = ""
238
+
239
+ if r.json().get('MRZ') is not None:
240
+ mrz = r.json().get('MRZ')
241
+
242
+ for key, value in r.json().items():
243
+ if key == 'Status' or key == 'Images' or key == 'MRZ' or key == 'Position':
244
+ continue
245
+
246
+ mrz_value = ''
247
+ if mrz is not None and mrz.get(key) is not None:
248
+ mrz_value = mrz[key]
249
+ del mrz[key]
250
+
251
+ row_value = ("<tr>"
252
+ "<td>{key}</td>"
253
+ "<td>{value}</td>"
254
+ "<td>{mrz_value}</td>"
255
+ "</tr>".format(key=key, value=value, mrz_value=mrz_value))
256
+ table_value = table_value + row_value
257
+
258
+
259
+ if mrz is not None:
260
+ for key, value in mrz.items():
261
+ if key == 'MRZ':
262
+ value = value.replace('<', '&lt;')
263
+ value = value.replace(',', '<p>')
264
+
265
+ row_value = ("<tr>"
266
+ "<td>{key}</td>"
267
+ "<td>{value}</td>"
268
+ "<td>{mrz_value}</td>"
269
+ "</tr>".format(key=key, value='', mrz_value=value))
270
+ table_value = table_value + row_value
271
+
272
+
273
+ html = ("<table>"
274
+ "<tr>"
275
+ "<th style=""width:20%"">Field</th>"
276
+ "<th style=""width:40%"">Value</th>"
277
+ "<th style=""width:40%"">MRZ</th>"
278
+ "</tr>"
279
+ "<tr>"
280
+ "<td>Status</td>"
281
+ "<td>{status}</td>"
282
+ "<td></td>"
283
+ "</tr>"
284
+ "{table_value}"
285
+ "</table>".format(status=status, table_value=table_value))
286
+
287
+ table_value = ""
288
+ for key, value in r.json().items():
289
+ if key == 'Images':
290
+ for image_key, image_value in value.items():
291
+ row_value = ("<tr>"
292
+ "<td>{key}</td>"
293
+ "<td><img src=""data:image/png;base64,{base64_image} width = '200' height= '100' /></td>"
294
+ "</tr>".format(key=image_key, base64_image=image_value))
295
+ table_value = table_value + row_value
296
+
297
+ images = ("<table>"
298
+ "<tr>"
299
+ "<th>Field</th>"
300
+ "<th>Image</th>"
301
+ "</tr>"
302
+ "{table_value}"
303
+ "</table>".format(table_value=table_value))
304
+
305
+ return [html, images]
306
+
307
+ with gr.Blocks() as demo:
308
+ gr.Markdown(
309
+ """
310
+ # KBY-AI Technology
311
+ We offer SDKs for face recognition, liveness detection, and ID card recognition.
312
+ """
313
+ )
314
+ with gr.TabItem("Face Liveness Detection"):
315
+ with gr.Row():
316
+ with gr.Column():
317
+ live_image_input = gr.Image(type='filepath')
318
+ gr.Examples(['live_examples/1.jpg', 'live_examples/2.jpg', 'live_examples/3.jpg', 'live_examples/4.jpg'],
319
+ inputs=live_image_input)
320
+ check_liveness_button = gr.Button("Check Liveness")
321
+ with gr.Column():
322
+ liveness_face_output = gr.Image(type="pil").style(height=150)
323
+ livness_result_output = gr.HTML()
324
+
325
+ check_liveness_button.click(check_liveness, inputs=live_image_input, outputs=[liveness_face_output, livness_result_output])
326
+ with gr.TabItem("Face Recognition"):
327
+ with gr.Row():
328
+ with gr.Column():
329
+ compare_face_input1 = gr.Image(type='filepath')
330
+ gr.Examples(['face_examples/1.jpg', 'face_examples/3.jpg', 'face_examples/5.jpg', 'face_examples/7.jpg', 'face_examples/9.jpg'],
331
+ inputs=compare_face_input1)
332
+ compare_face_button = gr.Button("Compare Face")
333
+ with gr.Column():
334
+ compare_face_input2 = gr.Image(type='filepath')
335
+ gr.Examples(['face_examples/2.jpg', 'face_examples/4.jpg', 'face_examples/6.jpg', 'face_examples/8.jpg', 'face_examples/10.jpg'],
336
+ inputs=compare_face_input2)
337
+ with gr.Column():
338
+ compare_face_output = gr.Image(type="pil").style(height=150)
339
+ compare_result_output = gr.HTML(label='Result')
340
+
341
+ compare_face_button.click(compare_face, inputs=[compare_face_input1, compare_face_input2], outputs=[compare_face_output, compare_result_output])
342
+ with gr.TabItem("ID Card Recognition"):
343
+ with gr.Row():
344
+ with gr.Column(scale=3):
345
+ id_image_input = gr.Image(type='filepath')
346
+ gr.Examples(['idcard_examples/1.jpg', 'idcard_examples/2.jpg', 'idcard_examples/3.jpg'],
347
+ inputs=id_image_input)
348
+ id_recognition_button = gr.Button("ID Card Recognition")
349
+ with gr.Column(scale=5):
350
+ id_result_output = gr.HTML()
351
+
352
+ with gr.Column(scale=2):
353
+ image_result_output = gr.HTML()
354
+
355
+ id_recognition_button.click(idcard_recognition, inputs=id_image_input, outputs=[id_result_output, image_result_output])
356
+
357
+ demo.launch(server_name="0.0.0.0", server_port=9000)
gradio/face_examples/1.jpg ADDED
gradio/face_examples/10.jpg ADDED
gradio/face_examples/2.jpg ADDED
gradio/face_examples/3.jpg ADDED
gradio/face_examples/4.jpg ADDED
gradio/face_examples/5.jpg ADDED
gradio/face_examples/6.jpg ADDED
gradio/face_examples/7.jpg ADDED
gradio/face_examples/8.jpg ADDED
gradio/face_examples/9.jpg ADDED
gradio/idcard_examples/1.jpg ADDED
gradio/idcard_examples/2.jpg ADDED
gradio/idcard_examples/3.jpg ADDED
gradio/live_examples/1.jpg ADDED
gradio/live_examples/2.jpg ADDED
gradio/live_examples/3.jpg ADDED
gradio/live_examples/4.jpg ADDED
header/idsdk.h ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #pragma once
2
+
3
+ #ifdef __cplusplus
4
+ extern "C" {
5
+ #endif
6
+
7
+ enum SDK_ERROR
8
+ {
9
+ SDK_SUCCESS = 0,
10
+ SDK_LICENSE_KEY_ERROR = -1,
11
+ SDK_LICENSE_APPID_ERROR = -2,
12
+ SDK_LICENSE_EXPIRED = -3,
13
+ SDK_NO_ACTIVATED = -4,
14
+ SDK_INIT_ERROR = -5,
15
+ };
16
+
17
+
18
+ /*
19
+ * Get the machine code for SDK activation
20
+ */
21
+ const char* getMachineCode();
22
+
23
+ /*
24
+ * Activate the SDK using the provided license
25
+ */
26
+
27
+ int setActivation(char* license);
28
+
29
+ /*
30
+ * Initialize the SDK with the specified model path
31
+ */
32
+ int initSDK();
33
+
34
+ /*
35
+ * The function accepts only one parameter, which should be the base64-encoded format of the image (e.g., JPG, PNG, etc.).
36
+ * If the recognition is successful, the function will return a JSON-formatted string containing the recognized information. In case of failure, the return value will be NULL.
37
+ */
38
+ char* idcardRecognition(char* image_base64);
39
+
40
+ #ifdef __cplusplus
41
+ }
42
+ #endif
idsdk.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ from ctypes import *
4
+
5
+ libPath = os.path.abspath(os.path.dirname(__file__)) + '/libidsdk.so'
6
+ idsdk = cdll.LoadLibrary(libPath)
7
+
8
+ getMachineCode = idsdk.getMachineCode
9
+ getMachineCode.argtypes = []
10
+ getMachineCode.restype = c_char_p
11
+
12
+ setActivation = idsdk.setActivation
13
+ setActivation.argtypes = [c_char_p]
14
+ setActivation.restype = c_int32
15
+
16
+ initSDK = idsdk.initSDK
17
+ initSDK.argtypes = []
18
+ initSDK.restype = c_int32
19
+
20
+ idcardRecognition = idsdk.idcardRecognition
21
+ idcardRecognition.argtypes = [c_char_p]
22
+ idcardRecognition.restype = c_char_p
23
+
license.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ To obtain the license, please get in touch with us through the following contact details:
2
+
3
4
+ Telegram: @kbyai
5
+ WhatsApp: +19092802609
6
+ Skype: live:.cid.66e2522354b1049b
postman/kby-ai-idcard.postman_collection.json ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "info": {
3
+ "_postman_id": "ae453c9a-d672-4e3d-bf4e-3847473197bc",
4
+ "name": "kby-ai-idcard",
5
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
6
+ "_exporter_id": "2379931"
7
+ },
8
+ "item": [
9
+ {
10
+ "name": "idcard_recognition",
11
+ "request": {
12
+ "method": "POST",
13
+ "header": [],
14
+ "body": {
15
+ "mode": "formdata",
16
+ "formdata": [
17
+ {
18
+ "key": "file",
19
+ "type": "file",
20
+ "src": []
21
+ }
22
+ ]
23
+ },
24
+ "url": {
25
+ "raw": "http://18.221.33.238:8082/idcard_recognition",
26
+ "protocol": "http",
27
+ "host": [
28
+ "18",
29
+ "221",
30
+ "33",
31
+ "238"
32
+ ],
33
+ "port": "8082",
34
+ "path": [
35
+ "idcard_recognition"
36
+ ]
37
+ }
38
+ },
39
+ "response": []
40
+ },
41
+ {
42
+ "name": "idcard_recognition_base64",
43
+ "request": {
44
+ "method": "POST",
45
+ "header": [],
46
+ "body": {
47
+ "mode": "raw",
48
+ "raw": "{\r\n \"base64\":\"xxx\"\r\n}",
49
+ "options": {
50
+ "raw": {
51
+ "language": "json"
52
+ }
53
+ }
54
+ },
55
+ "url": {
56
+ "raw": "http://127.0.0.1:8082/idcard_recognition_base64",
57
+ "protocol": "http",
58
+ "host": [
59
+ "127",
60
+ "0",
61
+ "0",
62
+ "1"
63
+ ],
64
+ "port": "8082",
65
+ "path": [
66
+ "idcard_recognition_base64"
67
+ ]
68
+ }
69
+ },
70
+ "response": []
71
+ }
72
+ ]
73
+ }
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ flask
2
+ flask-cors