Spaces:
Runtime error
Runtime error
| # -------------------------------------------------------- | |
| # SiamMask | |
| # Licensed under The MIT License | |
| # Written by Qiang Wang (wangqiang2015 at ia.ac.cn) | |
| # -------------------------------------------------------- | |
| import numpy as np | |
| from collections import namedtuple | |
| Corner = namedtuple('Corner', 'x1 y1 x2 y2') | |
| BBox = Corner | |
| Center = namedtuple('Center', 'x y w h') | |
| def corner2center(corner): | |
| """ | |
| :param corner: Corner or np.array 4*N | |
| :return: Center or 4 np.array N | |
| """ | |
| if isinstance(corner, Corner): | |
| x1, y1, x2, y2 = corner | |
| return Center((x1 + x2) * 0.5, (y1 + y2) * 0.5, (x2 - x1), (y2 - y1)) | |
| else: | |
| x1, y1, x2, y2 = corner[0], corner[1], corner[2], corner[3] | |
| x = (x1 + x2) * 0.5 | |
| y = (y1 + y2) * 0.5 | |
| w = x2 - x1 | |
| h = y2 - y1 | |
| return x, y, w, h | |
| def center2corner(center): | |
| """ | |
| :param center: Center or np.array 4*N | |
| :return: Corner or np.array 4*N | |
| """ | |
| if isinstance(center, Center): | |
| x, y, w, h = center | |
| return Corner(x - w * 0.5, y - h * 0.5, x + w * 0.5, y + h * 0.5) | |
| else: | |
| x, y, w, h = center[0], center[1], center[2], center[3] | |
| x1 = x - w * 0.5 | |
| y1 = y - h * 0.5 | |
| x2 = x + w * 0.5 | |
| y2 = y + h * 0.5 | |
| return x1, y1, x2, y2 | |
| def cxy_wh_2_rect(pos, sz): | |
| return np.array([pos[0]-sz[0]/2, pos[1]-sz[1]/2, sz[0], sz[1]]) # 0-index | |
| def get_axis_aligned_bbox(region): | |
| nv = region.size | |
| if nv == 8: | |
| cx = np.mean(region[0::2]) | |
| cy = np.mean(region[1::2]) | |
| x1 = min(region[0::2]) | |
| x2 = max(region[0::2]) | |
| y1 = min(region[1::2]) | |
| y2 = max(region[1::2]) | |
| A1 = np.linalg.norm(region[0:2] - region[2:4]) * np.linalg.norm(region[2:4] - region[4:6]) | |
| A2 = (x2 - x1) * (y2 - y1) | |
| s = np.sqrt(A1 / A2) | |
| w = s * (x2 - x1) + 1 | |
| h = s * (y2 - y1) + 1 | |
| else: | |
| x = region[0] | |
| y = region[1] | |
| w = region[2] | |
| h = region[3] | |
| cx = x+w/2 | |
| cy = y+h/2 | |
| return cx, cy, w, h | |
| def aug_apply(bbox, param, shape, inv=False, rd=False): | |
| """ | |
| apply augmentation | |
| :param bbox: original bbox in image | |
| :param param: augmentation param, shift/scale | |
| :param shape: image shape, h, w, (c) | |
| :param inv: inverse | |
| :param rd: round bbox | |
| :return: bbox(, param) | |
| bbox: augmented bbox | |
| param: real augmentation param | |
| """ | |
| if not inv: | |
| center = corner2center(bbox) | |
| original_center = center | |
| real_param = {} | |
| if 'scale' in param: | |
| scale_x, scale_y = param['scale'] | |
| imh, imw = shape[:2] | |
| h, w = center.h, center.w | |
| scale_x = min(scale_x, float(imw) / w) | |
| scale_y = min(scale_y, float(imh) / h) | |
| # center.w *= scale_x | |
| # center.h *= scale_y | |
| center = Center(center.x, center.y, center.w * scale_x, center.h * scale_y) | |
| bbox = center2corner(center) | |
| if 'shift' in param: | |
| tx, ty = param['shift'] | |
| x1, y1, x2, y2 = bbox | |
| imh, imw = shape[:2] | |
| tx = max(-x1, min(imw - 1 - x2, tx)) | |
| ty = max(-y1, min(imh - 1 - y2, ty)) | |
| bbox = Corner(x1 + tx, y1 + ty, x2 + tx, y2 + ty) | |
| if rd: | |
| bbox = Corner(*map(round, bbox)) | |
| current_center = corner2center(bbox) | |
| real_param['scale'] = current_center.w / original_center.w, current_center.h / original_center.h | |
| real_param['shift'] = current_center.x - original_center.x, current_center.y - original_center.y | |
| return bbox, real_param | |
| else: | |
| if 'scale' in param: | |
| scale_x, scale_y = param['scale'] | |
| else: | |
| scale_x, scale_y = 1., 1. | |
| if 'shift' in param: | |
| tx, ty = param['shift'] | |
| else: | |
| tx, ty = 0, 0 | |
| center = corner2center(bbox) | |
| center = Center(center.x - tx, center.y - ty, center.w / scale_x, center.h / scale_y) | |
| return center2corner(center) | |
| def IoU(rect1, rect2): | |
| # overlap | |
| x1, y1, x2, y2 = rect1[0], rect1[1], rect1[2], rect1[3] | |
| tx1, ty1, tx2, ty2 = rect2[0], rect2[1], rect2[2], rect2[3] | |
| xx1 = np.maximum(tx1, x1) | |
| yy1 = np.maximum(ty1, y1) | |
| xx2 = np.minimum(tx2, x2) | |
| yy2 = np.minimum(ty2, y2) | |
| ww = np.maximum(0, xx2 - xx1) | |
| hh = np.maximum(0, yy2 - yy1) | |
| area = (x2-x1) * (y2-y1) | |
| target_a = (tx2-tx1) * (ty2 - ty1) | |
| inter = ww * hh | |
| overlap = inter / (area + target_a - inter) | |
| return overlap | |