I used dlib and numpy to extract the list of facial keypoints.
Code:
def get_landmarks(im):
rects = detector(im, 1)
if len(rects) > 1:
raise TooManyFaces
if len(rects) == 0:
raise NoFaces
return numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])
for f in glob.glob(os.path.join(faces_folder_path, "*")):
print("Processing file: {}".format(f))
img = io.imread(f)
win.clear_overlay()
win.set_image(img)
dets = detector(img, 1)
print("Number of faces detected: {}".format(len(dets)))
for k, d in enumerate(dets):
# Get the landmarks/parts for the face in box d.
shape = predictor(img, d)
lms = get_landmarks(img)
print ("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(k, d.left(), d.top(), d.right(), d.bottom()))
print ("Part 0: {}, Part 1: {} ...".format(shape.part(0), shape.part(1)))
newSection()
print ("Keypoints:" + (str(lms)))
# Draw the face landmarks on the screen.
win.add_overlay(shape)
win.add_overlay(dets)
dlib.hit_enter_to_continue()
Result:
And as you can see, it works fine. However, what I need isn't the blue alignment lines, but for there to be a numbered correlation between the keypoints and the image, like this. How can I overlay the numpy matrix with the image points:
numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])
on the opencv image? I attempted it myself:
for idx, point in enumerate(lms):
pos = (point[0, 0], point[0, 1])
cv2.putText(imB, str(idx), pos,
fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,
fontScale=0.4,
color=(0, 0, 255))
cv2.circle(im, pos, 3, color=(0, 255, 255))
WIDTH = 1000
HEIGHT = 1000
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image', imB)
cv2.resizeWindow('image', WIDTH, HEIGHT)
But it just gives me a blank grew box with a red box in it.