app

app

Classes

Name Description
ForensicFace Class for processing facial images to extract useful features for forensic analysis.

ForensicFace

app.ForensicFace(
    models=['sepaelv2'],
    model=None,
    det_size=320,
    use_gpu=True,
    gpu=0,
    concat_embeddings=True,
    extended=True,
    det_thresh=0.5,
    backend_name='onnx',
    backend=None,
    models_root=osp.join(osp.expanduser('~'), '.forensicface', 'models'),
)

Class for processing facial images to extract useful features for forensic analysis.

Methods

Name Description
aggregate_embeddings Aggregates multiple embeddings into a single embedding.
aggregate_from_images Given a list of image paths, this method returns the average embedding of all faces found in the images.
build_mosaic Detect, align, and build a rectangular mosaic from original images.
build_mosaic_from_aligned_faces Build a rectangular mosaic from already aligned RGB face images.
compare Compute the similarity cosine between the embeddings of two face images.
detect_and_align Detect faces and return aligned crops without embedding/FIQA.
extract_faces Extracts faces from a video and saves them as individual images.
process_aligned_face_image Process an already aligned RGB face image.
process_aligned_faces_batch Process already aligned RGB face images in one recognition batch.
process_image Process an image assuming one or multiple faces.
process_image_multiple_faces Process an image assuming multiple faces.
process_image_single_face Process a an image considering it has a single face and extract useful features for forensic analysis.
process_images_batch Batched counterpart of process_image.
aggregate_embeddings
app.ForensicFace.aggregate_embeddings(embeddings, weights=None, method='mean')

Aggregates multiple embeddings into a single embedding.

Parameters
embeddings : np.ndarray

A 2D array of shape (num_embeddings, embedding_dim) containing the embeddings to be aggregated.

weights : np.ndarray | None = None

A 1D array of shape (num_embeddings,) containing the weights to be assigned to each embedding. If not provided, all embeddings are equally weighted.

method : str = 'mean'

choice of agregating based on the mean or median of the embeddings. Possible values are ‘mean’ and ‘median’.

Returns
: np.ndarray

np.ndarray: A 1D array of shape (embedding_dim,) containing the aggregated embedding.

aggregate_from_images
app.ForensicFace.aggregate_from_images(
    list_of_image_paths,
    method='mean',
    quality_weight=False,
)

Given a list of image paths, this method returns the average embedding of all faces found in the images.

Parameters
list_of_image_paths : list[str]

List of paths to images.

method : str = 'mean'

choice of agregating based on the mean or median of the embeddings. Possible values are ‘mean’ and ‘median’.

quality_weight : bool = False

If True, use the FIQA(L) score as a weight for aggregation.

Returns
: np.ndarray | dict[str, np.ndarray] | list

np.ndarray | dict[str, np.ndarray] | list: If one or more faces

: np.ndarray | dict[str, np.ndarray] | list

are found and concat_embeddings=True, returns a 1D numpy array

: np.ndarray | dict[str, np.ndarray] | list

representing the average embedding. If concat_embeddings=False,

: np.ndarray | dict[str, np.ndarray] | list

returns a dictionary with one aggregated embedding per model using

: np.ndarray | dict[str, np.ndarray] | list

keys in the form embedding_<model_name>. If no faces are found,

: np.ndarray | dict[str, np.ndarray] | list

returns an empty list.

build_mosaic
app.ForensicFace.build_mosaic(
    img_path_list,
    mosaic_shape,
    border=0.03,
    save_to=None,
    draw_keypoints=False,
    keypoint_colors=DEFAULT_KEYPOINT_COLORS,
)

Detect, align, and build a rectangular mosaic from original images.

Parameters
img_path_list : list[str | np.ndarray]

list of paths to image files or list of bgr_images

mosaic_shape : tuple[int, int]

tuple of integers, (n_cols, n_rows)

border : float = 0.03

float, percent of image to use as white border

save_to : str | None = None

optional path used to save the mosaic image.

draw_keypoints : bool = False

if True, draw keypoints on each aligned face.

keypoint_colors : tuple[str, str, str, str, str] = DEFAULT_KEYPOINT_COLORS

colors used for the five aligned keypoints when draw_keypoints=True.

Returns
: np.ndarray

np.ndarray: OpenCV BGR image with mosaic.

build_mosaic_from_aligned_faces
app.ForensicFace.build_mosaic_from_aligned_faces(
    aligned_faces,
    mosaic_shape,
    border=0.03,
    save_to=None,
    draw_keypoints=False,
    keypoints=None,
    keypoint_colors=DEFAULT_KEYPOINT_COLORS,
)

