Skip to main content

Pure Python OpenFace 2.2 AU extraction with CLNF landmark refinement

Project description

pyfaceau - Action Unit Generation based on Python and Openface 2.2

Python 3.10+ License: CC BY-NC 4.0


Overview

pyfaceau is a Python reimplementation of the OpenFace 2.2 Facial Action Unit extraction pipeline. It achieves r =92 correlation with the original C++ implementation while requiring zero compilation and running on any platform.

Key Features

  • ** 100% Python** - No C++ compilation required
  • ** Easy Installation** - pip install and go
  • ** High Accuracy** - r=0.92 overall
  • ** High Performance** - 50-100 FPS with parallel processing (6-10x speedup!)
  • ** Multi-Core Support** - Automatic parallelization across CPU cores
  • ** Modular** - Use individual components independently
  • ** 17 Action Units** - Full AU extraction (AU01, AU02, AU04, etc.)

Quick Start

Installation

Option 1: Install from PyPI (Recommended)

# Install pyfaceau
pip install pyfaceau

# Download model weights (14MB)
python -m pyfaceau.download_weights

# Or manually download from GitHub
# https://github.com/johnwilsoniv/face-analysis/tree/main/S0%20PyfaceAU/weights

Option 2: Install from Source

# Clone repository
git clone https://github.com/johnwilsoniv/face-analysis.git
cd "face-analysis/S0 PyfaceAU"

# Install in development mode
pip install -e .

# Model weights are included in the repository

Basic Usage

High-Performance Mode (Recommended - 50-100 FPS)

from pyfaceau import ParallelAUPipeline

# Initialize parallel pipeline 
pipeline = ParallelAUPipeline(
    retinaface_model='weights/retinaface_mobilenet025_coreml.onnx',
    pfld_model='weights/pfld_cunjian.onnx',
    pdm_file='weights/In-the-wild_aligned_PDM_68.txt',
    au_models_dir='path/to/AU_predictors',
    triangulation_file='weights/tris_68_full.txt',
    num_workers=6,  # Adjust based on CPU cores
    batch_size=30
)

# Process video
results = pipeline.process_video(
    video_path='input.mp4',
    output_csv='results.csv'
)

print(f"Processed {len(results)} frames")
# Typical output: ~28-50 FPS depending on CPU cores

Standard Mode (4.6 FPS)

from pyfaceau import FullPythonAUPipeline

# Initialize standard pipeline
pipeline = FullPythonAUPipeline(
    retinaface_model='weights/retinaface_mobilenet025_coreml.onnx',
    pfld_model='weights/pfld_cunjian.onnx',
    pdm_file='weights/In-the-wild_aligned_PDM_68.txt',
    au_models_dir='path/to/AU_predictors',
    triangulation_file='weights/tris_68_full.txt',
    use_calc_params=True,
    use_coreml=True,  # macOS only
    verbose=False
)

# Process video
results = pipeline.process_video(
    video_path='input.mp4',
    output_csv='results.csv'
)

Example Output

frame,success,AU01_r,AU02_r,AU04_r,AU06_r,AU12_r,...
0,True,0.60,0.90,0.00,1.23,2.45,...
1,True,0.55,0.85,0.00,1.20,2.50,...

Architecture

pyfaceau replicates the complete OpenFace 2.2 AU extraction pipeline:

Video Input
    ↓
Face Detection (RetinaFace ONNX)
    ↓
Landmark Detection (PFLD 68-point)
    ↓
3D Pose Estimation (Python Implementation of CalcParams with 98% fidelity)
    ↓
Face Alignment
    ↓
HOG Feature Extraction (PyFHOG)
    ↓
Geometric Features (PDM reconstruction)
    ↓
Running Median Tracking (Cython-optimized)
    ↓
AU Prediction (17 SVR models)
    ↓
Output: 17 AU intensities

Custom Components & Innovations

pyfaceau includes several novel components that can be used independently in other projects:

Python-based CalcParams - 3D Pose Estimation

A pure Python implementation of OpenFace's CalcParams algorithm for 3D head pose estimation. Achieves 99.45% correlation with the C++ reference implementation.

from pyfaceau.alignment import CalcParams

# Initialize with PDM model
calc_params = CalcParams(pdm_file='weights/In-the-wild_aligned_PDM_68.txt')

