Smart Attendance - Liveness Detection Model

This repository contains the face liveness detection (anti-spoofing) model used in the Smart Attendance System. The model determines if a face presented to the camera is a real person (live) or a spoof attempt (e.g., a photo, video replay, or printout).

Model Details

  • Architecture: MobileNetV2 base (pretrained on ImageNet, fine-tuned) with a custom classification head.
  • Task: Binary Classification (Liveness vs. Spoof)
  • Input Shape: (224, 224, 3)
  • Preprocessing:
    • Convert image to BGR color space (since the model was trained on BGR images from OpenCV).
    • Resize to (224, 224).
    • Normalize pixel values to the range [-1.0, 1.0] using (x / 127.5) - 1.0.
  • Output: A single probability score between 0.0 and 1.0 (via Sigmoid activation).
    • Near 1.0 indicates a live person.
    • Near 0.0 indicates a spoof.

Architecture Specification

base_model = tf.keras.applications.MobileNetV2(
    input_shape=(224, 224, 3),
    include_top=False,
    weights=None
)
x = base_model.output
x = tf.keras.layers.GlobalAveragePooling2D()(x)
x = tf.keras.layers.Dropout(0.001)(x)
outputs = tf.keras.layers.Dense(1, activation="sigmoid")(x)
model = tf.keras.models.Model(inputs=base_model.input, outputs=outputs)

How to Use

To load and run inference with this model in Python:

import cv2
import numpy as np
import tensorflow as tf

# Load the weights
model_path = "liveness_mobilenet_v2.h5"

# Reconstruct model and load weights
base_model = tf.keras.applications.MobileNetV2(
    input_shape=(224, 224, 3),
    include_top=False,
    weights=None
)
x = base_model.output
x = tf.keras.layers.GlobalAveragePooling2D(name="global_average_pooling2d_3")(x)
x = tf.keras.layers.Dropout(0.001, name="dropout_3")(x)
outputs = tf.keras.layers.Dense(1, activation="sigmoid", name="dense_3")(x)
model = tf.keras.models.Model(inputs=base_model.input, outputs=outputs)
model.load_weights(model_path, by_name=True)

# Preprocessing function
def preprocess_liveness(face_crop: np.ndarray) -> np.ndarray:
    face_resized = cv2.resize(face_crop, (224, 224))
    face_normalized = (face_resized.astype(np.float32) / 127.5) - 1.0
    return np.expand_dims(face_normalized, axis=0)

# Run inference
# (Ensure face_crop is in BGR format before passing)
face_bgr = cv2.cvtColor(face_crop, cv2.COLOR_RGB2BGR)
input_tensor = preprocess_liveness(face_bgr)
prediction = model.predict(input_tensor)[0][0]
print(f"Liveness score: {prediction}")
Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support