# Copyright (c) OpenMMLab. All rights reserved. import numpy as np def temporal_iou(proposal_min, proposal_max, gt_min, gt_max): """Compute IoU score between a groundtruth bbox and the proposals. Args: proposal_min (list[float]): List of temporal anchor min. proposal_max (list[float]): List of temporal anchor max. gt_min (float): Groundtruth temporal box min. gt_max (float): Groundtruth temporal box max. Returns: list[float]: List of iou scores. """ len_anchors = proposal_max - proposal_min int_tmin = np.maximum(proposal_min, gt_min) int_tmax = np.minimum(proposal_max, gt_max) inter_len = np.maximum(int_tmax - int_tmin, 0.) union_len = len_anchors - inter_len + gt_max - gt_min jaccard = np.divide(inter_len, union_len) return jaccard def temporal_iop(proposal_min, proposal_max, gt_min, gt_max): """Compute IoP score between a groundtruth bbox and the proposals. Compute the IoP which is defined as the overlap ratio with groundtruth proportional to the duration of this proposal. Args: proposal_min (list[float]): List of temporal anchor min. proposal_max (list[float]): List of temporal anchor max. gt_min (float): Groundtruth temporal box min. gt_max (float): Groundtruth temporal box max. Returns: list[float]: List of intersection over anchor scores. """ len_anchors = np.array(proposal_max - proposal_min) int_tmin = np.maximum(proposal_min, gt_min) int_tmax = np.minimum(proposal_max, gt_max) inter_len = np.maximum(int_tmax - int_tmin, 0.) scores = np.divide(inter_len, len_anchors) return scores def soft_nms(proposals, alpha, low_threshold, high_threshold, top_k): """Soft NMS for temporal proposals. Args: proposals (np.ndarray): Proposals generated by network. alpha (float): Alpha value of Gaussian decaying function. low_threshold (float): Low threshold for soft nms. high_threshold (float): High threshold for soft nms. top_k (int): Top k values to be considered. Returns: np.ndarray: The updated proposals. """ proposals = proposals[proposals[:, -1].argsort()[::-1]] tstart = list(proposals[:, 0]) tend = list(proposals[:, 1]) tscore = list(proposals[:, -1]) rstart = [] rend = [] rscore = [] while len(tscore) > 0 and len(rscore) <= top_k: max_index = np.argmax(tscore) max_width = tend[max_index] - tstart[max_index] iou_list = temporal_iou(tstart[max_index], tend[max_index], np.array(tstart), np.array(tend)) iou_exp_list = np.exp(-np.square(iou_list) / alpha) for idx, _ in enumerate(tscore): if idx != max_index: current_iou = iou_list[idx] if current_iou > low_threshold + (high_threshold - low_threshold) * max_width: tscore[idx] = tscore[idx] * iou_exp_list[idx] rstart.append(tstart[max_index]) rend.append(tend[max_index]) rscore.append(tscore[max_index]) tstart.pop(max_index) tend.pop(max_index) tscore.pop(max_index) rstart = np.array(rstart).reshape(-1, 1) rend = np.array(rend).reshape(-1, 1) rscore = np.array(rscore).reshape(-1, 1) new_proposals = np.concatenate((rstart, rend, rscore), axis=1) return new_proposals