insightface_pytorch

repository·master·Indexed 23 days ago

https://github.com/treb1en/insightface_pytorch

A PyTorch 0.4.1 reimplementation of Arcface and InsightFace. It features backbone modules for Arcface and MobileFaceNet, tools for transforming MXNET data to image datafolders, and pretrained models for face recognition. The library includes an MTCNN implementation for face detection and landmarking, as well as utilities for face alignment, warping, and cropping via the warp_and_crop_face function.

Tokens
5.6K
Snippets
13
Records
37
Agent score
83%

What's inside insightface_pytorch

  1. Detect faces via camera

    master

    To capture a face image using your camera for the facebank:

    1. Ensure you have downloaded the desired weights to the model folder.
    2. Run the capture script with a name flag:
    python take_pic.py -n name

    Press q to take the picture. The script will capture only the single highest-probability face if multiple people are present.

    1. To start the verification process, run:
    python face_verify.py
  2. Prepare dataset for training

    master

    To train the models, you need to prepare the dataset (e.g., the emore dataset).

    1. Download and unzip the dataset files into the data path.
    2. Run the preparation script to organize the files:
    python prepare_data.py

    After execution, the faces_emore/ directory will contain subfolders like agedb_30, calfw, cfp_ff, cfp_fp, cplfw, imgs, lfw, and vgg2_fp.

  3. Prepare the Facebank for detection

    master

    To perform face detection and verification over a camera or video, you must set up a face_bank directory. The system uses the folder structure to identify unique IDs. If a folder contains multiple images, the system will calculate an average embedding for that ID.

    Required structure:

    data/facebank/
            ---> id1/
                ---> id1_1.jpg
            ---> id2/
                ---> id2_1.jpg
            ---> id3/
                ---> id3_1.jpg
               ---> id3_2.jpg
  4. Detect faces using MTCNN

    master

    To perform face detection using this MTCNN implementation, use the detect_faces function from the src module. This function accepts a PIL Image object and returns the detected bounding boxes and facial landmarks.

    Returns:

    • bounding_boxes: The coordinates of the detected faces.
    • landmarks: The facial landmark points for each detected face.
    from src import detect_faces
    from PIL import Image
    
    image = Image.open('image.jpg')
    bounding_boxes, landmarks = detect_faces(image)
  5. Train the models

    master

    You can train the models using the train.py script with the following arguments:

    • -b [batch_size]: Set the batch size.
    • -lr [learning rate]: Set the learning rate.
    • -e [epochs]: Set the number of epochs.

    Example command for training MobileFacenet:

    python train.py -net mobilefacenet -b 200 -w 4
    python train.py -b [batch_size] -lr [learning rate] -e [epochs]
    
    # Example:
    python train.py -net mobilefacenet -b 200 -w 4
  6. Extract faces from MXNet RecordIO files

    master

    If your dataset is stored in MXNet RecordIO format (.rec and .idx), you can use mxnet.recordio.MXIndexedRecordIO to read specific images by index. The process involves:

    1. Opening the recordio file.
    2. Reading the indexed record.
    3. Unpacking the header and image bytes.
    4. Converting the bytes into a PIL Image object.
    import mxnet as mx
    import io
    from PIL import Image
    from pathlib import Path
    
    face_folder = Path('/path/to/dataset')
    bin_path = face_folder/'train.rec'
    idx_path = face_folder/'train.idx'
    
    # Open the recordio file
    imgrec = mx.recordio.MXIndexedRecordIO(str(idx_path), str(bin_path), 'r')
    
    # Read an image by index
    img_info = imgrec.read_idx(813)
    header, img = mx.recordio.unpack(img_info)
    
    # Convert to PIL Image
    encoded_jpg_io = io.BytesIO(img)
    image = Image.open(encoded_jpg_io)
  7. Switch to MobileFaceNet architecture

    master

    To use the MobileFaceNet architecture instead of the default, update the use_mobilfacenet flag in your configuration object before initializing the face_learner.

    conf.use_mobilfacenet = True
    learner = face_learner(conf, inference=True)
    learner.load_state(conf, 'mobilefacenet.pth', True, True)
  8. Extract and align all faces from an image

    master

    This workflow demonstrates how to iterate through all detected faces in an image, crop them using their bounding boxes, adjust landmarks to be relative to the crop, and finally align/crop them into a standardized format.

    1. Detect faces and landmarks.
    2. Convert the PIL image to a NumPy array (OpenCV format: BGR).
    3. For each detection:
      • Adjust bounding box coordinates to ensure they stay within image boundaries.
      • Crop the face from the image.
      • Calculate facial landmarks relative to the top-left corner of the crop.
      • Apply warp_and_crop_face to get the aligned face.
      • Convert the resulting NumPy array back to a PIL Image.
    from src import detect_faces
    from src.align_trans import warp_and_crop_face
    from PIL import Image
    import numpy as np
    from tqdm import tqdm_notebook as tqdm
    
    img = Image.open('images/jf.jpg')
    bounding_boxes, landmarks = detect_faces(img)
    faces = []
    img_cv2 = np.array(img)[...,::-1]
    
    for i in tqdm(range(len(bounding_boxes))):
        box = bounding_boxes[i][:4].astype(np.int32).tolist()
        # Boundary safety checks
        for idx, coord in enumerate(box[:2]):
            if coord > 1:
                box[idx] -= 1
        if box[2] + 1 < img_cv2.shape[1]:
            box[2] += 1
        if box[3] + 1 < img_cv2.shape[0]:
            box[3] += 1
            
        face = img_cv2[box[1]:box[3],box[0]:box[2]]
        landmark = landmarks[i]
        # Make landmarks relative to the crop
        facial5points = [[landmark[j] - box[0], landmark[j+5] - box[1]] for j in range(5)]
        
        dst_img = warp_and_crop_face(face, facial5points)
        faces.append(Image.fromarray(dst_img[...,::-1]))