File size: 6,651 Bytes
407b7fd
4de922e
 
 
 
 
 
 
 
 
407b7fd
4de922e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94ada36
 
4de922e
 
 
 
407b7fd
4de922e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2d013f4
407b7fd
4de922e
 
 
 
 
 
407b7fd
 
4de922e
 
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
162
163
164
165
166
167
168
169
170
import gradio as gr
import tensorflow as tf
import cv2
import numpy as np
import os
import time
import dlib
import mediapipe as mp
from skimage import feature
# from your_cnn_model import YourCNNModel  # Import your CNN model

class AntiSpoofingSystem:
    def __init__(self):
        self.detector = dlib.get_frontal_face_detector()
        self.predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
        self.mp_hands = mp.solutions.hands
        self.hands = self.mp_hands.Hands(static_image_mode=False, max_num_hands=1, min_detection_confidence=0.7)
        self.net_smartphone = cv2.dnn.readNet('yolov4.weights', 'yolov4.cfg')
        with open('coco.names', 'r') as f:
            self.classes_smartphone = f.read().strip().split('\n')
        self.EAR_THRESHOLD = 0.25
        self.BLINK_CONSEC_FRAMES = 4
        self.left_eye_state = False
        self.right_eye_state = False
        self.left_blink_counter = 0
        self.right_blink_counter = 0
        self.smartphone_detected = False
        self.smartphone_detection_frame_interval = 30
        self.frame_count = 0

    def calculate_ear(self, eye):
        A = np.linalg.norm(eye[1] - eye[5])
        B = np.linalg.norm(eye[2] - eye[4])
        C = np.linalg.norm(eye[0] - eye[3])
        return (A + B) / (2.0 * C)

    def analyze_texture(self, face_region):
        gray_face = cv2.cvtColor(face_region, cv2.COLOR_BGR2GRAY)
        lbp = feature.local_binary_pattern(gray_face, P=8, R=1, method="uniform")
        lbp_hist, _ = np.histogram(lbp.ravel(), bins=np.arange(0, 58), range=(0, 58))
        lbp_hist = lbp_hist.astype("float")
        lbp_hist /= (lbp_hist.sum() + 1e-5)
        return np.sum(lbp_hist[:10]) > 0.3

    def detect_hand_gesture(self, frame):
        results = self.hands.process(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
        return results.multi_hand_landmarks is not None

    def detect_smartphone(self, frame):
        if self.frame_count % self.smartphone_detection_frame_interval == 0:
            blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)
            self.net_smartphone.setInput(blob)
            output_layers_names = self.net_smartphone.getUnconnectedOutLayersNames()
            detections = self.net_smartphone.forward(output_layers_names)
            for detection in detections:
                for obj in detection:
                    scores = obj[5:]
                    class_id = np.argmax(scores)
                    confidence = scores[class_id]
                    if confidence > 0.5 and self.classes_smartphone[class_id] == 'cell phone':
                        self.smartphone_detected = True
                        self.left_blink_counter = 0
                        self.right_blink_counter = 0
                        return
        self.frame_count += 1
        self.smartphone_detected = False

    def detect_blink(self, left_ear, right_ear):
        if self.smartphone_detected:
            self.left_eye_state = False
            self.right_eye_state = False
            self.left_blink_counter = 0
            self.right_blink_counter = 0
            return False

        if left_ear < self.EAR_THRESHOLD:
            if not self.left_eye_state:
                self.left_eye_state = True
        else:
            if self.left_eye_state:
                self.left_eye_state = False
                self.left_blink_counter += 1

        if right_ear < self.EAR_THRESHOLD:
            if not self.right_eye_state:
                self.right_eye_state = True
        else:
            if self.right_eye_state:
                self.right_eye_state = False
                self.right_blink_counter += 1

        return self.left_blink_counter > 0 and self.right_blink_counter > 0

    def run(self, input_image):
        frame = input_image
        blink_count = 0
        hand_gesture_detected = False
        real_person_detected = False
        cropped_face = None

        self.detect_smartphone(frame)

        if not self.smartphone_detected:
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            faces = self.detector(gray)

            for face in faces:
                landmarks = self.predictor(gray, face)
                leftEye = np.array([(landmarks.part(n).x, landmarks.part(n).y) for n in range(36, 42)])
                rightEye = np.array([(landmarks.part(n).x, landmarks.part(n).y) for n in range(42, 48)])

                ear_left = self.calculate_ear(leftEye)
                ear_right = self.calculate_ear(rightEye)

                if self.detect_blink(ear_left, ear_right):
                    blink_count += 1

                hand_gesture_detected = self.detect_hand_gesture(frame)

                (x, y, w, h) = (face.left(), face.top(), face.width(), face.height())
                cropped_face = frame[max(y - h // 2, 0):min(y + 3 * h // 2, frame.shape[0]),
                                     max(x - w // 2, 0):min(x + 3 * w // 2, frame.shape[1])]

                if blink_count >= 5 and hand_gesture_detected and self.analyze_texture(cropped_face):
                    real_person_detected = True
                    break

        return real_person_detected, cropped_face

# Initialize the anti-spoofing system
anti_spoofing_system = AntiSpoofingSystem()

# Load your CNN model (this is a placeholder for your actual model loading code)
supervised_embedding_model = tf.keras.models.load_model('v3_embedding_model (2).h5')
#cnn_model.load_weights('v3_embedding_model (2).h5')

def process_frame(image):
    real_person_detected, cropped_face = anti_spoofing_system.run(image)

    if not real_person_detected:
        return image, "No real person detected or spoofing attempt."

    # Placeholder for actual CNN model prediction
    person_id, confidence = "PersonID", 0.99  # Replace with your CNN model logic

    result_text = f"Person identified: {person_id} with confidence: {confidence}" if person_id else "Person not recognized. Registration required."
    cv2.putText(image, result_text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
    return image

def video_stream():
    cap = cv2.VideoCapture(0)
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        processed_frame = process_frame(frame)
        yield processed_frame

iface = gr.Interface(
    fn=video_stream,
    inputs=None,
    outputs=gr.outputs.Video(label="Output Video"),
    live=True,
    title="Live Face Recognition and Verification System",
    description="Live detection and verification of persons from a camera feed."
)

if __name__ == "__main__":
    iface.launch()