SmartKYC – AI-Driven Digital Onboarding
Hackathon Prototype Code (FastAPI + OCR + Face Match)
This document contains the full backend prototype code for SmartKYC — an AI-powered digital
onboarding solution. It performs OCR on uploaded ID documents, compares the ID photo with a
selfie for identity verification, and calculates a simple risk score to automate the KYC process.
import os
import cv2
import numpy as np
import pytesseract
import tempfile
from fastapi import FastAPI, UploadFile, File
from [Link] import JSONResponse
from PIL import Image
try:
import face_recognition
FACE_LIB = True
except ImportError:
FACE_LIB = False
app = FastAPI(title="SmartKYC – AI-Driven Digital Onboarding")
def save_temp(upload_file: UploadFile):
suffix = [Link](upload_file.filename)[1]
fd, path = [Link](suffix=suffix)
with [Link](fd, "wb") as f:
[Link](upload_file.[Link]())
return path
def extract_text(img):
pil = [Link](img)
text = pytesseract.image_to_string(pil)
return text
def detect_face(img):
gray = [Link](img, cv2.COLOR_RGB2GRAY)
face_cascade = [Link]([Link] + 'haarcascade_frontalface_default.xml'
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
if len(faces) == 0:
return None
x, y, w, h = max(faces, key=lambda r: r[2]*r[3])
return img[y:y+h, x:x+w]
def compare_faces(img1, img2):
if FACE_LIB:
enc1 = face_recognition.face_encodings(img1)
enc2 = face_recognition.face_encodings(img2)
if not enc1 or not enc2:
return False, None
dist = [Link](enc1[0] - enc2[0])
return dist < 0.6, round(float(dist), 3)
else:
h1 = [Link]([img1], [0], None, [256], [0,256])
h2 = [Link]([img2], [0], None, [256], [0,256])
score = [Link](h1, h2, cv2.HISTCMP_CORREL)
return score > 0.5, round(float(score), 3)
@[Link]("/verify_kyc")
async def verify_kyc(id_doc: UploadFile = File(...), selfie: UploadFile = File(...)):
id_path = save_temp(id_doc)
selfie_path = save_temp(selfie)
id_img = [Link]([Link](id_path).convert("RGB"))
selfie_img = [Link]([Link](selfie_path).convert("RGB"))
text = extract_text(id_img)
import re
aadhaar = [Link](r'\b\d{4}\s?\d{4}\s?\d{4}\b', text)
pan = [Link](r'[A-Z]{5}\d{4}[A-Z]', text)
fields = {"aadhaar": aadhaar[0] if aadhaar else None, "pan": pan[0] if pan else None}
face1 = detect_face(id_img)
face2 = detect_face(selfie_img)
match = False
score = None
if face1 is not None and face2 is not None:
match, score = compare_faces(face1, face2)
risk = 0
if not fields["aadhaar"] and not fields["pan"]:
risk += 0.4
if not match:
risk += 0.4
risk = round(min(1, risk), 2)
decision = "Approved" if risk < 0.3 else ("Review" if risk < 0.7 else "Rejected")
result = {
"Extracted_Text_Snippet": text[:150],
"Parsed_Fields": fields,
"Face_Match": match,
"Face_Score": score,
"Risk_Score": risk,
"Decision": decision
}
[Link](id_path)
[Link](selfie_path)
return JSONResponse(content=result)
Run Instructions:
1. Install dependencies:
pip install fastapi uvicorn pillow opencv-python pytesseract face_recognition numpy
2. Run server:
uvicorn smartkyc_api:app --reload
3. Test API:
POST → [Link]
Upload fields: id_doc (ID image), selfie (user selfie)