# Estimate 3D pose from 2D landmarks
params_local, params_global, detected_landmarks = calc_params.estimate_pose(
    landmarks_2d,  # 68x2 array of detected landmarks
    img_width,
    img_height
)

# Extract pose parameters
tx, ty = params_global[4], params_global[5]  # Translation
rx, ry, rz = params_global[1:4]  # Rotation (radians)
scale = params_global[0]  # Scale factor

Use cases: Head pose tracking, gaze estimation, facial alignment

CLNF Landmark Refinement

Constrained Local Neural Fields (CLNF) refinement using SVR patch experts for improved landmark accuracy. Particularly effective for challenging poses and expressions.

from pyfaceau.detectors import CLNFRefiner

# Initialize refiner
refiner = CLNFRefiner(
    pdm_file='weights/In-the-wild_aligned_PDM_68.txt',
    patch_expert_file='weights/svr_patches_0.25_general.txt'
)

# Refine landmarks
refined_landmarks = refiner.refine_landmarks(
    frame,
    initial_landmarks,
    face_bbox,
    num_iterations=5
)

Use cases: Landmark tracking, facial feature extraction, expression analysis

Cython Histogram Median Tracker (260x speedup)

High-performance running median tracking for temporal smoothing of geometric features. Implements OpenFace's histogram-based median algorithm in optimized Cython.

from pyfaceau.features import HistogramMedianTracker

# Initialize tracker
tracker = HistogramMedianTracker(
    num_features=136,  # 68 landmarks x 2 (x,y)
    history_length=120
)

# Update with new frame
smoothed_features = tracker.update(current_features)

Use cases: Temporal smoothing, noise reduction, video feature tracking

Batched AU Predictor

Optimized AU prediction using batch processing for HOG features. Reduces overhead when processing multiple frames.

from pyfaceau.prediction import BatchedAUPredictor

# Initialize predictor
predictor = BatchedAUPredictor(
    au_models_dir='weights/AU_predictors',
    batch_size=30
)

# Predict AUs for multiple frames
au_results = predictor.predict_batch(
    hog_features_list,  # List of HOG feature arrays
    geom_features_list  # List of geometric feature arrays
)

Use cases: Video processing, batch AU extraction, real-time analysis

OpenFace22 Face Aligner

Pure Python implementation of OpenFace 2.2's face alignment algorithm. Produces pixel-perfect aligned faces matching the C++ implementation.

from pyfaceau.alignment import OpenFace22FaceAligner

# Initialize aligner
aligner = OpenFace22FaceAligner(
    pdm_file='weights/In-the-wild_aligned_PDM_68.txt',
    triangulation_file='weights/tris_68_full.txt'
)

# Align face for AU extraction
aligned_face = aligner.align_face(
    frame,
    landmarks_2d,
    tx, ty, rz  # From CalcParams
)

Output: 112x112 RGB aligned face, ready for HOG extraction

Use cases: Face normalization, AU extraction preprocessing, facial feature analysis


Supported Action Units

pyfaceau extracts 17 Facial Action Units:

Dynamic AUs (11):

  • AU01 - Inner Brow Raiser
  • AU02 - Outer Brow Raiser
  • AU05 - Upper Lid Raiser
  • AU09 - Nose Wrinkler
  • AU15 - Lip Corner Depressor
  • AU17 - Chin Raiser
  • AU20 - Lip Stretcher
  • AU23 - Lip Tightener
  • AU25 - Lips Part
  • AU26 - Jaw Drop
  • AU45 - Blink

Static AUs (6):

  • AU04 - Brow Lowerer
  • AU06 - Cheek Raiser
  • AU07 - Lid Tightener
  • AU10 - Upper Lip Raiser
  • AU12 - Lip Corner Puller
  • AU14 - Dimpler

Requirements

Python Dependencies

python >= 3.10
numpy >= 1.20.0
opencv-python >= 4.5.0
pandas >= 1.3.0
scipy >= 1.7.0
onnxruntime >= 1.10.0
pyfhog >= 0.1.0

Model Files

Download OpenFace 2.2 AU predictor models:

  • Available from: OpenFace repository
  • Place in: AU_predictors/ directory
  • Required: 17 .dat files (AU_1_dynamic_intensity_comb.dat, etc.)

