Iou 的計算
我們先考慮一維的情況:令 \(A = [x_1,x_2], B = [y_1, y_2]\),若想要 \(A\) 與 \(B\) 有交集,需要滿足如下情況:
簡言之,要保證 \(A\) 和 \(B\) 的最大值中最小的那個減去它們中的最小值中最大的那個即可獲得公共部分,代碼實現如下:
class Anchor:
def __init__(self, base_size=16):
self.base_size = base_size # 滑動窗口的大小
if not base_size:
raise ValueError("Invalid base_size: {}.".format(base_size))
self._anchor = np.array([1, 1, self.base_size, self.base_size]) - 1
@property
def anchor(self):
return self._anchor
@anchor.setter
def anchor(self, new_anchor):
self._anchor = new_anchor
@property
def w(self):
'''
錨框的寬度
'''
return self.anchor[2] - self.anchor[0] + 1
@property
def h(self):
'''
錨框的高度
'''
return self.anchor[3] - self.anchor[1] + 1
@property
def size(self):
'''
錨框的面積
'''
return self.w * self.h
@property
def _whctrs(self):
"""
Return x center, and y center for an anchor (window). 錨框的中心坐標
"""
x_ctr = self.anchor[0] + 0.5 * (self.w - 1)
y_ctr = self.anchor[1] + 0.5 * (self.h - 1)
return np.array([x_ctr, y_ctr])
@staticmethod
def _coordinate(aspect, ctr):
'''
依據寬高組合計算錨框的坐標
'''
k = (aspect - 1) / 2
return np.concatenate([ctr - k, ctr + k], axis=1)
先創建一個可以用來做運算的計算器,然后在此基礎上計算二維的 IoU,即
def iou(anchor, anchor1):
A = Anchor()
B = Anchor()
A.anchor = anchor
B.anchor = anchor1
T = np.stack([A.anchor, B.anchor])
xmin, ymin, xmax, ymax = np.split(T, 4, axis=1)
w = xmax.min() - xmin.max()
h = ymax.min() - ymin.max()
I = w * h
U = A.size + B.size - I
return I / U
下面舉一例子,並可視化:
img = np.ones((128 ,300, 3)) # 圖片
anchor = [ 12., 8., 195., 103.]
anchor1 = [ 28., 8., 211., 103.]
iou(anchor, anchor1)
最終結果為:
0.8151364126804707