Fix PnP rotation/translation shape for modern OpenCV/NumPy.

solvePnP returns (3,1); transpose made (1,3), which broke eye depth .dot()
and struct.pack of translation scalars. Flatten to (3,) instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
copilot 2026-09-14 11:12:25 +02:00
parent 85aa70fc67
commit 6da0ba68df

View file

@ -783,8 +783,10 @@ class Tracker():
face_info.translation = np.array([0.0, 0.0, 0.0], np.float32) face_info.translation = np.array([0.0, 0.0, 0.0], np.float32)
return False, np.zeros(4), np.zeros(3), 99999., pts_3d, lms return False, np.zeros(4), np.zeros(3), 99999., pts_3d, lms
else: else:
face_info.rotation = np.transpose(face_info.rotation) # OpenCV returns (3,1); flatten so [0]/[1]/[2] are scalars for UDP packing
face_info.translation = np.transpose(face_info.translation) # and 1D .dot() math does not broadcast to (1,3).
face_info.rotation = np.asarray(face_info.rotation, dtype=np.float32).reshape(3)
face_info.translation = np.asarray(face_info.translation, dtype=np.float32).reshape(3)
rmat, _ = cv2.Rodrigues(rotation) rmat, _ = cv2.Rodrigues(rotation)
inverse_rotation = np.linalg.inv(rmat) inverse_rotation = np.linalg.inv(rmat)
@ -833,7 +835,7 @@ class Tracker():
reference = rmat.dot(pt) reference = rmat.dot(pt)
reference = reference + face_info.translation reference = reference + face_info.translation
reference = self.camera.dot(reference) reference = self.camera.dot(reference)
depth = reference[2] depth = float(reference[2])
pt_3d = np.array([lms[66+i][0] * depth, lms[66+i][1] * depth, depth], np.float32) pt_3d = np.array([lms[66+i][0] * depth, lms[66+i][1] * depth, depth], np.float32)
pt_3d = self.inverse_camera.dot(pt_3d) pt_3d = self.inverse_camera.dot(pt_3d)
pt_3d = pt_3d - face_info.translation pt_3d = pt_3d - face_info.translation