-
-
Save zalo/71fbd5dbfe23cb46406d211b84be9f7e to your computer and use it in GitHub Desktop.
import numpy as np | |
import cv2 | |
import face_alignment | |
# Initialize the face alignment tracker | |
fa = face_alignment.FaceAlignment(face_alignment.LandmarksType._3D, flip_input=True, device="cuda") | |
# Start the webcam capture, exit with 'q' | |
cap = cv2.VideoCapture(0) | |
while(not (cv2.waitKey(1) & 0xFF == ord('q'))): | |
ret, frame = cap.read() | |
if(ret): | |
# Clear the indices frame | |
canonical = np.zeros(frame.shape) | |
# Run the face alignment tracker on the webcam image | |
imagePoints = fa.get_landmarks_from_image(frame) | |
if(imagePoints is not None): | |
imagePoints = imagePoints[0] | |
# Compute the Mean-Centered-Scaled Points | |
mean = np.mean(imagePoints, axis=0) # <- This is the unscaled mean | |
scaled = (imagePoints / np.linalg.norm(imagePoints[42] - imagePoints[39])) * 0.06 # Set the inner eye distance to 60cm (just because) | |
centered = scaled - np.mean(scaled, axis=0) # <- This is the scaled mean | |
# Construct a "rotation" matrix (strong simplification, might have shearing) | |
rotationMatrix = np.empty((3,3)) | |
rotationMatrix[0,:] = (centered[16] - centered[0])/np.linalg.norm(centered[16] - centered[0]) | |
rotationMatrix[1,:] = (centered[8] - centered[27])/np.linalg.norm(centered[8] - centered[27]) | |
rotationMatrix[2,:] = np.cross(rotationMatrix[0, :], rotationMatrix[1, :]) | |
invRot = np.linalg.inv(rotationMatrix) | |
# Object-space points, these are what you'd run OpenCV's solvePnP() with | |
objectPoints = centered.dot(invRot) | |
# Draw the computed data | |
for i, (imagePoint, objectPoint) in enumerate(zip(imagePoints, objectPoints)): | |
# Draw the Point Predictions | |
cv2.circle(frame, (imagePoint[0], imagePoint[1]), 3, (0,255,0)) | |
# Draw the X Axis | |
cv2.line(frame, tuple(mean[:2].astype(int)), | |
tuple((mean+(rotationMatrix[0,:] * 100.0))[:2].astype(int)), (0, 0, 255), 3) | |
# Draw the Y Axis | |
cv2.line(frame, tuple(mean[:2].astype(int)), | |
tuple((mean-(rotationMatrix[1,:] * 100.0))[:2].astype(int)), (0, 255, 0), 3) | |
# Draw the Z Axis | |
cv2.line(frame, tuple(mean[:2].astype(int)), | |
tuple((mean+(rotationMatrix[2,:] * 100.0))[:2].astype(int)), (255, 0, 0), 3) | |
# Draw the indices in Object Space | |
cv2.putText(canonical, str(i), | |
((int)((objectPoint[0] * 1000.0) + 320.0), | |
(int)((objectPoint[1] * 1000.0) + 240.0)), | |
cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255, 255, 255), 1, cv2.LINE_AA) | |
cv2.imshow('Webcam View', frame) | |
cv2.imshow('Canonical View', canonical) | |
# When everything is done, release the capture | |
cap.release() | |
cv2.destroyAllWindows() |
Hi,
Thanks for your reply.
Sorry for late response.import numpy as np
import cv2
import face_alignment
import math
def rotationMatrixToEulerAngles(R) :
sy = math.sqrt(R[0,0] * R[0,0] + R[1,0] * R[1,0])
singular = sy < 1e-6
if not singular :
x = math.atan2(R[2,1] , R[2,2])
y = math.atan2(-R[2,0], sy)
z = math.atan2(R[1,0], R[0,0])
else :
x = math.atan2(-R[1,2], R[1,1])
y = math.atan2(-R[2,0], sy)
z = 0
return np.array([x, y, z])
#Initialize the face alignment tracker
fa = face_alignment.FaceAlignment(face_alignment.LandmarksType.3D, flip_input=True, device="cpu") frame=cv2.imread("model9.jpg") #("model9.jpg") canonical = np.zeros(frame.shape) #Run the face alignment tracker on the image #imagePoints = fa.get_landmarks_from_image(frame) imagePoints = fa.get_landmarks(frame) if(imagePoints is not None): imagePoints = imagePoints[0] # Compute the Mean-Centered-Scaled Points mean = np.mean(imagePoints, axis=0) # <- This is the unscaled mean scaled = (imagePoints / np.linalg.norm(imagePoints[42] - imagePoints[39])) * 0.06 # Set the inner eye distance to 60cm (just because) centered = scaled - np.mean(scaled, axis=0) # <- This is the scaled mean # Construct a "rotation" matrix (strong simplification, might have shearing) rotationMatrix = np.empty((3,3)) rotationMatrix[0,:] = (centered[16] - centered[0])/np.linalg.norm(centered[16] - centered[0]) rotationMatrix[1,:] = (centered[8] - centered[27])/np.linalg.norm(centered[8] - centered[27]) rotationMatrix[2,:] = np.cross(rotationMatrix[0, :], rotationMatrix[1, :]) eulerAngles=rotationMatrixToEulerAngles(rotationMatrix) pitch, yaw, roll = [math.radians()*100.0 for _ in eulerAngles]
pitch = math.degrees(math.asin(math.sin(pitch)))
roll = -math.degrees(math.asin(math.sin(roll)))
yaw = math.degrees(math.asin(math.sin(yaw)))rotate_degree=[ str(int(pitch)), str(int(roll)),str(int(yaw))]
rotate_degree=[math.floor(pitch),math.floor(roll),math.floor(yaw)]
print ("Rotate_Degree:",rotate_degree)
cv2.imshow('Webcam View', frame)
cv2.imshow('Canonical View', canonical)
cv2.waitKey(0)With the above code, if i print rotate_degree giving result as Rotate_Degree: ['16', '44', '-20'], where as from https://azure.microsoft.com/en-us/services/cognitive-services/face/#demo link getting values for pitch, roll, yaw as like this "headPose": { "pitch": 6.0, "roll": 24.7, "yaw": 11.1 }
What should i modify to get the results??Thanks in Advance.
Regards,
Sandhyalaxmi Kanna
rotationMatrix = np.empty((3, 3))
rotationMatrix[0, :] = (centered[16] - centered[0]) / np.linalg.norm(centered[16] - centered[0])
rotationMatrix[1, :] = (centered[8] - centered[27]) / np.linalg.norm(centered[8] - centered[27])
rotationMatrix[2, :] = np.cross(rotationMatrix[0, :], rotationMatrix[1, :])
eulerAngles = rotationMatrixToEulerAngles(rotationMatrix)
pitch, yaw, roll = eulerAngles
pitch = np.degrees(np.arcsin(np.sin(pitch)))
roll = -np.degrees(np.arcsin(np.sin(roll)))
yaw = -np.degrees(np.arcsin(np.sin(yaw)))
Thanks @patrickwangqy. It is working very well.
np.arcsin(np.sin(pitch))
why?
np.arcsin(np.sin(pitch))
why?
angle range
you clip it with -90+90 deg? but what if actual YAW > 90 deg ?
it is impossible
Hi,
Thanks for your reply.
Sorry for late response.
import numpy as np
import cv2
import face_alignment
import math
def rotationMatrixToEulerAngles(R) :
sy = math.sqrt(R[0,0] * R[0,0] + R[1,0] * R[1,0])
singular = sy < 1e-6
if not singular :
x = math.atan2(R[2,1] , R[2,2])
y = math.atan2(-R[2,0], sy)
z = math.atan2(R[1,0], R[0,0])
else :
x = math.atan2(-R[1,2], R[1,1])
y = math.atan2(-R[2,0], sy)
z = 0
return np.array([x, y, z])
#Initialize the face alignment tracker
fa = face_alignment.FaceAlignment(face_alignment.LandmarksType.3D, flip_input=True, device="cpu")
frame=cv2.imread("model9.jpg") #("model9.jpg")
canonical = np.zeros(frame.shape)
#Run the face alignment tracker on the image
#imagePoints = fa.get_landmarks_from_image(frame)
imagePoints = fa.get_landmarks(frame)
if(imagePoints is not None):
imagePoints = imagePoints[0]
# Compute the Mean-Centered-Scaled Points
mean = np.mean(imagePoints, axis=0) # <- This is the unscaled mean
scaled = (imagePoints / np.linalg.norm(imagePoints[42] - imagePoints[39])) * 0.06 # Set the inner eye distance to 60cm (just because)
centered = scaled - np.mean(scaled, axis=0) # <- This is the scaled mean
# Construct a "rotation" matrix (strong simplification, might have shearing)
rotationMatrix = np.empty((3,3))
rotationMatrix[0,:] = (centered[16] - centered[0])/np.linalg.norm(centered[16] - centered[0])
rotationMatrix[1,:] = (centered[8] - centered[27])/np.linalg.norm(centered[8] - centered[27])
rotationMatrix[2,:] = np.cross(rotationMatrix[0, :], rotationMatrix[1, :])
eulerAngles=rotationMatrixToEulerAngles(rotationMatrix)
pitch, yaw, roll = [math.radians()*100.0 for _ in eulerAngles]
pitch = math.degrees(math.asin(math.sin(pitch)))
roll = -math.degrees(math.asin(math.sin(roll)))
yaw = math.degrees(math.asin(math.sin(yaw)))
# rotate_degree=[ str(int(pitch)), str(int(roll)),str(int(yaw))]
rotate_degree=[math.floor(pitch),math.floor(roll),math.floor(yaw)]
print ("Rotate_Degree:",rotate_degree)
cv2.imshow('Webcam View', frame)
cv2.imshow('Canonical View', canonical)
cv2.waitKey(0)
With the above code, if i print rotate_degree giving result as Rotate_Degree: ['16', '44', '-20'], where as from https://azure.microsoft.com/en-us/services/cognitive-services/face/#demo link getting values for pitch, roll, yaw as like this
"headPose": {
"pitch": 6.0,
"roll": 24.7,
"yaw": 11.1
}
What should i modify to get the results??
My model9.jpg image is
Thanks in Advance.
Regards,
Sandhyalaxmi Kanna