Project Structure

S0 pyfaceau/
├── pyfaceau/                  # Core library
│   ├── pipeline.py            # Full AU extraction pipeline
│   ├── detectors/             # Face and landmark detection
│   ├── alignment/             # Face alignment and pose estimation
│   ├── features/              # HOG and geometric features
│   ├── prediction/            # AU prediction and running median
│   └── utils/                 # Utilities and Cython extensions
├── weights/                   # Model weights
├── tests/                     # Test suite
├── examples/                  # Usage examples
└── docs/                      # Documentation

Advanced Usage

Process Single Frame

from pyfaceau import FullPythonAUPipeline
import cv2

pipeline = FullPythonAUPipeline(...)

# Read frame
frame = cv2.imread('image.jpg')

# Process (requires landmarks and pose from CSV or detector)
aligned = pipeline.aligner.align_face(frame, landmarks, tx, ty, rz)
hog_features = pipeline.extract_hog(aligned)
aus = pipeline.predict_aus(hog_features, geom_features)

Use Individual Components

# Face detection only
from pyfaceau.detectors import ONNXRetinaFaceDetector
detector = ONNXRetinaFaceDetector('weights/retinaface_mobilenet025_coreml.onnx')
faces = detector.detect_faces(frame)

# Landmark detection only
from pyfaceau.detectors import CunjianPFLDDetector
landmarker = CunjianPFLDDetector('weights/pfld_cunjian.onnx')
landmarks, conf = landmarker.detect_landmarks(frame, bbox)

# Face alignment only
from pyfaceau.alignment import OpenFace22FaceAligner
aligner = OpenFace22FaceAligner('weights/In-the-wild_aligned_PDM_68.txt')
aligned = aligner.align_face(frame, landmarks, tx, ty, rz)

Citation

If you use pyfaceau in your research, please cite:

@article{wilson2025splitface,
  title={A Split-Face Computer Vision/Machine Learning Assessment of Facial Paralysis Using Facial Action Units},
  author={Wilson IV, John and Rosenberg, Joshua and Gray, Mingyang L and Razavi, Christopher R},
  journal={Facial Plastic Surgery \& Aesthetic Medicine},
  year={2025},
  publisher={Mary Ann Liebert, Inc.}
}

Also cite the original OpenFace:

@inproceedings{baltrusaitis2018openface,
  title={OpenFace 2.0: Facial behavior analysis toolkit},
  author={Baltru{\v{s}}aitis, Tadas and Zadeh, Amir and Lim, Yao Chong and Morency, Louis-Philippe},
  booktitle={2018 13th IEEE International Conference on Automatic Face \& Gesture Recognition (FG 2018)},
  pages={59--66},
  year={2018},
  organization={IEEE}
}

Acknowledgments

  • OpenFace - Original C++ implementation by Tadas Baltrusaitis
  • PyFHOG - HOG feature extraction library
  • RetinaFace - Face detection model
  • PFLD - Landmark detection by Cunjian Chen

Support


