Face Landmark detection

Installing dlib

If you use this code the first issue you might have is installing dlib. It was unnecessarily challenging but in the end I fixed it using these steps.

  • Installing cmake
    (conda install -c anaconda cmake)
  • Downloading Visual Studio build tools, running the .exe file and selecting the C++ tools
  • Running install dlib” in your Command Prompt

The code

Importing all the modules should give you no errors now. Providing the others were installed correctly.

path_to_image is just the directory path to the image you wish to perform the code on.

Detector uses the dlib get_frontal_face_detector() function to detects faces in the image.

Predictor in line 11 uses shape_predictor_68_face_landmarks.dat which was trained to localise individual facial structures and predict x,y coordinates.

The next bit you loop over the face detections and draw the rectangle and then loop over the x,y coordinates and draw circles on the image.

Change the 1 in line 43 to a larger value for larger points.

from imutils import face_utils
import numpy as np
import dlib
import cv2

path_to_image =  r'C:\Users\jack\Desktop\JDHProjects\FaceAverage\facial-landmarks\images\nick.jpg'

# initialize dlib's face detector (HOG-based) and then create
# the facial landmark predictor
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

# load the input image and convert it to grayscale
image = cv2.imread(path_to_image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# detect faces in the grayscale image
rects = detector(gray, 1)


# loop over the face detections
for (i, rect) in enumerate(rects):
	# determine the facial landmarks for the face region, then
	# convert the facial landmark (x, y)-coordinates to a NumPy
	# array

	shape = predictor(gray, rect)
	shape = face_utils.shape_to_np(shape)

	# convert dlib's rectangle to a OpenCV-style bounding box
	# [i.e., (x, y, w, h)], then draw the face bounding box
	(x, y, w, h) = face_utils.rect_to_bb(rect)
	cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

	# show the face number
	cv2.putText(image, "Face #{}".format(i + 1), (x - 10, y - 10),
		cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
    
	# loop over the (x, y)-coordinates for the facial landmarks
	# and draw them on the image and save the values to a txt doc
	store_file = open("images/nick.txt", "w")
	for (x, y) in shape:
		cv2.circle(image, (x, y), 1, (0, 0, 255), -1)
		store_file.write(str(x) + " ")
		store_file.write(str(y) + "\n")
	store_file.close()

# show the output image with the face detections + facial landmarks
cv2.imshow("Output", image)
cv2.waitKey(0)
Original Image
Image with rectangle face detect and landmarks
Text file with list of facial feature coordinates