How to Use Face Anti-Spoofing for Liveness Detection with Ailia Models
Face anti-spoofing liveness detection uses a lightweight MN3 Large neural network to classify faces as real or spoof in real-time, combining optional Blazeface detection with softmax probability thresholds.
The axinc-ai/ailia-models repository provides a production-ready implementation of face anti-spoofing for liveness detection. The face-anti-spoofing.py script delivers an end-to-end pipeline that distinguishes between live faces and presentation attacks using a MobileNetV3 architecture optimized for edge deployment.
Architecture of the Face Anti-Spoofing System
Model and Dependency Management
The pipeline relies on the MN3_large.onnx model, a MobileNetV3 variant trained for binary classification (real vs. spoof). When face detection is enabled, the system also downloads blazefaceback.onnx for bounding box extraction. The util/model_utils.py module handles automatic retrieval from the Ailia model bucket if files are missing.
Pre-processing Pipeline
Input frames undergo strict normalization before inference. In face_recognition/face-anti-spoofing/face-anti-spoofing.py, the preprocess() function converts BGR to RGB, resizes images to 128×128 pixels, and applies per-channel mean and standard deviation normalization. The data is then transposed to CHW format, batched, and cast to float32 for GPU/CPU inference.
Inference and Decision Logic
The ailia.Net instance executes forward propagation, producing raw logits. The util/math_utils.py softmax implementation converts these to probabilities across two classes: index 0 (real) and index 1 (spoof). The default --spoof_thresh of 0.4 determines the classification boundary; faces scoring above the threshold as "real" are considered live.
Running the Liveness Detection Pipeline
Single Image Analysis
Execute the script against a static image to evaluate liveness without real-time overhead:
python face_recognition/face-anti-spoofing/face-anti-spoofing.py \
-i path/to/image.jpg \
--detection
The --detection flag enables Blazeface to locate faces automatically. Output includes confidence scores such as face is real: 97.432%.
Real-Time Webcam Detection
For production kiosks or access control systems, process live video streams:
python face_recognition/face-anti-spoofing/face-anti-spoofing.py \
-v 0 \
--detection
The -v 0 parameter selects the default webcam. The recognize_from_video() function handles frame capture, face cropping via crop_blazeface(), and visualization through draw_detections(), which renders green bounding boxes for live faces and red for spoofs.
Batch Processing Multiple Images
Process directories of enrollment photos or audit trails programmatically:
import glob, cv2, ailia
from face_recognition.face-anti-spoofing.face-anti-spoofing import predict
net = ailia.Net('MN3_large.onnx.prototxt', 'MN3_large.onnx')
for img_path in glob.glob("samples/*.jpg"):
img = cv2.imread(img_path)
prob = predict(net, img)[0]
status = 'real' if prob[0] > prob[1] else 'spoof'
print(f"{img_path}: {status} ({prob.max()*100:.2f}%)")
Integrating Face Anti-Spoofing into Python Applications
Embed the liveness detection logic within larger biometric systems by importing the core functions directly:
import cv2, ailia, numpy as np
from face_recognition.face-anti-spoofing.face-anti-spoofing import (
preprocess, predict
)
# Initialize model
net = ailia.Net('MN3_large.onnx.prototxt', 'MN3_large.onnx')
def is_live(face_img, threshold=0.4):
"""Determine if a cropped face is live based on anti-spoofing score."""
probs = predict(net, face_img)[0]
real_score = probs[0]
return real_score >= (1 - threshold)
# Real-time integration example
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
# Assume face_bbox obtained from external detector
x, y, w, h = face_bbox
face_crop = frame[y:y+h, x:x+w]
live = is_live(face_crop)
label = "Live" if live else "Spoof"
color = (0, 255, 0) if live else (0, 0, 255)
cv2.rectangle(frame, (x, y), (x+w, y+h), color, 2)
cv2.putText(frame, label, (x, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2)
cv2.imshow("Liveness Detection", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Source Code Structure and Key Files
The implementation spans multiple utility modules and the main inference script:
face_recognition/face-anti-spoofing/face-anti-spoofing.py– Main entry point containingpreprocess(),predict(),recognize_from_image(), andrecognize_from_video().util/model_utils.py– Handles automatic download ofMN3_large.onnxandblazefaceback.onnxfrom the Ailia model bucket.util/math_utils.py– Provides the softmax function for converting model logits to probabilities.util/detector_utils.py– Containsload_image()for input handling.face_detection/blazeface/blazeface_utils.py– Implementscompute_blazeface()andcrop_blazeface()for face localization when--detectionis enabled.
Summary
- The face anti-spoofing liveness detection pipeline in
axinc-ai/ailia-modelsuses a MobileNetV3 (MN3_large.onnx) architecture optimized for 128×128 input resolution. - Pre-processing includes BGR-to-RGB conversion, resizing, per-channel normalization, and CHW transposition before
float32inference. - The system supports optional Blazeface integration (
--detectionflag) for automatic face cropping, or direct inference on pre-cropped images. - Classification relies on softmax probabilities with a configurable threshold (
--spoof_thresh, default 0.4) to distinguish real faces from presentation attacks. - The modular design allows easy integration into existing biometric systems via the
preprocess()andpredict()functions.
Frequently Asked Questions
What model architecture does the face anti-spoofing system use?
The implementation utilizes MobileNetV3 Large (MN3_large.onnx), a lightweight convolutional neural network optimized for mobile and edge devices. This architecture balances inference speed and accuracy, processing 128×128 pixel face crops to output binary classification logits for real versus spoof detection.
How does the liveness detection threshold work?
The --spoof_thresh parameter (default 0.4) controls the decision boundary for classification. After applying softmax to the model outputs, the system compares the "real" probability (index 0) against the threshold. If the real score meets or exceeds 1 - spoof_thresh, the face is classified as live; otherwise, it is flagged as a presentation attack or spoof attempt.
Can I use this without a face detector for pre-cropped images?
Yes. The --detection flag is optional. If omitted, the script assumes the input image contains a single face already cropped to the expected 128×128 dimensions. This mode is ideal for processing enrollment photos or images from external detection pipelines where face localization has already been performed.
What preprocessing steps are required before inference?
The preprocess() function in face-anti-spoofing.py performs four critical transformations: color space conversion (BGR to RGB), spatial resizing to 128×128 pixels, per-channel normalization using dataset-specific mean and standard deviation values, and tensor transposition from HWC to CHW format followed by batch dimension addition and float32 casting. These steps ensure input compatibility with the MobileNetV3 model.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →