| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- #coding:utf-8
- import numpy as np
- from .matching import maxWeightMatching
- def compute_matching(dt_boxes, gt_boxes, bm_thr):
- assert dt_boxes.shape[-1] > 3 and gt_boxes.shape[-1] > 3
- if dt_boxes.shape[0] < 1 or gt_boxes.shape[0] < 1:
- return list()
- N, K = dt_boxes.shape[0], gt_boxes.shape[0]
- ious = compute_iou_matrix(dt_boxes, gt_boxes)
- rows, cols = np.where(ious > bm_thr)
- bipartites = [(i + 1, j + N + 1, ious[i, j]) for (i, j) in zip(rows, cols)]
- mates = maxWeightMatching(bipartites)
- if len(mates) < 1:
- return list()
- rows = np.where(np.array(mates) > -1)[0]
- indices = np.where(rows < N + 1)[0]
- rows = rows[indices]
- cols = np.array([mates[i] for i in rows])
- matches = [(i-1, j - N - 1) for (i, j) in zip(rows, cols)]
- return matches
- def compute_head_body_matching(dt_body, dt_head, gt_body, gt_head, bm_thr):
- assert dt_body.shape[-1] > 3 and gt_body.shape[-1] > 3
- assert dt_head.shape[-1] > 3 and gt_head.shape[-1] > 3
- assert dt_body.shape[0] == dt_head.shape[0]
- assert gt_body.shape[0] == gt_head.shape[0]
- N, K = dt_body.shape[0], gt_body.shape[0]
- ious_body = compute_iou_matrix(dt_body, gt_body)
- ious_head = compute_iou_matrix(dt_head, gt_head)
- mask_body = ious_body > bm_thr
- mask_head = ious_head > bm_thr
- # only keep the both matches detections
- mask = np.array(mask_body) & np.array(mask_head)
- ious = np.zeros((N, K))
- ious[mask] = (ious_body[mask] + ious_head[mask]) / 2
- rows, cols = np.where(ious > bm_thr)
- bipartites = [(i + 1, j + N + 1, ious[i, j]) for (i, j) in zip(rows, cols)]
- mates = maxWeightMatching(bipartites)
- if len(mates) < 1:
- return list()
- rows = np.where(np.array(mates) > -1)[0]
- indices = np.where(rows < N + 1)[0]
- rows = rows[indices]
- cols = np.array([mates[i] for i in rows])
- matches = [(i-1, j - N - 1) for (i, j) in zip(rows, cols)]
- return matches
- def compute_multi_head_body_matching(dt_body, dt_head_0, dt_head_1, gt_body, gt_head, bm_thr):
- assert dt_body.shape[-1] > 3 and gt_body.shape[-1] > 3
- assert dt_head_0.shape[-1] > 3 and gt_head.shape[-1] > 3
- assert dt_head_1.shape[-1] > 3 and gt_head.shape[-1] > 3
- assert dt_body.shape[0] == dt_head_0.shape[0]
- assert gt_body.shape[0] == gt_head.shape[0]
- N, K = dt_body.shape[0], gt_body.shape[0]
- ious_body = compute_iou_matrix(dt_body, gt_body)
- ious_head_0 = compute_iou_matrix(dt_head_0, gt_head)
- ious_head_1 = compute_iou_matrix(dt_head_1, gt_head)
- mask_body = ious_body > bm_thr
- mask_head_0 = ious_head_0 > bm_thr
- mask_head_1 = ious_head_1 > bm_thr
- mask_head = mask_head_0 | mask_head_1
- # only keep the both matches detections
- mask = np.array(mask_body) & np.array(mask_head)
- ious = np.zeros((N, K))
- #ious[mask] = (ious_body[mask] + ious_head[mask]) / 2
- ious[mask] = ious_body[mask]
- rows, cols = np.where(ious > bm_thr)
- bipartites = [(i + 1, j + N + 1, ious[i, j]) for (i, j) in zip(rows, cols)]
- mates = maxWeightMatching(bipartites)
- if len(mates) < 1:
- return list()
- rows = np.where(np.array(mates) > -1)[0]
- indices = np.where(rows < N + 1)[0]
- rows = rows[indices]
- cols = np.array([mates[i] for i in rows])
- matches = [(i-1, j - N - 1) for (i, j) in zip(rows, cols)]
- return matches
- def get_head_body_ignores(dt_body, dt_head, gt_body, gt_head, bm_thr):
- if gt_body.size:
- body_ioas = compute_ioa_matrix(dt_body, gt_body)
- head_ioas = compute_ioa_matrix(dt_head, gt_head)
- body_ioas = np.max(body_ioas, axis=1)
- head_ioas = np.max(head_ioas, axis=1)
- head_rows = np.where(head_ioas > bm_thr)[0]
- body_rows = np.where(body_ioas > bm_thr)[0]
- rows = set.union(set(head_rows), set(body_rows))
- return len(rows)
- else:
- return 0
- def get_ignores(dt_boxes, gt_boxes, bm_thr):
- if gt_boxes.size:
- ioas = compute_ioa_matrix(dt_boxes, gt_boxes)
- ioas = np.max(ioas, axis = 1)
- rows = np.where(ioas > bm_thr)[0]
- return len(rows)
- else:
- return 0
- def compute_ioa_matrix(dboxes: np.ndarray, gboxes: np.ndarray):
- eps = 1e-6
- assert dboxes.shape[-1] >= 4 and gboxes.shape[-1] >= 4
- N, K = dboxes.shape[0], gboxes.shape[0]
- dtboxes = np.tile(np.expand_dims(dboxes, axis = 1), (1, K, 1))
- gtboxes = np.tile(np.expand_dims(gboxes, axis = 0), (N, 1, 1))
- iw = np.minimum(dtboxes[:,:,2], gtboxes[:,:,2]) - np.maximum(dtboxes[:,:,0], gtboxes[:,:,0])
- ih = np.minimum(dtboxes[:,:,3], gtboxes[:,:,3]) - np.maximum(dtboxes[:,:,1], gtboxes[:,:,1])
- inter = np.maximum(0, iw) * np.maximum(0, ih)
- dtarea = np.maximum(dtboxes[:,:,2] - dtboxes[:,:,0], 0) * np.maximum(dtboxes[:,:,3] - dtboxes[:,:,1], 0)
- ioas = inter / (dtarea + eps)
- return ioas
- def compute_iou_matrix(dboxes:np.ndarray, gboxes:np.ndarray):
- eps = 1e-6
- assert dboxes.shape[-1] >= 4 and gboxes.shape[-1] >= 4
- N, K = dboxes.shape[0], gboxes.shape[0]
- dtboxes = np.tile(np.expand_dims(dboxes, axis = 1), (1, K, 1))
- gtboxes = np.tile(np.expand_dims(gboxes, axis = 0), (N, 1, 1))
- iw = np.minimum(dtboxes[:,:,2], gtboxes[:,:,2]) - np.maximum(dtboxes[:,:,0], gtboxes[:,:,0])
- ih = np.minimum(dtboxes[:,:,3], gtboxes[:,:,3]) - np.maximum(dtboxes[:,:,1], gtboxes[:,:,1])
- inter = np.maximum(0, iw) * np.maximum(0, ih)
- dtarea = (dtboxes[:,:,2] - dtboxes[:,:,0]) * (dtboxes[:,:,3] - dtboxes[:,:,1])
- gtarea = (gtboxes[:,:,2] - gtboxes[:,:,0]) * (gtboxes[:,:,3] - gtboxes[:,:,1])
- ious = inter / (dtarea + gtarea - inter + eps)
- return ious
|