Dlib: facial distance between landmarks to calculate euclidean distance

Created on 13 Nov 2017  路  5Comments  路  Source: davisking/dlib

Hi,

I am able to run sample application in which i got the points(lines between eyes and nose) plotted on the face. I need to get euclidean distance between the plotted points

I tried with the below approach but was unable to succeed

for (name, (i, j)) in face_utils.FACIAL_LANDMARKS_IDXS.items():
        (lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
        leftEyePts = shape[lStart:lEnd]
    face_descriptor = facerec.compute_face_descriptor(img, shape)

Error: TypeError: 'full_object_detection' object has no attribute '__getitem__'

Please suggest the best possible way to calculate euclidean distance.

Thanks
vijay

Most helpful comment

I found some other people saying I should use numpy but ran into issues with it as well. Wasn't able to covert the dlib Vector class to numpy vectors. I just wrote my own method:

from math import sqrt

def euclidean_dist(vector_x, vector_y):
    if len(vector_x) != len(vector_y):
        raise Exception('Vectors must be same dimensions')
    return sum((vector_x[dim] - vector_y[dim]) ** 2 for dim in range(len(vector_x)))

used like:

face_descriptor_a = facerec.compute_face_descriptor(img_a, shape)
face_descriptor_b = facerec.compute_face_descriptor(img_b, shape)

is_same_face = euclidean_dist(face_descriptor_a, face_descriptor_b) < .6

All 5 comments

Bumb, I'm also looking for a good way to calculate euclidian distance between face_descriptors. I found this SO post for basic calculation of euclidian distance but when I try to use it I get:

TypeError: unsupported operand type(s) for -: 'vector' and 'vector'

This makes sense and is expected but still leaves me looking for a solution to calculate.

using numpy you can get euclidean distance np.linalg.norm(known_faces - face, axis=1).
know_faces and face are numpy arrays of 128D facial landmarks

I found some other people saying I should use numpy but ran into issues with it as well. Wasn't able to covert the dlib Vector class to numpy vectors. I just wrote my own method:

from math import sqrt

def euclidean_dist(vector_x, vector_y):
    if len(vector_x) != len(vector_y):
        raise Exception('Vectors must be same dimensions')
    return sum((vector_x[dim] - vector_y[dim]) ** 2 for dim in range(len(vector_x)))

used like:

face_descriptor_a = facerec.compute_face_descriptor(img_a, shape)
face_descriptor_b = facerec.compute_face_descriptor(img_b, shape)

is_same_face = euclidean_dist(face_descriptor_a, face_descriptor_b) < .6

My solution implementation for #950 -

Used this self defined function for conversion from dlib vectors to numpy arrays -

def dlibVect_to_numpyNDArray(vector):
    array = np.zeros(shape=128)
    for i in range(0, len(vector)):
        array[i] = vector[i]
    return array

And found out the euclidean distance using numpy methods -

test_landmarks = dlibVect_to_numpyNDArray(face_descriptor)
dist = np.linalg.norm(database_landmarks - test_landmarks)

Write up a conditional clause to check the dist threshold

The easiest way for convert dlip vector to np array is usingnp.asarray(<your-dlib-key>) after that operation you can use np.linalg.norm(database_landmarks - <your-dlib-key>)

My solution implementation for #950 -

Used this self defined function for conversion from dlib vectors to numpy arrays -

def dlibVect_to_numpyNDArray(vector):
    array = np.zeros(shape=128)
    for i in range(0, len(vector)):
        array[i] = vector[i]
    return array

And found out the euclidean distance using numpy methods -

test_landmarks = dlibVect_to_numpyNDArray(face_descriptor)
dist = np.linalg.norm(database_landmarks - test_landmarks)

Write up a conditional clause to check the dist threshold

I think there is no need to write a function for convert dlib vector to numpy array you can use numpy.asarray() function for that operation.

Was this page helpful?
0 / 5 - 0 ratings