forensicface

from forensicface.app import ForensicFace
import matplotlib.pyplot as plt

A Python package for forensic face examination

Installation

Python >= 3.13 is required.

An Nvidia GPU with CUDA properly configured is recommended, but not required. It is automatically detected and used if available.

Installing forensicface on a dedicated Python virtual environment is highly recommended.

It works on Windows and Linux. It should work on MacOS, but it has naver been tested.

You can install forensicface via pip:

pip install forensicface

After installing forensicface, you’ll need to manually put the model files in the folder ~/.forensicface/models/<model_name>
If you don’t have these files, send an e-mail to rafael.ror <at> pf.gov.br

Basic usage

from forensicface.app import ForensicFace

ff = ForensicFace()
[ForensicFace] Initialized with configuration:
                  loaded_models=['sepaelv2']
                  modules=['detection', 'headpose', 'genderage', 'cr_fiqa']
                  det_size=(320, 320)
                  session_providers=all models use CUDAExecutionProvider

Processing an image file with a single face. forensicface returns a dictionary with the following keys:
- ‘ipd’ - interpuppilary distance - ‘fiqa_score’ - a facial image quality score - ‘gender’ - estimated sex, either M or F - ‘age’ - estimated age, in years - ‘yaw’, ‘pitch’ and ‘roll’ - estimated head pose angles - ‘det_score’ - face detection score - ‘keypoints’ - x and y coordinates of the eyes, tip of the nose and corners of the mouth. - ‘bbox’ - bounding box of the face - ‘embedding’ - vector representation of the face - ‘aligned_face’ - RGB image of the aligned face, with 112 x 112 pixels. This is the input to the model that extracts the embedding.

results = ff.process_image("obama2.png")
results.keys()
FutureWarning: process_image: The return of this function when 'single_face = True' will change in a future release.
Instead of returning a dict, it will return a list (with one dict). 
dict_keys(['ipd', 'fiqa_score', 'gender', 'age', 'yaw', 'pitch', 'roll', 'det_score', 'keypoints', 'bbox', 'embedding', 'aligned_face'])
results.get("gender"), results.get("age"), results.get("yaw")
('M', 60, np.float32(-37.767048))

It’s possible to have the keypoints drawn on the aligned face. This is useful to check if the face detection and alignment were correct.

aligned_img_with_kps = ff.process_image("obama2.png", draw_keypoints=True).get(
    "aligned_face"
)
plt.imshow(aligned_img_with_kps)
FutureWarning: process_image: The return of this function when 'single_face = True' will change in a future release.
Instead of returning a dict, it will return a list (with one dict). 

Processing an image file with multiple faces. forensicface returns a list of dictionaries, with the same keys as in the single face case.

Processamento básico de imagens

Obter pontos de referência, distância interpupilar, representação vetorial, a face alinhada com dimensão fixa (112x112), estimativas de sexo, idade, pose (pitch, yaw, roll) e qualidade. Opcionalmente, é possível anotar a face alinhada com os pontos de referência utilizados no alinhamento (parâmetro draw_kypoints).

results = ff.process_image_single_face("obama2.png", draw_keypoints=True)
results.keys()
dict_keys(['ipd', 'fiqa_score', 'gender', 'age', 'yaw', 'pitch', 'roll', 'det_score', 'keypoints', 'bbox', 'embedding', 'aligned_face'])
plt.imshow(results["aligned_face"])

Comparar duas imagens faciais e obter o escore de similaridade.

ff.compare("obama.png", "obama2.png")
np.float32(0.85561067)

Agregar embeddings de duas imagens faciais em uma única representação, com ponderação por qualidade

agg = ff.aggregate_from_images(["obama.png", "obama2.png"], quality_weight=True)
agg.shape
(512,)

Estimativa de qualidade CR-FIQA

Estimativa de qualidade pelo método CR-FIQA

Para desabilitar, instancie o forensicface com a opção extended = False:

ff = ForensicFace(extended=False)

Obs.: a opção extended = False também desabilita as estimativas de sexo, idade e pose.

good = ff.process_image("001_frontal.jpg")
bad = ff.process_image("001_cam1_1.jpg")
good["fiqa_score"], bad["fiqa_score"]
(np.float32(2.3785863), np.float32(1.4386019))

Crédito dos modelos utilizados

  • Detecção, gênero (M/F), idade e pose (pitch, yaw, roll): insightface

  • Reconhecimento: adaface

  • Estimativa de qualidade: CR-FIQA