1.IOU计算:
先验框表示方式变换:
(cx, cy, w, h) to (xmin, ymin, xmax, ymax):
def point_form(boxes):
""" Convert prior_boxes to (xmin, ymin, xmax, ymax)
representation for comparison to point form ground truth data.
Args:
boxes: (tensor) center-size default boxes from priorbox layers.
Return:
boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes.
"""
return torch.cat((boxes[:, :2] - boxes[:, 2:]/2, # xmin, ymin
boxes[:, :2] + boxes[:, 2:]/2), 1) # xmax, ymax
boxes[:, :2] = cx, cy
boxes[:, 2:] = w, h
通过上图可知,xmin = cx - w/2, ymin = cy - h/2, xmax = cx + w/2, ymax = cy + h/2.
(xmin, ymin, xmax, ymax) to (cx, cy, w, h):
def center_size(boxes):
""" Convert prior_boxes to (cx, cy, w, h)
representation for comparison to center-size form ground truth data.
Args:
boxes: (tensor) point_form boxes
Return:
boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes.
"""
return torch.cat((boxes[:, 2:] + boxes[:, :2])/2, # cx, cy
boxes[:, 2:] - boxes[:, :2], 1) # w, h
boxes[:, 2:] = xmax, ymax
boxes[:, :2] = xmin, ymin
仍然由上图可知,cx = (xmax - xmin)/2 + xmin = (xmax + xmin)/2, cy = (ymax - ymin)/2 + ymin = (ymax + ymin)/2, w = xmax - xmin, h = ymax - ymin.
prior box 和 ground truth box之间的交集计算:
def intersect(box_a, box_b):
""" We resize both tensors to [A,B,2] without new malloc:
[A,2] -> [A,1,2] -> [A,B,2]
[B,2] -> [1,B,2] -> [A,B,2]
Then we compute the area of intersect between box_a and box_b.
Args:
box_a: (tensor) bounding boxes, Shape: [A,4].
box_b: (tensor) bounding boxes, Shape: [B,4].
Return:
(tensor) intersection area, Shape: [A,B].
"""
A = box_a.size(0)
B = box_b.size(0)
max_xy = torch.min(box_a[:, 2:].unsqueeze(1).expand(A, B, 2),
box_b[:, 2:].unsqueeze(0).expand(A, B, 2))
min_xy = torch.max(box_a[:, :2].unsqueeze(1).expand(A, B, 2),
box_b[:, :2].unsqueeze(0).expand(A, B, 2))
inter = torch.clamp((max_xy - min_xy), min=0)
return inter[:, :, 0] * inter[:, :, 1]
box_a 和 box_b形如(xmin, ymin, xmax, ymax)
max_xy得到的是点A,min_xy得到的是点B’,二者相减得到的是相交区域的宽和高,相乘即得面积。
并集区域计算:
A∪B = SA + SB - A∩B (SA指A的面积,SB指B的面积)
def jaccard(box_a, box_b):
"""Compute the jaccard overlap of two sets of boxes. The jaccard overlap
is simply the intersection over union of two boxes. Here we operate on
ground truth boxes and default boxes.
E.g.:
A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B)
Args:
box_a: (tensor) Ground truth bounding boxes, Shape: [num_objects,4]
box_b: (tensor) Prior boxes from priorbox layers, Shape: [num_priors,4]
Return:
jaccard overlap: (tensor) Shape: [box_a.size(0), box_b.size(0)]
"""
inter = intersect(box_a, box_b)
area_a = ((box_a[:, 2]-box_a[:, 0]) *
(box_a[:, 3]-box_a[:, 1])).unsqueeze(1).expand_as(inter) # [A,B]
area_b = ((box_b[:, 2]-box_b[:, 0]) *
(box_b[:, 3]-box_b[:, 1])).unsqueeze(0).expand_as(inter) # [A,B]
union = area_a + area_b - inter
return inter / union # [A,B]
box_a和box_b形如:(xmin, ymin, xmax, ymax)
SA = (xmax - xmin) * (ymax - ymin)
SB = (xmax - xmin) * (ymax - ymin)
交集面积等于inter
IOU = inter / (SA + SB - inter)