Attender / face_recognition_module.py
chualinwei3's picture
Upload 33 files
3f635ef verified
Raw
History Blame Contribute Delete
6.59 kB
"""
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()