Spaces:
Running
Running
import sys | |
import os | |
import io | |
import gradio as gr | |
import json | |
import requests | |
from PIL import Image | |
from flask import request | |
import sqlite3 | |
from datetime import datetime, timedelta | |
# Initialize SQLite database | |
css = """ | |
.example-image img{ | |
display: flex; /* Use flexbox to align items */ | |
justify-content: center; /* Center the image horizontally */ | |
align-items: center; /* Center the image vertically */ | |
height: 300px; /* Set the height of the container */ | |
object-fit: contain; /* Preserve aspect ratio while fitting the image within the container */ | |
} | |
.example-image img{ | |
display: flex; /* Use flexbox to align items */ | |
text-align: center; | |
justify-content: center; /* Center the image horizontally */ | |
align-items: center; /* Center the image vertically */ | |
height: 350px; /* Set the height of the container */ | |
object-fit: contain; /* Preserve aspect ratio while fitting the image within the container */ | |
} | |
.markdown-success-container { | |
background-color: #F6FFED; | |
padding: 20px; | |
margin: 20px; | |
border-radius: 1px; | |
border: 2px solid green; | |
text-align: center; | |
} | |
.markdown-fail-container { | |
background-color: #FFF1F0; | |
padding: 20px; | |
margin: 20px; | |
border-radius: 1px; | |
border: 2px solid red; | |
text-align: center; | |
} | |
.block-background { | |
# background-color: #202020; /* Set your desired background color */ | |
border-radius: 5px; | |
} | |
""" | |
# Initialize SQLite database | |
conn = sqlite3.connect("ip_requests.db") | |
cursor = conn.cursor() | |
cursor.execute(""" | |
CREATE TABLE IF NOT EXISTS requests ( | |
ip_address TEXT PRIMARY KEY, | |
count INTEGER, | |
last_request TIMESTAMP | |
) | |
""") | |
conn.commit() | |
def track_requests(ip_address): | |
now = datetime.now() | |
cursor.execute("SELECT count, last_request FROM requests WHERE ip_address=?", (ip_address,)) | |
result = cursor.fetchone() | |
if result: | |
count, last_request = result | |
last_request = datetime.strptime(last_request, "%Y-%m-%d %H:%M:%S") | |
if now - last_request > timedelta(days=1): | |
count = 0 | |
else: | |
count = 0 | |
count += 1 | |
cursor.execute(""" | |
INSERT OR REPLACE INTO requests (ip_address, count, last_request) | |
VALUES (?, ?, ?) | |
""", (ip_address, count, now.strftime("%Y-%m-%d %H:%M:%S"))) | |
conn.commit() | |
return count | |
screenReplayThreshold = 0.5 | |
portraitReplaceThreshold = 0.5 | |
printedCopyThreshold = 0.5 | |
def find_key_in_dict(d, target_key): | |
for key, value in d.items(): | |
if key == target_key: | |
return value | |
elif isinstance(value, dict): # If the value is a dictionary, search recursively | |
result = find_key_in_dict(value, target_key) | |
if result is not None: | |
return result | |
return None | |
def json_to_html_table(data, image_keys): | |
html = "<table border='1' style='border-collapse: collapse; width: 100%;'>" | |
for key, value in data.items(): | |
if isinstance(value, dict): | |
html += f"<tr><td colspan='2'><strong>{key}</strong></td></tr>" | |
for sub_key, sub_value in value.items(): | |
if sub_key in image_keys: | |
html += f"<tr><td>{sub_key}</td><td><img src='data:image/png;base64,{sub_value}' width = '200' height= '100' /></td></tr>" | |
else: | |
html += f"<tr><td>{sub_key}</td><td>{sub_value}</td></tr>" | |
else: | |
if key in image_keys: | |
html += f"<tr><td>{key}</td><td><img src='data:image/png;base64,{value}' width = '200' height= '100' /></td></tr>" | |
else: | |
html += f"<tr><td>{key}</td><td>{value}</td></tr>" | |
html += "</table>" | |
return html | |
def check_liveness(frame): | |
if frame is None: | |
liveness_result = f"""<div class="markdown-fail-container"><p style="text-align: center; font-size: 20px; color: red;">Liveness Check Failed</p></div>""" | |
return [liveness_result, {"status": "error", "result": "select image file!"}] | |
img_bytes = io.BytesIO() | |
Image.open(frame).save(img_bytes, format="JPEG") | |
img_bytes.seek(0) | |
url = "https://api.cortex.cerebrium.ai/v4/p-4f1d877e/my-first-project/check-liveness/" | |
try: | |
files = [ | |
('file', ('image.jpg', img_bytes, 'image/jpeg')) | |
] | |
headers = { | |
'Authorization': 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9qZWN0SWQiOiJwLTRmMWQ4NzdlIiwiaWF0IjoxNzM5MjM2NjA5LCJleHAiOjIwNTQ4MTI2MDl9.0LH0iOnqHZfKTH4GF5iTZ4qNj5vylCryo8rBnErljsq2qD2cpVTetCqhKtnbstTUEjuv6MAJw9jt58z-QNJfYLK9sJcnBhawTR3iM2Ap_bFyjlzg2LbgkwRPjUVJkkcuCRhBKyebXwvqQBvWyOtMq6UekauumbmYBRbA2-T4u343YD4tO2xIfsTsTXznALp1SechjRuys-3xo3ZQbUs05_p38fOFucKI-abc91Eq6sIOkLFjYEM68yuV0UBWl-OSpPu66e0SClroAVlKFDMPS9MY0Jr7X1pBYX4jew6vozj9D8Y-HS-KkdPFqJ7HrZOfQd0wGUgYJHyC58yReWXaRQ', | |
# 'Content-Type': 'application/json' | |
} | |
result = requests.post(url=url, files=files, headers=headers) | |
except: | |
liveness_result = f"""<div class="markdown-fail-container"><p style="text-align: center; font-size: 20px; color: red;">Liveness Check Failed</p></div>""" | |
return [liveness_result, {"status": "error", "result": "failed to open file!"}] | |
print("the result is", result) | |
if result.ok: | |
json_result = result.json() | |
if json_result.get("resultCode") == "Error": | |
liveness_result = f"""<div class="markdown-fail-container"><p style="text-align: center; font-size: 20px; color: red;">Liveness Check Failed</p></div>""" | |
return [liveness_result, {"status": "error", "result": "server error!"}] | |
if 'data' in json_result: | |
data = json_result['data'] | |
print("the result data is is",data) | |
if data["IsLive"] : | |
liveness_result = f"""<div class="markdown-success-container"><p style="text-align: center; font-size: 20px; color: green;">Liveness Check: Live </p></div>""" | |
json_output = {"Is Live": "Success", | |
"document Type": data["DocumentType"], | |
# "Printed Cutout Check": "Failed" if printedCopy < printedCopyThreshold else "Success" | |
} | |
# Update json_result with the modified process_results | |
return [liveness_result, json_output] | |
else: | |
liveness_result = f"""<div class="markdown-fail-container"><p style="text-align: center; font-size: 20px; color: red;">Liveness Check: Fake </p></div>""" | |
json_output = {"Is Live": "Failed", | |
"document Type": data["DocumentType"], | |
# "Printed Cutout Check": "Failed" if printedCopy < printedCopyThreshold else "Success" | |
} | |
# Update json_result with the modified process_results | |
return [liveness_result, json_output] | |
liveness_result = f"""<div class="markdown-fail-container"><p style="text-align: center; font-size: 20px; color: red;">Liveness Check Failed</p></div>""" | |
return [liveness_result, {"status": "error", "result": "document not found!"}] | |
else: | |
liveness_result = f"""<div class="markdown-fail-container"><p style="text-align: center; font-size: 20px; color: red;">Liveness Check Failed</p></div>""" | |
return [liveness_result, {"status": "error", "result": f"{result.text}"}] | |
def idcard_recognition(frame1): | |
ip_address = request.remote_addr | |
request_count = track_requests(ip_address) | |
print("you have exceeded the daily limit of 5 requests", request_count) | |
if request_count > 3: | |
print("you have exceeded the daily limit of 5 requests") | |
return "You have exceeded the daily limit of 5 requests." | |
url = "https://api.cortex.cerebrium.ai/v4/p-4f1d877e/my-first-project/process-image/" | |
# url = "https://edreesi-ocr-api.hf.space/process-image/" | |
files = None | |
if frame1 is not None: | |
# Open the image using Pillow | |
img = Image.open(frame1).convert("RGB") # Convert to RGB to remove alpha channels | |
img_bytes = io.BytesIO() | |
# Save the image in JPEG format with consistent quality | |
img.save(img_bytes, format="JPEG", quality=95, optimize=True, exif=b"") # Strip EXIF metadata | |
img_bytes.seek(0) # Reset the file pointer | |
# Log the file size for debugging | |
print("Gradio File Size:", len(img_bytes.getvalue()), "bytes") | |
# Prepare the files payload | |
files = [ | |
('file', ('image.jpg', img_bytes, 'image/jpeg')) | |
] | |
else: | |
return ['', None, None] | |
# headers = {"X-RapidAPI-Key": os.environ.get("API_KEY")} | |
headers = {} | |
# r = requests.post(url=url, files=files, headers=headers) | |
# r = requests.request("POST", url, headers=headers, data={}, files=files) | |
payload = json.dumps({"prompt": "your value here"}) | |
headers = { | |
'Authorization': 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9qZWN0SWQiOiJwLTRmMWQ4NzdlIiwiaWF0IjoxNzM5MjM2NjA5LCJleHAiOjIwNTQ4MTI2MDl9.0LH0iOnqHZfKTH4GF5iTZ4qNj5vylCryo8rBnErljsq2qD2cpVTetCqhKtnbstTUEjuv6MAJw9jt58z-QNJfYLK9sJcnBhawTR3iM2Ap_bFyjlzg2LbgkwRPjUVJkkcuCRhBKyebXwvqQBvWyOtMq6UekauumbmYBRbA2-T4u343YD4tO2xIfsTsTXznALp1SechjRuys-3xo3ZQbUs05_p38fOFucKI-abc91Eq6sIOkLFjYEM68yuV0UBWl-OSpPu66e0SClroAVlKFDMPS9MY0Jr7X1pBYX4jew6vozj9D8Y-HS-KkdPFqJ7HrZOfQd0wGUgYJHyC58yReWXaRQ', | |
# 'Content-Type': 'application/json' | |
} | |
r = requests.request("POST", url, headers=headers, data={}, files=files) | |
# print(r.text) | |
print("Status Code:", r.status_code) | |
print("r Body:", r.text) | |
# r = requests.post(url=url, files=files, headers=headers) | |
print('the result is', r.json()) | |
images = None | |
rawValues = {} | |
image_table_value = "" | |
result_table_dict = { | |
'portrait':'', | |
'type':'', | |
'score':'', | |
# 'countryName':'', | |
'FullName':'', | |
'Gender':'', | |
'PlaceOfBirth':'', | |
'DateOfBirth':'', | |
'IssuanceCenter':'', | |
'IdentityNumber':'', | |
'DateOfIssue':'', | |
'DateOfExpiry':'', | |
} | |
if 'data' in r.json(): | |
data = r.json()['data'] | |
for key, value in data.items(): | |
if key == 'faceImage': | |
# Assign faceImage to the portrait field | |
result_table_dict['portrait'] = value | |
elif key == 'barcodeImage': | |
# Add barcodeImage to the result dictionary | |
result_table_dict['barcodeImage'] = value | |
else: | |
# Add other fields to the result dictionary | |
result_table_dict[key] = value | |
# Generate HTML for images | |
image_table_value = "" | |
if 'barcodeImage' in data: | |
image_table_value += ( | |
"<tr>" | |
f"<td>barcodeImage</td>" | |
f"<td><img src='data:image/png;base64,{data['barcodeImage']}' width='200' height='100' /></td>" | |
"</tr>" | |
) | |
# Generate the final HTML table for images | |
images = ( | |
"<table>" | |
"<tr>" | |
"<th>Field</th>" | |
"<th>Image</th>" | |
"</tr>" | |
f"{image_table_value}" | |
"</table>" | |
) | |
# Prepare raw values for JSON output | |
for key, value in r.json().items(): | |
if key == 'data': | |
if 'faceImage' in value: | |
del value['faceImage'] | |
if 'barcodeImage' in value: | |
del value['barcodeImage'] | |
rawValues[key] = value | |
else: | |
rawValues[key] = value | |
# Generate the result HTML table | |
result = json_to_html_table(result_table_dict, {'portrait', 'barcodeImage'}) | |
json_result = json.dumps(rawValues, indent=6) | |
return [result, json_result, images] | |
def launch_demo(): | |
with gr.Blocks(css=css) as demo: | |
gr.Markdown( | |
f""" | |
<p style="font-size: 20px; font-weight: bold;">π Product Documentation</p> | |
<div style="display: flex; align-items: center;"> | |
  <a href="" style="display: flex; align-items: center;"><img src="https://recognito.vision/wp-content/uploads/2024/05/book.png" style="width: 48px; margin-right: 5px;"/></a> | |
</div> | |
<p style="font-size: 20px; font-weight: bold;">π Visit Recognito</p> | |
<br/> | |
""" | |
) | |
with gr.Tabs(): | |
with gr.Tab("ID Document Recognition"): | |
with gr.Row(): | |
with gr.Column(scale=6): | |
with gr.Row(): | |
with gr.Column(scale=6): | |
id_image_input1 = gr.Image(type='filepath', label='ID Card Image', elem_classes="example-image") | |
# with gr.Column(scale=3): | |
# id_image_input2 = gr.Image(type='filepath', label='Back', elem_classes="example-image") | |
# with gr.Row(): | |
# id_examples = gr.Examples( | |
# examples=[['examples/1_f.png', 'examples/1_b.png'], | |
# ['examples/2_f.png', 'examples/2_b.png'], | |
# ['examples/3_f.png', 'examples/3_b.png'], | |
# ['examples/4.png', None]], | |
# inputs=[id_image_input1, id_image_input1], | |
# outputs=None, | |
# fn=idcard_recognition | |
# ) | |
with gr.Blocks(): | |
with gr.Column(scale=4, min_width=400, elem_classes="block-background"): | |
id_recognition_button = gr.Button("ID Card Recognition", variant="primary", size="lg") | |
with gr.Tab("Key Fields"): | |
id_result_output = gr.HTML() | |
with gr.Tab("Raw JSON"): | |
json_result_output = gr.JSON() | |
with gr.Tab("Images"): | |
image_result_output = gr.HTML() | |
id_recognition_button.click(idcard_recognition, inputs=id_image_input1, outputs=[id_result_output, json_result_output, image_result_output]) | |
with gr.Tab("Id Card Liveness Detection"): | |
with gr.Row(): | |
with gr.Column(scale=1): | |
id_image_input = gr.Image(label="Image", type='filepath', elem_classes="example-image") | |
gr.Examples(examples=['examples/1_f.png', 'examples/2_f.png', 'examples/3_f.png', 'examples/4.png'], inputs=id_image_input) | |
with gr.Blocks(): | |
with gr.Column(scale=1, elem_classes="block-background"): | |
check_liveness_button = gr.Button("Check Document Liveness", variant="primary", size="lg") | |
liveness_result = gr.Markdown("") | |
json_output = gr.JSON() | |
check_liveness_button.click(check_liveness, inputs=id_image_input, outputs=[liveness_result, json_output]) | |
gr.HTML('<a href="https://visitorbadge.io/status?path=https%3A%2F%2Fedreesi-card-recognition.hf.space%2F"><img src="https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fedreesi-card-recognition.hf.space%2F&countColor=%23263759" /></a>') | |
demo.launch(server_name="0.0.0.0", server_port=7860, show_api=False) | |
if __name__ == '__main__': | |
launch_demo() |