Built for the facial behavior research community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyfaceau-1.0.3.tar.gz (418.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pyfaceau-1.0.3-cp313-cp313-win_amd64.whl (592.1 kB view details)

Uploaded CPython 3.13Windows x86-64

pyfaceau-1.0.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pyfaceau-1.0.3-cp312-cp312-win_amd64.whl (592.6 kB view details)

Uploaded CPython 3.12Windows x86-64

pyfaceau-1.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pyfaceau-1.0.3-cp311-cp311-win_amd64.whl (592.1 kB view details)

Uploaded CPython 3.11Windows x86-64

pyfaceau-1.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pyfaceau-1.0.3-cp310-cp310-win_amd64.whl (592.5 kB view details)

Uploaded CPython 3.10Windows x86-64

pyfaceau-1.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

File details

Details for the file pyfaceau-1.0.3.tar.gz.

File metadata

  • Download URL: pyfaceau-1.0.3.tar.gz
  • Upload date:
  • Size: 418.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyfaceau-1.0.3.tar.gz
Algorithm Hash digest
SHA256 f3d25808021bcbd29812f962066dd77c19496d49b148ba3db4abd12383e430c0
MD5 0d8843717b38909be997c6b318373742
BLAKE2b-256 89efcced87b6d646fcf9d68925d063e0d42abe06de8197ca74bda7f188e12a82

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyfaceau-1.0.3.tar.gz:

Publisher: build-wheels.yml on johnwilsoniv/pyfaceau

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyfaceau-1.0.3-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: pyfaceau-1.0.3-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 592.1 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyfaceau-1.0.3-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 8204d1383f8f8a8d407f30194527a71a1738070f35238a52ac33414cc0d11ec5
MD5 8b8f5ac210d90d7ed1aedcb2a44959a8
BLAKE2b-256 8a66ec8ac4d7544cdc85f769cdf120be143b6ad9351259d00d5b16c085c736ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyfaceau-1.0.3-cp313-cp313-win_amd64.whl:

Publisher: build-wheels.yml on johnwilsoniv/pyfaceau

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyfaceau-1.0.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyfaceau-1.0.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f1c28d47fbf95e98c514a37cd089442fb524db3479c5149b6c47fe2b83d64b84
MD5 76e46f0e337604978d480269372e2ea3
BLAKE2b-256 1ee8b271b4951f34e2130fa6bfc0f7f22360b5fbd3063ce8e495e03398c1e39c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyfaceau-1.0.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build-wheels.yml on johnwilsoniv/pyfaceau

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyfaceau-1.0.3-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: pyfaceau-1.0.3-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 592.6 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyfaceau-1.0.3-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 1c08740e577bc7283fd98fa989c1c31d93d2d4ee1d1db014aeaa0cf09a8110e4
MD5 571586cf9c9c6e135389700f45656282
BLAKE2b-256 929d44745566d2a08f66c7bcc3dd74622e1a0fb6f7fd47be10a70366e710df1b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyfaceau-1.0.3-cp312-cp312-win_amd64.whl:

Publisher: build-wheels.yml on johnwilsoniv/pyfaceau

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyfaceau-1.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyfaceau-1.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7454b304bc12270b0e4a1eea43269224421e0336b59e29cd311ec62d3fe59cb4
MD5 0beaeda391377e4cff664cd73ccd36b7
BLAKE2b-256 5af778319b8c1c28b1351532b564ecb9815e59c1d1eca5605c2c3441eb2a017f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyfaceau-1.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build-wheels.yml on johnwilsoniv/pyfaceau

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyfaceau-1.0.3-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: pyfaceau-1.0.3-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 592.1 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyfaceau-1.0.3-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 22b1918c94eca3aaecc66098098d894facc907b48e0ffead0fd744d966b393a6
MD5 e7285ae27c97c96a426750dc6d606c7a
BLAKE2b-256 b086bb618f8830b1e5b4dfbe464b75408554cd525df6500e3442df03e0ee9e46

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyfaceau-1.0.3-cp311-cp311-win_amd64.whl:

Publisher: build-wheels.yml on johnwilsoniv/pyfaceau

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyfaceau-1.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyfaceau-1.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4eac8195948716e62ebd7985dd25da832fbf6d72425a84af1dbe9732e3deda75
MD5 6f7af57133cd0926df6794ec05309e17
BLAKE2b-256 4297aef040578d5ce0354f7f225014c72aa8a9be50a3ca4bbf5702280a8c19f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyfaceau-1.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build-wheels.yml on johnwilsoniv/pyfaceau

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyfaceau-1.0.3-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: pyfaceau-1.0.3-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 592.5 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyfaceau-1.0.3-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 e42b6167a2b13b8b5554153272651e9bee804904ae52c3ebd40bd24ec9a15902
MD5 eea48827e292998620e656cceaed4d41
BLAKE2b-256 0aab0abc859cc16afea7a5e731bffd48fc6c6e60aed09daddbeae5881d965094

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyfaceau-1.0.3-cp310-cp310-win_amd64.whl:

Publisher: build-wheels.yml on johnwilsoniv/pyfaceau

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyfaceau-1.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyfaceau-1.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fdcd8220ec219df51a76efc15d4e74cd3d430a272c92cd333ae69aef7f9d62a5
MD5 e1733b992e715b02c38f819664e697f5
BLAKE2b-256 09804b9f129e965f8ce54d8ba258591247ec0a95f9a58848cd84573f0fd8fead

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyfaceau-1.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build-wheels.yml on johnwilsoniv/pyfaceau

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page