#!/usr/bin/env python # coding: utf-8 # # extract_face_landmarks: extract 68 landmark features from face images # A function extract facial landmarks. # > from mlxtend.image import extract_face_landmarks # ## Overview # The `extract_face_landmarks` function detects the faces in a given image, and then it will return the face landmark points (also known as face shape) for the first found face in the image based on dlib's face landmark detection code (https://dlib.net/face_landmark_detection_ex.cpp.html): # # > The face detector we use is made using the classic Histogram of Oriented # Gradients (HOG) feature combined with a linear classifier, an image pyramid, # and sliding window detection scheme. The pose estimator was created by # using dlib's implementation of the paper: # One Millisecond Face Alignment with an Ensemble of Regression Trees by # Vahid Kazemi and Josephine Sullivan, CVPR 2014 # and was trained on the iBUG 300-W face landmark dataset (see # https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/): # C. Sagonas, E. Antonakos, G, Tzimiropoulos, S. Zafeiriou, M. Pantic. # 300 faces In-the-wild challenge: Database and results. # Image and Vision Computing (IMAVIS), Special Issue on Facial Landmark Localisation "In-The-Wild". 2016. # You can get the trained model file from: # https://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2. # Note that the license for the iBUG 300-W dataset excludes commercial use. # So you should contact Imperial College London to find out if it's OK for # you to use this model file in a commercial product. # ### References # # - Kazemi, Vahid, and Josephine Sullivan. "One millisecond face alignment with an ensemble of regression trees." Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2014. # ## Example 1 -- RGB Images # In[1]: import imageio import matplotlib.pyplot as plt from mlxtend.image import extract_face_landmarks img = imageio.imread('test-face.png') landmarks = extract_face_landmarks(img) print(landmarks.shape) print('\n\nFirst 10 landmarks:\n', landmarks[:10]) # Visualization of the landmarks: # In[2]: fig = plt.figure(figsize=(15, 5)) ax = fig.add_subplot(1, 3, 1) ax.imshow(img) ax = fig.add_subplot(1, 3, 2) ax.scatter(landmarks[:, 0], -landmarks[:, 1], alpha=0.8) ax = fig.add_subplot(1, 3, 3) img2 = img.copy() for p in landmarks: img2[p[1]-3:p[1]+3, p[0]-3:p[0]+3, :] = (255, 255, 255) # note that the values -3 and +3 will make the landmarks # overlayed on the image 6 pixels wide; depending on the # resolution of the face image, you may want to change # this value ax.imshow(img2) plt.show() # ### Displaying the index of landmark points # In[3]: import numpy as np left_eye = np.array([36, 37, 38, 39, 40, 41]) right_eye = np.array([42, 43, 44, 45, 46, 47]) # In[4]: import matplotlib.pyplot as plt get_ipython().run_line_magic('matplotlib', 'inline') fig = plt.figure(figsize=(10,10)) plt.plot(landmarks[:,0], -landmarks[:,1], 'ro', markersize=8, alpha = 0.5) for i in range(landmarks.shape[0]): plt.text(landmarks[i,0]+1, -landmarks[i,1], str(i), size=14) left_eye_center = np.mean(landmarks[left_eye], axis=0) right_eye_center = np.mean(landmarks[right_eye], axis=0) print('Coordinates of the Left Eye: ', left_eye_center) print('Coordinates of the Right Eye: ', right_eye_center) plt.plot([left_eye_center[0]], [-left_eye_center[1]], marker='+', color='blue', markersize=10, mew=4) plt.plot([right_eye_center[0]], [-right_eye_center[1]], marker='+', color='blue', markersize=10, mew=4) plt.xticks([]) plt.yticks([]) plt.show() # ## Example 2 -- Grayscale Images # In[5]: import imageio import matplotlib.pyplot as plt from mlxtend.image import extract_face_landmarks img = imageio.imread('test-face_grayscale_lowres.png', ) landmarks = extract_face_landmarks(img) print(landmarks.shape) print('\n\nFirst 10 landmarks:\n', landmarks[:10]) # In[6]: fig = plt.figure(figsize=(15, 5)) ax = fig.add_subplot(1, 3, 1) ax.imshow(img, cmap='gray') ax = fig.add_subplot(1, 3, 2) ax.scatter(landmarks[:, 0], -landmarks[:, 1], alpha=0.8) ax = fig.add_subplot(1, 3, 3) img2 = img.copy() for p in landmarks: img2[p[1]-1:p[1]+1, p[0]-1:p[0]+1] = 255 # note that the values -1 and +1 will make the landmarks # overlayed on the image 2 pixels wide; depending on the # resolution of the face image, you may want to change # this value ax.imshow(img2, cmap='gray') plt.show() # ## API # In[7]: with open('../../api_modules/mlxtend.image/extract_face_landmarks.md', 'r') as f: print(f.read())