def test_face(self, static_image_mode: bool, refine_landmarks: bool, num_frames: int): image_path = os.path.join(os.path.dirname(__file__), 'testdata/portrait.jpg') image = cv2.imread(image_path) rows, cols, _ = image.shape with mp_faces.FaceMesh(static_image_mode=static_image_mode, refine_landmarks=refine_landmarks, min_detection_confidence=0.5) as faces: for idx in range(num_frames): results = faces.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) self._annotate(image.copy(), results, idx, refine_landmarks) multi_face_landmarks = [] for landmarks in results.multi_face_landmarks: self.assertLen( landmarks.landmark, mp_faces.FACEMESH_NUM_LANDMARKS_WITH_IRISES if refine_landmarks else mp_faces.FACEMESH_NUM_LANDMARKS) x = [landmark.x * cols for landmark in landmarks.landmark] y = [landmark.y * rows for landmark in landmarks.landmark] face_landmarks = np.column_stack((x, y)) multi_face_landmarks.append(face_landmarks) self.assertLen(multi_face_landmarks, 1) # Verify the eye landmarks are correct as sanity check. for eye_idx, gt_lds in EYE_INDICES_TO_LANDMARKS.items(): prediction_error = np.abs( np.asarray(multi_face_landmarks[0][eye_idx]) - np.asarray(gt_lds)) npt.assert_array_less(prediction_error, DIFF_THRESHOLD) if refine_landmarks: for iris_idx, gt_lds in IRIS_INDICES_TO_LANDMARKS.items(): prediction_error = np.abs( np.asarray(multi_face_landmarks[0][iris_idx]) - np.asarray(gt_lds)) npt.assert_array_less(prediction_error, DIFF_THRESHOLD)
def test_face(self, static_image_mode: bool, num_frames: int): image_path = os.path.join(os.path.dirname(__file__), 'testdata/face.jpg') faces = mp_faces.FaceMesh( static_image_mode=static_image_mode, min_detection_confidence=0.5) image = cv2.flip(cv2.imread(image_path), 1) def process_one_frame(): results = faces.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) multi_face_landmarks = [] for landmarks in results.multi_face_landmarks: self.assertLen(landmarks.landmark, 468) x = [landmark.x for landmark in landmarks.landmark] y = [landmark.y for landmark in landmarks.landmark] face_landmarks = np.transpose(np.stack((y, x))) * image.shape[0:2] multi_face_landmarks.append(face_landmarks) self.assertLen(multi_face_landmarks, 1) # Verify the eye landmarks are correct as sanity check. for idx, gt_lds in EYE_INDICES_TO_LANDMARKS.items(): prediction_error = np.abs( np.asarray(multi_face_landmarks[0][idx]) - np.asarray(gt_lds)) npt.assert_array_less(prediction_error, DIFF_THRESHOLOD) for _ in range(num_frames): process_one_frame() faces.close()
def test_blank_image(self): faces = mp_faces.FaceMesh() image = np.zeros([100, 100, 3], dtype=np.uint8) image.fill(255) results = faces.process(image) self.assertIsNone(results.multi_face_landmarks) faces.close()
def test_invalid_image_shape(self): with mp_faces.FaceMesh() as faces: with self.assertRaisesRegex( ValueError, 'Input image must contain three channel rgb data.'): faces.process(np.arange(36, dtype=np.uint8).reshape(3, 3, 4))