说明一下问题:目标追踪代码里往往用到cython_bbox中的bbox_ious。但是该库需要用到 VC++,按照有些麻烦。于是采用直接替换该方法,用纯代码实现,无需调用库。
File “src\cython_bbox.pyx”, line 17, in cython_bbox.bbox_overlaps
ValueError: Buffer dtype mismatch, expected ‘DTYPE_t’ but got ‘float’
代码来源:
PaddleDetection-release-2.7\build\lib\ppdet\data\transform\atss_assigner.py
def bbox_ious(bboxes1, bboxes2, mode='iou', is_aligned=False, eps=1e-6):"""Calculate overlap between two set of bboxes.If ``is_aligned `` is ``False``, then calculate the overlaps between eachbbox of bboxes1 and bboxes2, otherwise the overlaps between each alignedpair of bboxes1 and bboxes2.Args:bboxes1 (Tensor): shape (B, m, 4) in <x1, y1, x2, y2> format or empty.bboxes2 (Tensor): shape (B, n, 4) in <x1, y1, x2, y2> format or empty.B indicates the batch dim, in shape (B1, B2, ..., Bn).If ``is_aligned `` is ``True``, then m and n must be equal.mode (str): "iou" (intersection over union) or "iof" (intersection overforeground).is_aligned (bool, optional): If True, then m and n must be equal.Default False.eps (float, optional): A value added to the denominator for numericalstability. Default 1e-6.Returns:Tensor: shape (m, n) if ``is_aligned `` is False else shape (m,)"""assert mode in ['iou', 'iof', 'giou', 'diou'], 'Unsupported mode {}'.format(mode)# Either the boxes are empty or the length of boxes's last dimenstion is 4assert (bboxes1.shape[-1] == 4 or bboxes1.shape[0] == 0)assert (bboxes2.shape[-1] == 4 or bboxes2.shape[0] == 0)# Batch dim must be the same# Batch dim: (B1, B2, ... Bn)assert bboxes1.shape[:-2] == bboxes2.shape[:-2]batch_shape = bboxes1.shape[:-2]rows = bboxes1.shape[-2] if bboxes1.shape[0] > 0 else 0cols = bboxes2.shape[-2] if bboxes2.shape[0] > 0 else 0if is_aligned:assert rows == colsif rows * cols == 0:if is_aligned:return np.random.random(batch_shape + (rows, ))else:return np.random.random(batch_shape + (rows, cols))area1 = (bboxes1[..., 2] - bboxes1[..., 0]) * (bboxes1[..., 3] - bboxes1[..., 1])area2 = (bboxes2[..., 2] - bboxes2[..., 0]) * (bboxes2[..., 3] - bboxes2[..., 1])if is_aligned:lt = np.maximum(bboxes1[..., :2], bboxes2[..., :2]) # [B, rows, 2]rb = np.minimum(bboxes1[..., 2:], bboxes2[..., 2:]) # [B, rows, 2]wh = (rb - lt).clip(min=0) # [B, rows, 2]overlap = wh[..., 0] * wh[..., 1]if mode in ['iou', 'giou']:union = area1 + area2 - overlapelse:union = area1if mode == 'giou':enclosed_lt = np.minimum(bboxes1[..., :2], bboxes2[..., :2])enclosed_rb = np.maximum(bboxes1[..., 2:], bboxes2[..., 2:])if mode == 'diou':enclosed_lt = np.minimum(bboxes1[..., :2], bboxes2[..., :2])enclosed_rb = np.maximum(bboxes1[..., 2:], bboxes2[..., 2:])b1_x1, b1_y1 = bboxes1[..., 0], bboxes1[..., 1]b1_x2, b1_y2 = bboxes1[..., 2], bboxes1[..., 3]b2_x1, b2_y1 = bboxes2[..., 0], bboxes2[..., 1]b2_x2, b2_y2 = bboxes2[..., 2], bboxes2[..., 3]else:lt = np.maximum(bboxes1[..., :, None, :2],bboxes2[..., None, :, :2]) # [B, rows, cols, 2]rb = np.minimum(bboxes1[..., :, None, 2:],bboxes2[..., None, :, 2:]) # [B, rows, cols, 2]wh = (rb - lt).clip(min=0) # [B, rows, cols, 2]overlap = wh[..., 0] * wh[..., 1]if mode in ['iou', 'giou']:union = area1[..., None] + area2[..., None, :] - overlapelse:union = area1[..., None]if mode == 'giou':enclosed_lt = np.minimum(bboxes1[..., :, None, :2],bboxes2[..., None, :, :2])enclosed_rb = np.maximum(bboxes1[..., :, None, 2:],bboxes2[..., None, :, 2:])if mode == 'diou':enclosed_lt = np.minimum(bboxes1[..., :, None, :2],bboxes2[..., None, :, :2])enclosed_rb = np.maximum(bboxes1[..., :, None, 2:],bboxes2[..., None, :, 2:])b1_x1, b1_y1 = bboxes1[..., :, None, 0], bboxes1[..., :, None, 1]b1_x2, b1_y2 = bboxes1[..., :, None, 2], bboxes1[..., :, None, 3]b2_x1, b2_y1 = bboxes2[..., None, :, 0], bboxes2[..., None, :, 1]b2_x2, b2_y2 = bboxes2[..., None, :, 2], bboxes2[..., None, :, 3]eps = np.array([eps])union = np.maximum(union, eps)ious = overlap / unionif mode in ['iou', 'iof']:return ious# calculate giousif mode in ['giou']:enclose_wh = (enclosed_rb - enclosed_lt).clip(min=0)enclose_area = enclose_wh[..., 0] * enclose_wh[..., 1]enclose_area = np.maximum(enclose_area, eps)gious = ious - (enclose_area - union) / enclose_areareturn giousif mode in ['diou']:left = ((b2_x1 + b2_x2) - (b1_x1 + b1_x2))**2 / 4right = ((b2_y1 + b2_y2) - (b1_y1 + b1_y2))**2 / 4rho2 = left + rightenclose_wh = (enclosed_rb - enclosed_lt).clip(min=0)enclose_c = enclose_wh[..., 0]**2 + enclose_wh[..., 1]**2enclose_c = np.maximum(enclose_c, eps)dious = ious - rho2 / enclose_creturn dious