alfred / gen /utils /bb_util.py
ch-min-ys's picture
delete ff_planner
483f96c
import numbers
import numpy as np
LIMIT = 99999999
def clip_bbox(bboxes, min_clip, max_x_clip, max_y_clip):
'''
# BBoxes are [x1, y1, x2, y2]
'''
bboxes_out = bboxes
added_axis = False
if len(bboxes_out.shape) == 1:
added_axis = True
bboxes_out = bboxes_out[:, np.newaxis]
bboxes_out[[0, 2], ...] = np.clip(bboxes_out[[0, 2], ...], min_clip, max_x_clip)
bboxes_out[[1, 3], ...] = np.clip(bboxes_out[[1, 3], ...], min_clip, max_y_clip)
if added_axis:
bboxes_out = bboxes_out[:, 0]
return bboxes_out
def xyxy_to_xywh(bboxes, clip_min=-LIMIT, clip_width=LIMIT, clip_height=LIMIT, round=False):
'''
[x1 y1, x2, y2] to [xMid, yMid, width, height]
'''
added_axis = False
if isinstance(bboxes, list):
bboxes = np.array(bboxes).astype(np.float32)
if len(bboxes.shape) == 1:
added_axis = True
bboxes = bboxes[:, np.newaxis]
bboxes_out = np.zeros(bboxes.shape)
x1 = bboxes[0, ...]
y1 = bboxes[1, ...]
x2 = bboxes[2, ...]
y2 = bboxes[3, ...]
bboxes_out[0, ...] = (x1 + x2) / 2.0
bboxes_out[1, ...] = (y1 + y2) / 2.0
bboxes_out[2, ...] = x2 - x1
bboxes_out[3, ...] = y2 - y1
if clip_min != -LIMIT or clip_width != LIMIT or clip_height != LIMIT:
bboxes_out = clip_bbox(bboxes_out, clip_min, clip_width, clip_height)
if bboxes_out.shape[0] > 4:
bboxes_out[4:, ...] = bboxes[4:, ...]
if added_axis:
bboxes_out = bboxes_out[:, 0]
if round:
bboxes_out = np.round(bboxes_out).astype(int)
return bboxes_out
def xywh_to_xyxy(bboxes, clip_min=-LIMIT, clip_width=LIMIT, clip_height=LIMIT, round=False):
'''
[xMid, yMid, width, height] to [x1 y1, x2, y2]
'''
added_axis = False
if isinstance(bboxes, list):
bboxes = np.array(bboxes).astype(np.float32)
if len(bboxes.shape) == 1:
added_axis = True
bboxes = bboxes[:, np.newaxis]
bboxes_out = np.zeros(bboxes.shape)
x_mid = bboxes[0, ...]
y_mid = bboxes[1, ...]
width = bboxes[2, ...]
height = bboxes[3, ...]
bboxes_out[0, ...] = x_mid - width / 2.0
bboxes_out[1, ...] = y_mid - height / 2.0
bboxes_out[2, ...] = x_mid + width / 2.0
bboxes_out[3, ...] = y_mid + height / 2.0
if clip_min != -LIMIT or clip_width != LIMIT or clip_height != LIMIT:
bboxes_out = clip_bbox(bboxes_out, clip_min, clip_width, clip_height)
if bboxes_out.shape[0] > 4:
bboxes_out[4:, ...] = bboxes[4:, ...]
if added_axis:
bboxes_out = bboxes_out[:, 0]
if round:
bboxes_out = np.round(bboxes_out).astype(int)
return bboxes_out
def scale_bbox(bboxes, scalars, clip_min=-LIMIT, clip_width=LIMIT, clip_height=LIMIT, round=False, in_place=False):
'''
@bboxes {np.array} 4xn array of boxes to be scaled
@scalars{number or arraylike} scalars for width and height of boxes
@in_place{bool} If false, creates new bboxes.
'''
added_axis = False
if isinstance(bboxes, list):
bboxes = np.array(bboxes, dtype=np.float32)
if len(bboxes.shape) == 1:
added_axis = True
bboxes = bboxes[:, np.newaxis]
if isinstance(scalars, numbers.Number):
scalars = np.full((2, bboxes.shape[1]), scalars, dtype=np.float32)
if not isinstance(scalars, np.ndarray):
scalars = np.array(scalars, dtype=np.float32)
if len(scalars.shape) == 1:
scalars = np.tile(scalars[:, np.newaxis], (1, bboxes.shape[1]))
width = bboxes[2, ...] - bboxes[0, ...]
height = bboxes[3, ...] - bboxes[1, ...]
x_mid = (bboxes[0, ...] + bboxes[2, ...]) / 2.0
y_mid = (bboxes[1, ...] + bboxes[3, ...]) / 2.0
if not in_place:
bboxes_out = bboxes.copy()
else:
bboxes_out = bboxes
bboxes_out[0, ...] = x_mid - width * scalars[0, ...] / 2.0
bboxes_out[1, ...] = y_mid - height * scalars[1, ...] / 2.0
bboxes_out[2, ...] = x_mid + width * scalars[0, ...] / 2.0
bboxes_out[3, ...] = y_mid + height * scalars[1, ...] / 2.0
if clip_min != -LIMIT or clip_width != LIMIT or clip_height != LIMIT:
bboxes_out = clip_bbox(bboxes_out, clip_min, clip_width, clip_height)
if added_axis:
bboxes_out = bboxes_out[:, 0]
if round:
bboxes_out = np.round(bboxes_out).astype(int)
return bboxes_out
def make_square(bboxes, in_place=False):
if isinstance(bboxes, list):
bboxes = np.array(bboxes).astype(np.float32)
if len(bboxes.shape) == 1:
num_boxes = 1
width = bboxes[2] - bboxes[0]
height = bboxes[3] - bboxes[1]
else:
num_boxes = bboxes.shape[1]
width = bboxes[2, ...] - bboxes[0, ...]
height = bboxes[3, ...] - bboxes[1, ...]
max_size = np.maximum(width, height)
scalars = np.zeros((2, num_boxes))
scalars[0, ...] = max_size * 1.0 / width
scalars[1, ...] = max_size * 1.0 / height
return scale_bbox(bboxes, scalars, in_place=in_place)