""" Mock Face Recognition Module for Testing (Windows-friendly) This is a simplified version that doesn't require dlib/face_recognition For production, install the full face_recognition library """ import numpy as np import cv2 from config import Config import logging import hashlib # Set up logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) logger.warning("Using MOCK face recognition module - for testing only!") logger.warning("Install face_recognition library for production use") class FaceRecognitionModule: """Mock face recognition for testing without dlib dependencies""" def __init__(self, tolerance=None, model='hog'): self.tolerance = tolerance or Config.FACE_RECOGNITION_TOLERANCE self.model = model logger.info(f"Mock Face Recognition Module initialized") def detect_faces(self, image_array): """Mock face detection using OpenCV Haar Cascades""" try: # Convert to grayscale gray = cv2.cvtColor(image_array, cv2.COLOR_RGB2GRAY) # Load Haar cascade for face detection face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') # Detect faces faces = face_cascade.detectMultiScale(gray, 1.3, 5) # Convert to format similar to face_recognition library face_locations = [(y, x+w, y+h, x) for (x, y, w, h) in faces] logger.info(f"Detected {len(face_locations)} face(s)") return face_locations except Exception as e: logger.error(f"Face detection error: {str(e)}") return [] def generate_face_encoding(self, image_array): """ Mock encoding generation using image hash In production, this would use deep learning-based face encodings """ try: face_locations = self.detect_faces(image_array) if len(face_locations) == 0: return False, "No face detected in the image. Please ensure your face is clearly visible." if len(face_locations) > 1: return False, "Multiple faces detected. Please ensure only one person is in the frame." # Create a simple "encoding" using image hash (for testing only) # In production, this would be a 128-dimensional face encoding top, right, bottom, left = face_locations[0] face_region = image_array[top:bottom, left:right] # Resize to standard size face_resized = cv2.resize(face_region, (100, 100)) # Create hash-based encoding (mock) face_bytes = face_resized.tobytes() hash_obj = hashlib.sha256(face_bytes) hash_digest = hash_obj.digest() # Get bytes directly # Convert to numpy array (128 dimensions to match real encodings) # Use hash bytes to create 128-dimensional vector encoding = np.array([float(b) for b in hash_digest[:128]] + [0.0] * (128 - len(hash_digest[:128]))) logger.info("Mock face encoding generated") return True, encoding except Exception as e: logger.error(f"Face encoding error: {str(e)}") return False, f"Face encoding failed: {str(e)}" def verify_face(self, captured_encoding, stored_encoding): """ Mock face verification using encoding similarity In production, this would use Euclidean distance between face encodings """ try: if captured_encoding is None or stored_encoding is None: return False, 0.0 # Convert to numpy arrays if not isinstance(captured_encoding, np.ndarray): captured_encoding = np.array(captured_encoding) if not isinstance(stored_encoding, np.ndarray): stored_encoding = np.array(stored_encoding) # Calculate similarity (mock - using correlation) # In production, this would be face_recognition.face_distance() correlation = np.corrcoef(captured_encoding, stored_encoding)[0, 1] # Convert to distance (0 = identical, 1 = completely different) distance = 1 - abs(correlation) # Calculate confidence confidence = (1 - distance) * 100 # Check if match is_match = distance <= self.tolerance logger.info(f"Mock verification: match={is_match}, confidence={confidence:.2f}%") return is_match, confidence except Exception as e: logger.error(f"Face verification error: {str(e)}") return False, 0.0 def register_face(self, image_array): """Complete face registration""" try: face_locations = self.detect_faces(image_array) if len(face_locations) == 0: return False, "No face detected. Please ensure your face is clearly visible and well-lit.", None if len(face_locations) > 1: return False, "Multiple faces detected. Please ensure only one person is in the frame.", None success, result = self.generate_face_encoding(image_array) if success: return True, result, face_locations[0] else: return False, result, None except Exception as e: logger.error(f"Face registration error: {str(e)}") return False, f"Registration failed: {str(e)}", None def compare_faces_batch(self, known_encodings, face_encoding_to_check): """Compare against multiple encodings""" try: matches = [] for known_encoding in known_encodings: is_match, _ = self.verify_face(face_encoding_to_check, known_encoding) matches.append(is_match) return matches except Exception as e: logger.error(f"Batch comparison error: {str(e)}") return [] # Singleton instance face_recognition_module = FaceRecognitionModule()