# Converts face landmarks to ROI.

type: "FaceLandmarksToRoi"

# Face landmarks. (NormalizedLandmarkList)
input_stream: "LANDMARKS:face_landmarks"
# Image size (width & height). (std::pair<int, int>)
input_stream: "IMAGE_SIZE:image_size"

# ROI according to landmarks. (NormalizedRect)
output_stream: "ROI:roi"

# Converts face landmarks to a detection that tightly encloses all landmarks.
node {
  calculator: "LandmarksToDetectionCalculator"
  input_stream: "NORM_LANDMARKS:face_landmarks"
  output_stream: "DETECTION:face_detection"
}

# Converts the face detection into a rectangle (normalized by image size)
# that encloses the face and is rotated such that the line connecting center of
# the wrist and MCP of the middle finger is aligned with the Y-axis of the
# rectangle.
node {
  calculator: "DetectionsToRectsCalculator"
  input_stream: "DETECTION:face_detection"
  input_stream: "IMAGE_SIZE:image_size"
  output_stream: "NORM_RECT:face_landmarks_rect_tight"
  options: {
    [mediapipe.DetectionsToRectsCalculatorOptions.ext] {
      rotation_vector_start_keypoint_index: 33  # Right side of left eye.
      rotation_vector_end_keypoint_index: 263  # Left side of right eye.
      rotation_vector_target_angle_degrees: 0
    }
  }
}

# Expands the face rectangle so that it's likely to contain the face even with
# some motion.
node {
  calculator: "RectTransformationCalculator"
  input_stream: "NORM_RECT:face_landmarks_rect_tight"
  input_stream: "IMAGE_SIZE:image_size"
  output_stream: "roi"
  options: {
    [mediapipe.RectTransformationCalculatorOptions.ext] {
      scale_x: 1.5
      scale_y: 1.5
      # TODO: remove `square_long` where appropriat
      square_long: true
    }
  }
}
