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 |