Build a rectangular mosaic from already aligned RGB face images.

This is a convenience wrapper around forensicface.mosaic.build_mosaic_from_aligned_faces using this instance’s configured face image size.

Parameters
aligned_faces : list[np.ndarray] | np.ndarray

list/array of already aligned RGB face images.

mosaic_shape : tuple[int, int]

tuple of integers, (n_cols, n_rows)

border : float = 0.03

float, percent of image to use as white border

save_to : str | None = None

optional path used to save the mosaic image.

draw_keypoints : bool = False

if True, draw keypoints on each aligned face.

keypoints : list[np.ndarray] | np.ndarray | None = None

optional list/array of aligned keypoints, one per aligned face. Required when draw_keypoints=True.

keypoint_colors : tuple[str, str, str, str, str] = DEFAULT_KEYPOINT_COLORS

colors used for the five aligned keypoints when draw_keypoints=True.

Returns
: np.ndarray

np.ndarray: OpenCV BGR image with mosaic.

compare
app.ForensicFace.compare(img1path, img2path)

Compute the similarity cosine between the embeddings of two face images.

Parameters
img1path : str

Path to the first image file.

img2path : str

Path to the second image file.

Returns
float : float

Cosine similarity.

: float

The score ranges from -1.0 (most dissimilar) to 1.0 (most similar).

Raises
: ValueError

If concat_embeddings is False, because this method requires a single concatenated embedding for each image.

detect_and_align
app.ForensicFace.detect_and_align(
    imgpath,
    *,
    single_face=True,
    select_single_face_by='size',
)

Detect faces and return aligned crops without embedding/FIQA.

Useful in two scenarios: 1. Batched extraction: run detect_and_align per image to fill a buffer of aligned crops, then call process_aligned_faces_batch once per chunk. Lets ONNX use real batch parallelism on GPU. 2. Materialize aligned crops on disk for later re-extraction with newer recognition models.

Parameters
imgpath : str | np.ndarray

path to the image (str) or a BGR np.ndarray.

single_face : bool = True

when True, return only the best detected face.

select_single_face_by : str = 'size'

"size" or "centrality"; applied only when single_face=True and multiple faces are detected.

Returns
: dict | list[dict] | None

dict | list[dict] | None: With single_face=True, returns

: dict | list[dict] | None

one aligned-face dictionary or None when no face is detected.

: dict | list[dict] | None

With single_face=False, returns a list of dictionaries,

: dict | list[dict] | None

possibly empty. Each dictionary includes aligned_face (RGB

: dict | list[dict] | None

ndarray), bbox, keypoints, aligned_keypoints,

: dict | list[dict] | None

and det_score. When extended=True, it also includes

: dict | list[dict] | None

gender, age, and pose.

extract_faces
app.ForensicFace.extract_faces(
    video_path,
    dest_folder=None,
    every_n_frames=1,
    margin=2.0,
    start_from=0.0,
    export_metadata=False,
)

Extracts faces from a video and saves them as individual images.

Parameters
video_path : str

The path to the input video file.

dest_folder : str = None

The path to the output folder. If not provided, a new folder with the same name as the input video file is created.

every_n_frames : int = 1

Extract faces from every n-th frame.

margin : float = 2.0

The factor by which the detected face bounding box should be extended.

start_from : float = 0.0

The time point, in seconds, after which the video frames should be processed.

export_metadata : bool = False

If True, export facial metadata for each face.

Returns
int : int

The number of extracted faces.

process_aligned_face_image
app.ForensicFace.process_aligned_face_image(rgb_aligned_face, keypoints=None)

Process an already aligned RGB face image.

Parameters
rgb_aligned_face : np.ndarray

RGB face image with shape (112, 112, 3).

keypoints : np.ndarray | None = None

Optional 5x2 keypoints in the aligned 112x112 image coordinate system. Required when a keypoint-aware recognition model such as sepaelv6 is loaded.

process_aligned_faces_batch
app.ForensicFace.process_aligned_faces_batch(
    rgb_aligned_faces,
    aligned_keypoints_batch=None,
)

Process already aligned RGB face images in one recognition batch.

Parameters
rgb_aligned_faces : np.ndarray

RGB aligned face images with shape (N, 112, 112, 3).

aligned_keypoints_batch : np.ndarray | None = None

Optional keypoints with shape (N, 5, 2) in the aligned 112x112 image coordinate system. Required when a keypoint-aware recognition model such as sepaelv6 is loaded.

Returns
: list[FaceResult]

list[FaceResult]: One result per aligned face. Each result includes

