File size: 4,562 Bytes
d4b77ac |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# --------------------------------------------------------
# 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
|