|
""" |
|
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 |
|
|