File size: 6,592 Bytes
3f635ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
"""

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()