PIPNet: Pixel-in-Pixel Net for Facial Landmark Detection

May 5, 2026 · View on GitHub

Downloads License: MIT

Tip

The models and functionality in this repository are integrated into UniFace — an all-in-one face analysis toolkit.<br> PyPI Version GitHub Stars License

ONNX Runtime inference for PIPNet facial landmark detection. Uses UniFace for face detection.

Original Result
man — original man — landmarks
portrait — original portrait — landmarks

98-point landmarks predicted by pipnet_r18_wflw_98.onnx (face boxes from SCRFD).

Models

PyTorch checkpoints and the ONNX exports built from them. Download via bash download.sh or from Releases.

ModelDatasetLandmarksInputBackbonePyTorchONNX
PIPNet R18 WFLW-98WFLW (supervised)98256×256ResNet-18pthonnx
PIPNet R18 300W+CelebA-68 (GSSL)300W+CelebA (semi-supervised)68256×256ResNet-18pthonnx

Both variants share the same architecture and produce 5 output tensors (cls_map, offset_x, offset_y, nb_x, nb_y). The PIPNet class auto-selects the 68-point or 98-point mean-face table from the ONNX output channel count.

Installation

pip install -r requirements.txt
bash download.sh  # Download model weights

Usage

CLI

python main.py assets/samples/face.jpg --weights weights/pipnet_r18_wflw_98.onnx

Python API

import cv2
from model import PIPNet
from uniface.detection import SCRFD

detector = SCRFD()
landmarker = PIPNet('weights/pipnet_r18_wflw_98.onnx')

image = cv2.imread('face.jpg')
faces = detector.detect(image)
landmarks = landmarker.get_landmarks(image, faces[0].bbox)  # (98, 2) float32

get_landmarks(image, bbox) returns landmarks in original-image pixel coordinates. The class handles the asymmetric 1.2× bbox crop, ImageNet normalization, and the pixel-in-pixel neighbor-averaging decoding step internally.

Exporting Your Own Weights

onnx_export.py converts a .pth checkpoint to ONNX. Install the extra deps first:

pip install -r requirements-export.txt

Then run against one of the .pth files from Models (or any compatible PIPNet checkpoint):

# WFLW (supervised, 98 points):
python onnx_export.py \
    --weights weights/pipnet_r18_wflw_98.pth \
    --num-lms 98 \
    --output weights/pipnet_r18_wflw_98.onnx

# 300W+CelebA (GSSL, 68 points):
python onnx_export.py \
    --weights weights/pipnet_r18_300w_celeba_68.pth \
    --num-lms 68 \
    --output weights/pipnet_r18_300w_celeba_68.onnx

Reference

  • PIPNet — Original PyTorch implementation.
  • UniFace — Face detection and all-in-one analysis toolkit.

License

MIT License