c-luis-e's picture
Update app.py
06d28c6 verified
from flask import Flask, request, jsonify, render_template
from verifier import AIFRKTPVerification
from deepface import DeepFace
import cv2
import numpy as np
import base64
import os
import uuid
# This is the line Gunicorn looks for. It must be named 'app'.
app = Flask(__name__)
# Initialize the verifier once when the server starts
face_verifier = AIFRKTPVerification()
def image_to_base64(img_stream):
"""Converts an image stream to a base64 string for embedding in HTML."""
return base64.b64encode(img_stream).decode('utf-8')
# --- Web Demo Routes ---
@app.route('/', methods=['GET', 'POST'])
def similarity_demo():
"""Handles the visual web demo for similarity checking."""
if request.method == 'POST':
if 'ktp_image' not in request.files or 'selfie_image' not in request.files:
return "Missing one or both images", 400
ktp_file, selfie_file = request.files['ktp_image'], request.files['selfie_image']
ktp_stream, selfie_stream = ktp_file.read(), selfie_file.read()
ktp_img = cv2.imdecode(np.frombuffer(ktp_stream, np.uint8), cv2.IMREAD_COLOR)
selfie_img = cv2.imdecode(np.frombuffer(selfie_stream, np.uint8), cv2.IMREAD_COLOR)
if ktp_img is None or selfie_img is None:
return "Could not decode one or both images.", 400
result = face_verifier.verify_with_images(ktp_img, selfie_img)
ktp_base64 = image_to_base64(ktp_stream)
selfie_base64 = image_to_base64(selfie_stream)
return render_template(
'index.html',
verification_result=result,
ktp_image_url=f"data:image/jpeg;base64,{ktp_base64}",
selfie_image_url=f"data:image/jpeg;base64,{selfie_base64}"
)
return render_template('index.html')
@app.route('/liveness', methods=['GET', 'POST'])
def liveness_demo():
"""Handles the visual web demo for the liveness check."""
if request.method == 'POST':
if 'liveness_image' not in request.files:
return "Missing image file", 400
image_file = request.files['liveness_image']
image_stream = image_file.read()
# Save temporarily for DeepFace, as it works best with a file path
temp_filename = f"/tmp/{uuid.uuid4().hex}.jpg"
with open(temp_filename, 'wb') as f:
f.write(image_stream)
try:
face_objs = DeepFace.extract_faces(
img_path=temp_filename, enforce_detection=False,
detector_backend='opencv', anti_spoofing=True
)
if not face_objs:
return "No face detected in the image.", 400
is_real = face_objs[0]['is_real']
liveness_result = {'liveness_passed': bool(is_real)}
image_base64 = image_to_base64(image_stream)
return render_template(
'liveness.html',
liveness_result=liveness_result,
image_url=f"data:image/jpeg;base64,{image_base64}"
)
finally:
# Clean up the temporary file
if os.path.exists(temp_filename):
os.remove(temp_filename)
return render_template('liveness.html')
# --- API Routes for iOS App ---
@app.route('/api/verify', methods=['POST'])
def api_verify():
"""Handles the similarity check for the iOS app and returns JSON."""
if 'ktp_image' not in request.files or 'selfie_image' not in request.files:
return jsonify({'error': 'Two images are required'}), 400
try:
ktp_file = request.files['ktp_image'].read()
selfie_file = request.files['selfie_image'].read()
ktp_img = cv2.imdecode(np.frombuffer(ktp_file, np.uint8), cv2.IMREAD_COLOR)
selfie_img = cv2.imdecode(np.frombuffer(selfie_file, np.uint8), cv2.IMREAD_COLOR)
if ktp_img is None or selfie_img is None:
return jsonify({'error': 'Could not decode images.'}), 400
result = face_verifier.verify_with_images(ktp_img, selfie_img)
if 'error' in result:
return jsonify(result), 400
return jsonify(result)
except Exception as e:
print(f"Error in /api/verify: {e}")
return jsonify({'error': 'Internal server error.'}), 500
@app.route('/api/liveness', methods=['POST'])
def api_liveness_check():
"""Handles the liveness check for the iOS app and returns JSON."""
if 'image' not in request.files:
return jsonify({'error': 'An image file is required.'}), 400
image_file = request.files['image']
temp_filename = f"/tmp/{uuid.uuid4().hex}.jpg"
image_file.save(temp_filename)
try:
face_objs = DeepFace.extract_faces(
img_path=temp_filename, enforce_detection=False,
detector_backend='opencv', anti_spoofing=True
)
if not face_objs:
return jsonify({'error': 'No face detected in the image.'}), 400
is_real = face_objs[0]['is_real']
confidence = face_objs[0]['confidence']
return jsonify({'liveness_passed': bool(is_real), 'confidence': float(confidence)})
except Exception as e:
print(f"Error in /api/liveness: {e}")
return jsonify({'error': 'An internal error occurred.'}), 500
finally:
if os.path.exists(temp_filename):
os.remove(temp_filename)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)