# How to Use Face Anti-Spoofing for Liveness Detection with Ailia Models

> Implement face anti-spoofing liveness detection using a lightweight MN3 Large neural network. Detect real or spoof faces in real-time with Ailia models.

- Repository: [axinc-ai/ailia-models](https://github.com/axinc-ai/ailia-models)
- Tags: how-to-guide
- Published: 2026-02-26

---

**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`](https://github.com/axinc-ai/ailia-models/blob/main/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`](https://github.com/axinc-ai/ailia-models/blob/main/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`](https://github.com/axinc-ai/ailia-models/blob/main/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`](https://github.com/axinc-ai/ailia-models/blob/main/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:

```bash
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:

```bash
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:

```python
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:

```python
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`](https://github.com/axinc-ai/ailia-models/blob/main/face_recognition/face-anti-spoofing/face-anti-spoofing.py) – Main entry point containing `preprocess()`, `predict()`, `recognize_from_image()`, and `recognize_from_video()`.
- [`util/model_utils.py`](https://github.com/axinc-ai/ailia-models/blob/main/util/model_utils.py) – Handles automatic download of `MN3_large.onnx` and `blazefaceback.onnx` from the Ailia model bucket.
- [`util/math_utils.py`](https://github.com/axinc-ai/ailia-models/blob/main/util/math_utils.py) – Provides the softmax function for converting model logits to probabilities.
- [`util/detector_utils.py`](https://github.com/axinc-ai/ailia-models/blob/main/util/detector_utils.py) – Contains `load_image()` for input handling.
- [`face_detection/blazeface/blazeface_utils.py`](https://github.com/axinc-ai/ailia-models/blob/main/face_detection/blazeface/blazeface_utils.py) – Implements `compute_blazeface()` and `crop_blazeface()` for face localization when `--detection` is enabled.

## Summary

- The **face anti-spoofing liveness detection** pipeline in `axinc-ai/ailia-models` uses 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 `float32` inference.
- The system supports **optional Blazeface integration** (`--detection` flag) 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()` and `predict()` 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`](https://github.com/axinc-ai/ailia-models/blob/main/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.