Skip to content

Anti-Spoofing

Face anti-spoofing detects whether a face is real (live) or fake (photo, video replay, mask).


Available Models

Model Size
MiniFASNet V1SE 1.2 MB
MiniFASNet V2 1.2 MB

Basic Usage

import cv2
from uniface import RetinaFace
from uniface.spoofing import MiniFASNet

detector = RetinaFace()
spoofer = MiniFASNet()

image = cv2.imread("photo.jpg")
faces = detector.detect(image)

for face in faces:
    result = spoofer.predict(image, face.bbox)

    label = "Real" if result.is_real else "Fake"
    print(f"{label}: {result.confidence:.1%}")

Output Format

result = spoofer.predict(image, face.bbox)

# SpoofingResult dataclass
result.is_real     # True = real, False = fake
result.confidence  # 0.0 to 1.0

Model Variants

from uniface.spoofing import MiniFASNet
from uniface.constants import MiniFASNetWeights

# Default (V2, recommended)
spoofer = MiniFASNet()

# V1SE variant
spoofer = MiniFASNet(model_name=MiniFASNetWeights.V1SE)
Variant Size Scale Factor
V1SE 1.2 MB 4.0
V2 1.2 MB 2.7

Confidence Thresholds

The default threshold is 0.5. Adjust for your use case:

result = spoofer.predict(image, face.bbox)

# High security (fewer false accepts)
HIGH_THRESHOLD = 0.7
if result.confidence > HIGH_THRESHOLD:
    print("Real (high confidence)")
else:
    print("Suspicious")

# Balanced
if result.is_real:  # Uses default 0.5 threshold
    print("Real")
else:
    print("Fake")

Visualization

import cv2

def draw_spoofing_result(image, face, result):
    """Draw spoofing result on image."""
    x1, y1, x2, y2 = map(int, face.bbox)

    # Color based on result
    color = (0, 255, 0) if result.is_real else (0, 0, 255)
    label = "Real" if result.is_real else "Fake"

    # Draw bounding box
    cv2.rectangle(image, (x1, y1), (x2, y2), color, 2)

    # Draw label
    text = f"{label}: {result.confidence:.1%}"
    cv2.putText(image, text, (x1, y1 - 10),
                cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)

    return image

# Usage
for face in faces:
    result = spoofer.predict(image, face.bbox)
    image = draw_spoofing_result(image, face, result)

cv2.imwrite("spoofing_result.jpg", image)

Real-Time Liveness Detection

import cv2
from uniface import RetinaFace
from uniface.spoofing import MiniFASNet

detector = RetinaFace()
spoofer = MiniFASNet()

cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    faces = detector.detect(frame)

    for face in faces:
        result = spoofer.predict(frame, face.bbox)

        # Draw result
        x1, y1, x2, y2 = map(int, face.bbox)
        color = (0, 255, 0) if result.is_real else (0, 0, 255)
        label = f"{'Real' if result.is_real else 'Fake'}: {result.confidence:.0%}"

        cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2)
        cv2.putText(frame, label, (x1, y1 - 10),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)

    cv2.imshow("Liveness Detection", frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

Use Cases

Access Control

def verify_liveness(image, face, spoofer, threshold=0.6):
    """Verify face is real for access control."""
    result = spoofer.predict(image, face.bbox)

    if result.is_real and result.confidence > threshold:
        return True, result.confidence
    return False, result.confidence

# Usage
is_live, confidence = verify_liveness(image, face, spoofer)
if is_live:
    print(f"Access granted (confidence: {confidence:.1%})")
else:
    print(f"Access denied - possible spoof attempt")

Multi-Frame Verification

For higher security, verify across multiple frames:

def verify_liveness_multiframe(frames, detector, spoofer, min_real=3):
    """Verify liveness across multiple frames."""
    real_count = 0

    for frame in frames:
        faces = detector.detect(frame)
        if not faces:
            continue

        result = spoofer.predict(frame, faces[0].bbox)
        if result.is_real:
            real_count += 1

    return real_count >= min_real

# Collect frames and verify
frames = []
for _ in range(5):
    ret, frame = cap.read()
    if ret:
        frames.append(frame)

is_verified = verify_liveness_multiframe(frames, detector, spoofer)

Attack Types Detected

MiniFASNet can detect various spoof attacks:

Attack Type Detection
Printed photos
Screen replay
Video replay
Paper masks
3D masks Limited

Limitations

  • High-quality 3D masks may not be detected
  • Performance varies with lighting and image quality
  • Always combine with other verification methods for high-security applications

Command-Line Tool

# Image
python tools/spoofing.py --source photo.jpg

# Webcam
python tools/spoofing.py --source 0

Factory Function

from uniface import create_spoofer

spoofer = create_spoofer()  # Returns MiniFASNet

Next Steps