| """ |
| Non-Maximum Suppression for video proposals. |
| """ |
|
|
|
|
| def compute_temporal_iou(pred, gt): |
| """ deprecated due to performance concerns |
| compute intersection-over-union along temporal axis |
| Args: |
| pred: [st (float), ed (float)] |
| gt: [st (float), ed (float)] |
| Returns: |
| iou (float): |
| |
| Ref: https://github.com/LisaAnne/LocalizingMoments/blob/master/utils/eval.py |
| """ |
| intersection = max(0, min(pred[1], gt[1]) - max(pred[0], gt[0])) |
| union = max(pred[1], gt[1]) - min(pred[0], gt[0]) |
| if union == 0: |
| return 0 |
| else: |
| return 1.0 * intersection / union |
|
|
|
|
| def temporal_non_maximum_suppression(predictions, nms_threshold, max_after_nms=100): |
| """ |
| Args: |
| predictions: list(sublist), each sublist is [st (float), ed(float), score (float)], |
| note larger scores are better and are preserved. For metrics that are better when smaller, |
| please convert to its negative, e.g., convert distance to negative distance. |
| nms_threshold: float in [0, 1] |
| max_after_nms: |
| Returns: |
| predictions_after_nms: list(sublist), each sublist is [st (float), ed(float), score (float)] |
| References: |
| https://github.com/wzmsltw/BSN-boundary-sensitive-network/blob/7b101fc5978802aa3c95ba5779eb54151c6173c6/Post_processing.py#L42 |
| """ |
| if len(predictions) == 1: |
| return predictions |
|
|
| predictions = sorted(predictions, key=lambda x: x[2], reverse=True) |
|
|
| tstart = [e[0] for e in predictions] |
| tend = [e[1] for e in predictions] |
| tscore = [e[2] for e in predictions] |
| rstart = [] |
| rend = [] |
| rscore = [] |
| while len(tstart) > 1 and len(rscore) < max_after_nms: |
| idx = 1 |
| while idx < len(tstart): |
| if compute_temporal_iou([tstart[0], tend[0]], [tstart[idx], tend[idx]]) > nms_threshold: |
| |
| tstart.pop(idx) |
| tend.pop(idx) |
| tscore.pop(idx) |
| |
| |
| |
| |
| else: |
| |
| idx += 1 |
| rstart.append(tstart.pop(0)) |
| rend.append(tend.pop(0)) |
| rscore.append(tscore.pop(0)) |
|
|
| if len(rscore) < max_after_nms and len(tstart) >= 1: |
| rstart.append(tstart.pop(0)) |
| rend.append(tend.pop(0)) |
| rscore.append(tscore.pop(0)) |
|
|
| predictions_after_nms = [[st, ed, s] for s, st, ed in zip(rscore, rstart, rend)] |
| return predictions_after_nms |
|
|