oguzakif's picture
init repo
d4b77ac
# --------------------------------------------------------
# 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