Spaces:
Sleeping
Sleeping
| import sys | |
| import json | |
| import math | |
| import requests | |
| from deepface import DeepFace | |
| from PIL import Image | |
| from io import BytesIO | |
| # Function: smoother and higher confidence for genuine matches | |
| def sigmoid_confidence(distance, threshold): | |
| x = (threshold - distance) * 10 # scale the confidence curve | |
| confidence = 1 / (1 + math.exp(-x)) * 100 | |
| return round(confidence, 2) | |
| def validate_image_url(url): | |
| """Validate that the URL points to a valid image""" | |
| try: | |
| print(f"Validating image URL: {url}", file=sys.stderr) | |
| response = requests.get(url, timeout=30) | |
| response.raise_for_status() | |
| # Check if it's actually an image | |
| content_type = response.headers.get('content-type', '') | |
| if not content_type.startswith('image/'): | |
| raise Exception(f"URL does not point to an image. Content-Type: {content_type}") | |
| # Try to open the image to validate it | |
| image_data = response.content | |
| if len(image_data) == 0: | |
| raise Exception("Image file is empty") | |
| image = Image.open(BytesIO(image_data)) | |
| print(f"Image validation successful: {image.format} {image.size}", file=sys.stderr) | |
| return True | |
| except Exception as e: | |
| print(f"Image validation failed for {url}: {str(e)}", file=sys.stderr) | |
| return False | |
| def download_and_save_image(url, output_path): | |
| """Download image and save it locally""" | |
| try: | |
| print(f"Downloading image from {url} to {output_path}", file=sys.stderr) | |
| response = requests.get(url, timeout=30) | |
| response.raise_for_status() | |
| with open(output_path, 'wb') as f: | |
| f.write(response.content) | |
| print(f"Successfully downloaded {len(response.content)} bytes to {output_path}", file=sys.stderr) | |
| return output_path | |
| except Exception as e: | |
| print(f"Error downloading image from {url}: {str(e)}", file=sys.stderr) | |
| raise | |
| selfie_url = sys.argv[1] | |
| id_url = sys.argv[2] | |
| print(f"Processing face verification:", file=sys.stderr) | |
| print(f" Selfie URL: {selfie_url}", file=sys.stderr) | |
| print(f" ID URL: {id_url}", file=sys.stderr) | |
| try: | |
| # Validate both images first | |
| if not validate_image_url(selfie_url): | |
| raise Exception(f"Invalid selfie image URL: {selfie_url}") | |
| if not validate_image_url(id_url): | |
| raise Exception(f"Invalid ID image URL: {id_url}") | |
| # Download images to local files | |
| selfie_path = "temp_selfie.jpg" | |
| id_path = "temp_id.jpg" | |
| download_and_save_image(selfie_url, selfie_path) | |
| download_and_save_image(id_url, id_path) | |
| print(f"Starting DeepFace verification with local files:", file=sys.stderr) | |
| print(f" Selfie: {selfie_path}", file=sys.stderr) | |
| print(f" ID: {id_path}", file=sys.stderr) | |
| result = DeepFace.verify( | |
| img1_path=selfie_path, | |
| img2_path=id_path, | |
| model_name='ArcFace', | |
| detector_backend='retinaface', # Best detection & alignment | |
| enforce_detection=True | |
| ) | |
| distance = result['distance'] | |
| threshold = result['threshold'] | |
| # Use sigmoid-based confidence | |
| confidence_score = sigmoid_confidence(distance, threshold) | |
| result['confidence'] = confidence_score | |
| print(f"DeepFace verification successful: {result}", file=sys.stderr) | |
| print(json.dumps(result)) | |
| except Exception as e: | |
| error_msg = f"Face verification failed: {str(e)}" | |
| print(error_msg, file=sys.stderr) | |
| print(json.dumps({"error": error_msg})) | |
| sys.exit(1) | |