: list[FaceResult]

embedding when concat_embeddings=True or one

: list[FaceResult]

embedding_<model_name> key per model otherwise. When

: list[FaceResult]

extended=True, each result also includes fiqa_score.

process_image
app.ForensicFace.process_image(
    imgpath,
    single_face=True,
    draw_keypoints=False,
    keypoint_colors=DEFAULT_KEYPOINT_COLORS,
    select_single_face_by='size',
)

Process an image assuming one or multiple faces. Args: - imgpath (str | np.ndarray): Path to the input image or cv2 image array in BGR. - draw_keypoints (bool): If set to True, draw the keypoints on the aligned face. - keypoint_colors (tuple[str, str, str, str, str]): colors used for the five aligned keypoints when draw_keypoints=True. - single_face (bool): If set to True, process only one face in the image. - select_single_face_by (str): criterion to select the face in the image, if more than one face is detected. Only applicable when single_face == True. Must be either ‘size’ or ‘centrality’. Returns: If single_face==True, return a dictionary containing the following keys: - ‘keypoints’: A 2D numpy array of shape (5, 2) containing the facial keypoints for each face in the image. The keypoints are ordered as follows: left eye, right eye, nose tip, left mouth corner, and right mouth corner.

    - 'ipd': A float representing the inter-pupillary distance for each face in the image.

    - 'embedding': A 1D numpy array of shape (512,) containing the facial embedding
           for each face in the image.
           If the concat_emmbeddings == True, keys for each model are used with the names <model_name>_embedding

    - 'bbox': A 1D numpy array of shape (4,) containing the bounding box coordinates for each face
      in the image. The coordinates are ordered as follows: (xmin, ymin, xmax, ymax).

    - 'aligned_face': A 3D numpy array of shape (H, W, C) in RGB order containing the aligned face image for
              each face in the image. The image has been cropped and aligned based on the
              facial keypoints.

    - 'det_score': A float representing the face detection score.

    If 'extended' is set to True, the dictionary will also contain the following keys:
    - 'gender': Estimated sex for each face in the image. Possible values: 'M' (male) and 'F' (female).

    - 'age': An integer representing the estimated age for each face in the image.

    - 'pitch': A float representing the pitch angle for each face in the image.

    - 'yaw': A float representing the yaw angle for each face in the image.

    - 'roll': A float representing the roll angle for each face in the image.

    - 'fiqa_score': A float indicating facial image quality.

If single_face==False, return a list of dictionaries, each containing the same keys as described above for each detected face in the image.
process_image_multiple_faces
app.ForensicFace.process_image_multiple_faces(
    imgpath,
    draw_keypoints=False,
    keypoint_colors=DEFAULT_KEYPOINT_COLORS,
)

Process an image assuming multiple faces. THIS METHOD IS DEPRECATED AND WILL BE REMOVED IN A FUTURE RELEASE. Use process_image instead.

process_image_single_face
app.ForensicFace.process_image_single_face(
    imgpath,
    draw_keypoints=False,
    keypoint_colors=DEFAULT_KEYPOINT_COLORS,
)

Process a an image considering it has a single face and extract useful features for forensic analysis. If more than one face is detected, the largest face will be returned. THIS METHOD IS DEPRECATED AND WILL BE REMOVED IN A FUTURE RELEASE. Use process_image instead.

process_images_batch
app.ForensicFace.process_images_batch(
    imgpaths,
    *,
    single_face=True,
    select_single_face_by='size',
    batch_size=16,
)

Batched counterpart of process_image.

Pipeline: 1. Per-image: detect_and_align, accumulate aligned crops into a buffer. 2. Per-chunk of batch_size: recognition/FIQA inference in one ONNX call per loaded model. 3. Reassemble into process_image-compatible dicts.

Parameters
imgpaths : list[str | np.ndarray]

iterable of image paths (str) or BGR ndarrays.

single_face : bool = True

when True, returns one dict per image (the best face) or None when no face is detected.

select_single_face_by : str = 'size'

"size" or "centrality" — only used with single_face=True.

batch_size : int = 16

number of faces fed to the recognition ONNX session at once. Default 16 is conservative — fits a single recognition model on an 8GB GPU (e.g. RTX 3070) with room for a second model. Raise it on bigger GPUs for more throughput; lower it on CPU. If the batch causes a CUDA OOM, the call auto-halves the batch and may warn while reducing the batch size.

Returns
list : list

Results parallel to imgpaths. With single_face=True,

: list

each item is a dict compatible with process_image or

: list

None when no face is detected. With single_face=False,

: list

each item is a list of per-image face dictionaries.