Spaces:
Running
on
Zero
Running
on
Zero
import numpy as np | |
def find_min_padding_exact(bbox, kpts, aspect_ratio=3/4, bbox_format='xywh'): | |
'''Find the minimum padding to make keypoint inside bbox''' | |
assert bbox_format.lower() in ['xywh', 'xyxy'], f"Invalid bbox format {bbox_format}. Only 'xyxy' or 'xywh' are supported." | |
if kpts.size % 2 == 0: | |
kpts = kpts.reshape(-1, 2) | |
vis = np.ones(kpts.shape[0]) | |
elif kpts.size % 3 == 0: | |
kpts = kpts.reshape(-1, 3) | |
vis = kpts[:, 2].flatten() | |
kpts = kpts[:, :2] | |
else: | |
raise ValueError('Keypoints should have 2 or 3 values each') | |
if bbox_format.lower() == 'xyxy': | |
bbox = np.array([ | |
bbox[0], | |
bbox[1], | |
bbox[2] - bbox[0], | |
bbox[3] - bbox[1], | |
]) | |
if aspect_ratio is not None: | |
# Fix the aspect ratio of the bounding box | |
bbox = fix_bbox_aspect_ratio(bbox, aspect_ratio=aspect_ratio, padding=1.0, bbox_format='xywh') | |
x0, y0, w, h = np.hsplit(bbox, [1, 2, 3]) | |
x1 = x0 + w | |
y1 = y0 + h | |
x_bbox_distances = np.max(np.stack([ | |
np.clip(x0 - kpts[:, 0], a_min=0, a_max=None), | |
np.clip(kpts[:, 0] - x1, a_min=0, a_max=None), | |
]), axis=0) | |
y_bbox_distances = np.max(np.stack([ | |
np.clip(y0 - kpts[:, 1], a_min=0, a_max=None), | |
np.clip(kpts[:, 1] - y1, a_min=0, a_max=None), | |
]), axis=0) | |
padding_x = 2 * x_bbox_distances / w | |
padding_y = 2 * y_bbox_distances / h | |
padding = 1 + np.maximum(padding_x, padding_y) | |
padding = np.array(padding).flatten() | |
padding[vis <= 0] = -1.0 | |
return padding | |
def fix_bbox_aspect_ratio(bbox, aspect_ratio=3/4, padding=1.25, bbox_format='xywh'): | |
assert bbox_format.lower() in ['xywh', 'xyxy'], f"Invalid bbox format {bbox_format}. Only 'xyxy' or 'xywh' are supported." | |
in_shape = bbox.shape | |
bbox = bbox.reshape((-1, 4)) | |
if bbox_format.lower() == 'xywh': | |
bbox_xyxy = np.array([ | |
bbox[:, 0], | |
bbox[:, 1], | |
bbox[:, 0] + bbox[:, 2], | |
bbox[:, 1] + bbox[:, 3], | |
]).T | |
else: | |
bbox_xyxy = np.array(bbox) | |
centers = bbox_xyxy[:, :2] + (bbox_xyxy[:, 2:] - bbox_xyxy[:, :2]) / 2 | |
widths = bbox_xyxy[:, 2] - bbox_xyxy[:, 0] | |
heights = bbox_xyxy[:, 3] - bbox_xyxy[:, 1] | |
new_widths = widths.copy().astype(np.float32) | |
new_heights = heights.copy().astype(np.float32) | |
for i in range(bbox_xyxy.shape[0]): | |
if widths[i] == 0: | |
widths[i] =+ 1 | |
if heights[i] == 0: | |
heights[i] =+ 1 | |
if widths[i] / heights[i] > aspect_ratio: | |
new_heights[i] = widths[i] / aspect_ratio | |
else: | |
new_widths[i] = heights[i] * aspect_ratio | |
new_widths *= padding | |
new_heights *= padding | |
new_bbox_xyxy = np.array([ | |
centers[:, 0] - new_widths / 2, | |
centers[:, 1] - new_heights / 2, | |
centers[:, 0] + new_widths / 2, | |
centers[:, 1] + new_heights / 2, | |
]).T | |
if bbox_format.lower() == 'xywh': | |
new_bbox = np.array([ | |
new_bbox_xyxy[:, 0], | |
new_bbox_xyxy[:, 1], | |
new_bbox_xyxy[:, 2] - new_bbox_xyxy[:, 0], | |
new_bbox_xyxy[:, 3] - new_bbox_xyxy[:, 1], | |
]).T | |
else: | |
new_bbox = new_bbox_xyxy | |
new_bbox = new_bbox.reshape(in_shape) | |
return new_bbox |