Project import generated by Copybara.

GitOrigin-RevId: d073f8e21be2fcc0e503cb97c6695078b6b75310
This commit is contained in:
MediaPipe Team
2021-02-27 03:30:05 -05:00
committed by chuoling
parent 39309bedba
commit 350fbb2100
755 changed files with 16391 additions and 11075 deletions
+113
View File
@@ -21,6 +21,8 @@ import cv2
import dataclasses
import numpy as np
from mediapipe.framework.formats import detection_pb2
from mediapipe.framework.formats import location_data_pb2
from mediapipe.framework.formats import landmark_pb2
PRESENCE_THRESHOLD = 0.5
@@ -58,6 +60,57 @@ def _normalized_to_pixel_coordinates(
return x_px, y_px
def draw_detection(
image: np.ndarray,
detection: detection_pb2.Detection,
keypoint_drawing_spec: DrawingSpec = DrawingSpec(color=RED_COLOR),
bbox_drawing_spec: DrawingSpec = DrawingSpec()):
"""Draws the detction bounding box and keypoints on the image.
Args:
image: A three channel RGB image represented as numpy ndarray.
detection: A detection proto message to be annotated on the image.
keypoint_drawing_spec: A DrawingSpec object that specifies the keypoints'
drawing settings such as color, line thickness, and circle radius.
bbox_drawing_spec: A DrawingSpec object that specifies the bounding box's
drawing settings such as color and line thickness.
Raises:
ValueError: If one of the followings:
a) If the input image is not three channel RGB.
b) If the location data is not relative data.
"""
if not detection.location_data:
return
if image.shape[2] != RGB_CHANNELS:
raise ValueError('Input image must contain three channel rgb data.')
image_rows, image_cols, _ = image.shape
location = detection.location_data
if location.format != location_data_pb2.LocationData.RELATIVE_BOUNDING_BOX:
raise ValueError(
'LocationData must be relative for this drawing funtion to work.')
# Draws keypoints.
for keypoint in location.relative_keypoints:
keypoint_px = _normalized_to_pixel_coordinates(keypoint.x, keypoint.y,
image_cols, image_rows)
cv2.circle(image, keypoint_px, keypoint_drawing_spec.circle_radius,
keypoint_drawing_spec.color, keypoint_drawing_spec.thickness)
# Draws bounding box if exists.
if not location.HasField('relative_bounding_box'):
return
relative_bounding_box = location.relative_bounding_box
rect_start_point = _normalized_to_pixel_coordinates(
relative_bounding_box.xmin, relative_bounding_box.ymin, image_cols,
image_rows)
rect_end_point = _normalized_to_pixel_coordinates(
relative_bounding_box.xmin + relative_bounding_box.width,
relative_bounding_box.ymin + +relative_bounding_box.height, image_cols,
image_rows)
cv2.rectangle(image, rect_start_point, rect_end_point,
bbox_drawing_spec.color, bbox_drawing_spec.thickness)
def draw_landmarks(
image: np.ndarray,
landmark_list: landmark_pb2.NormalizedLandmarkList,
@@ -116,3 +169,63 @@ def draw_landmarks(
for landmark_px in idx_to_coordinates.values():
cv2.circle(image, landmark_px, landmark_drawing_spec.circle_radius,
landmark_drawing_spec.color, landmark_drawing_spec.thickness)
def draw_axis(
image: np.ndarray,
rotation: np.ndarray,
translation: np.ndarray,
focal_length: Tuple[float, float] = (1.0, 1.0),
principal_point: Tuple[float, float] = (0.0, 0.0),
axis_length: float = 0.1,
x_axis_drawing_spec: DrawingSpec = DrawingSpec(color=(0, 0, 255)),
y_axis_drawing_spec: DrawingSpec = DrawingSpec(color=(0, 128, 0)),
z_axis_drawing_spec: DrawingSpec = DrawingSpec(color=(255, 0, 0))):
"""Draws the 3D axis on the image.
Args:
image: A three channel RGB image represented as numpy ndarray.
rotation: Rotation matrix from object to camera coordinate frame.
translation: Translation vector from object to camera coordinate frame.
focal_length: camera focal length along x and y directions.
principal_point: camera principal point in x and y.
axis_length: length of the axis in the drawing.
x_axis_drawing_spec: A DrawingSpec object that specifies the x axis
drawing settings such as color, line thickness.
y_axis_drawing_spec: A DrawingSpec object that specifies the y axis
drawing settings such as color, line thickness.
z_axis_drawing_spec: A DrawingSpec object that specifies the z axis
drawing settings such as color, line thickness.
Raises:
ValueError: If one of the followings:
a) If the input image is not three channel RGB.
"""
if image.shape[2] != RGB_CHANNELS:
raise ValueError('Input image must contain three channel rgb data.')
image_rows, image_cols, _ = image.shape
# Create axis points in camera coordinate frame.
axis_world = np.float32([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]])
axis_cam = np.matmul(rotation, axis_length*axis_world.T).T + translation
x = axis_cam[..., 0]
y = axis_cam[..., 1]
z = axis_cam[..., 2]
# Project 3D points to NDC space.
fx, fy = focal_length
px, py = principal_point
x_ndc = -fx * x / z + px
y_ndc = -fy * y / z + py
# Convert from NDC space to image space.
x_im = np.int32((1 + x_ndc) * 0.5 * image_cols)
y_im = np.int32((1 - y_ndc) * 0.5 * image_rows)
# Draw xyz axis on the image.
origin = (x_im[0], y_im[0])
x_axis = (x_im[1], y_im[1])
y_axis = (x_im[2], y_im[2])
z_axis = (x_im[3], y_im[3])
image = cv2.arrowedLine(image, origin, x_axis, x_axis_drawing_spec.color,
x_axis_drawing_spec.thickness)
image = cv2.arrowedLine(image, origin, y_axis, y_axis_drawing_spec.color,
y_axis_drawing_spec.thickness)
image = cv2.arrowedLine(image, origin, z_axis, z_axis_drawing_spec.color,
z_axis_drawing_spec.thickness)