(original) (raw)
#!/usr/bin/python
The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
This example shows how to use dlib's face recognition tool for clustering using chinese_whispers.
This is useful when you have a collection of photographs which you know are linked to
a particular person, but the person may be photographed with multiple other people.
In this example, we assume the largest cluster will contain photos of the common person in the
collection of photographs. Then, we save extracted images of the face in the largest cluster in
a 150x150 px format which is suitable for jittering and loading to perform metric learning (as shown
in the dnn_metric_learning_on_images_ex.cpp example.
https://github.com/davisking/dlib/blob/master/examples/dnn_metric_learning_on_images_ex.cpp
COMPILING/INSTALLING THE DLIB PYTHON INTERFACE
You can install dlib using the command:
pip install dlib
Alternatively, if you want to compile dlib yourself then go into the dlib
root folder and run:
python setup.py install
Compiling dlib should work on any operating system so long as you have
CMake installed. On Ubuntu, this can be done easily by running the
command:
sudo apt-get install cmake
Also note that this example requires Numpy which can be installed
via the command:
pip install numpy
import sys import os import dlib import glob
if len(sys.argv) != 5: print( "Call this program like this:\n" " ./face_clustering.py shape_predictor_5_face_landmarks.dat dlib_face_recognition_resnet_model_v1.dat ../examples/faces output_folder\n" "You can download a trained facial shape predictor and recognition model from:\n" " http://dlib.net/files/shape_predictor_5_face_landmarks.dat.bz2\n" " http://dlib.net/files/dlib_face_recognition_resnet_model_v1.dat.bz2") exit()
predictor_path = sys.argv[1] face_rec_model_path = sys.argv[2] faces_folder_path = sys.argv[3] output_folder_path = sys.argv[4]
Load all the models we need: a detector to find the faces, a shape predictor
to find face landmarks so we can precisely localize the face, and finally the
face recognition model.
detector = dlib.get_frontal_face_detector() sp = dlib.shape_predictor(predictor_path) facerec = dlib.face_recognition_model_v1(face_rec_model_path)
descriptors = [] images = []
Now find all the faces and compute 128D face descriptors for each face.
for f in glob.glob(os.path.join(faces_folder_path, "*.jpg")): print("Processing file: {}".format(f)) img = dlib.load_rgb_image(f)
# Ask the detector to find the bounding boxes of each face. The 1 in the
# second argument indicates that we should upsample the image 1 time. This
# will make everything bigger and allow us to detect more faces.
dets = detector(img, 1)
print("Number of faces detected: {}".format(len(dets)))
# Now process each face we found.
for k, d in enumerate(dets):
# Get the landmarks/parts for the face in box d.
shape = sp(img, d)
# Compute the 128D vector that describes the face in img identified by
# shape.
face_descriptor = facerec.compute_face_descriptor(img, shape)
descriptors.append(face_descriptor)
images.append((img, shape))Now let's cluster the faces.
labels = dlib.chinese_whispers_clustering(descriptors, 0.5) num_classes = len(set(labels)) print("Number of clusters: {}".format(num_classes))
Find biggest class
biggest_class = None biggest_class_length = 0 for i in range(0, num_classes): class_length = len([label for label in labels if label == i]) if class_length > biggest_class_length: biggest_class_length = class_length biggest_class = i
print("Biggest cluster id number: {}".format(biggest_class)) print("Number of faces in biggest cluster: {}".format(biggest_class_length))
Find the indices for the biggest class
indices = [] for i, label in enumerate(labels): if label == biggest_class: indices.append(i)
print("Indices of images in the biggest cluster: {}".format(str(indices)))
Ensure output directory exists
if not os.path.isdir(output_folder_path): os.makedirs(output_folder_path)
Save the extracted faces
print("Saving faces in largest cluster to output folder...") for i, index in enumerate(indices): img, shape = images[index] file_path = os.path.join(output_folder_path, "face_" + str(i)) # The size and padding arguments are optional with default size=150x150 and padding=0.25 dlib.save_face_chip(img, shape, file_path, size=150, padding=0.25)