Views
No views yet
(224, 224, 3)(224, 224).[-1.0, 1.0] using (x / 127.5) - 1.0.0.0 and 1.0 (via Sigmoid activation).
1.0 indicates a live person.0.0 indicates a spoof.1base_model = tf.keras.applications.MobileNetV2(
2 input_shape=(224, 224, 3),
3 include_top=False,
4 weights=None
5)
6x = base_model.output
7x = tf.keras.layers.GlobalAveragePooling2D()(x)
8x = tf.keras.layers.Dropout(0.001)(x)
9outputs = tf.keras.layers.Dense(1, activation="sigmoid")(x)
10model = tf.keras.models.Model(inputs=base_model.input, outputs=outputs)1import cv2
2import numpy as np
3import tensorflow as tf
4
5# Load the weights
6model_path = "liveness_mobilenet_v2.h5"
7
8# Reconstruct model and load weights
9base_model = tf.keras.applications.MobileNetV2(
10 input_shape=(224, 224, 3),
11 include_top=False,
12 weights=None
13)
14x = base_model.output
15x = tf.keras.layers.GlobalAveragePooling2D(name="global_average_pooling2d_3")(x)
16x = tf.keras.layers.Dropout(0.001, name="dropout_3")(x)
17outputs = tf.keras.layers.Dense(1, activation="sigmoid", name="dense_3")(x)
18model = tf.keras.models.Model(inputs=base_model.input, outputs=outputs)
19model.load_weights(model_path, by_name=True)
20
21# Preprocessing function
22def preprocess_liveness(face_crop: np.ndarray) -> np.ndarray:
23 face_resized = cv2.resize(face_crop, (224, 224))
24 face_normalized = (face_resized.astype(np.float32) / 127.5) - 1.0
25 return np.expand_dims(face_normalized, axis=0)
26
27# Run inference
28# (Ensure face_crop is in BGR format before passing)
29face_bgr = cv2.cvtColor(face_crop, cv2.COLOR_RGB2BGR)
30input_tensor = preprocess_liveness(face_bgr)
31prediction = model.predict(input_tensor)[0][0]
32print(f"Liveness score: {prediction}")