Source code for blocks.utils.rpn
from typing import Optional, List, Sequence
import numpy as np
from ..datasets import RPNDataset
__all__ = ['decode_rpn_predictions']
[docs]def decode_rpn_predictions(dataset: RPNDataset,
classifier_probabilities: np.ndarray,
regression_predictions: np.ndarray,
non_maximum_suppression: Optional[float]=0.3,
min_probability: Optional[float]=None,
top_k: Optional[int]=None) -> List[Sequence[float]]:
"""
Decode the given RPN predictions to a list of regions.
Optionally:
- use non maximum suppression
- filter out regions with low probability
- output only top k regions
:param dataset: RPN dataset which created the anchors
:param classifier_probabilities: predicted classifier probabilities (in 0-1 interval)
:param regression_predictions: predicted diffs regression values
:param non_maximum_suppression: if specified, use nms with the given threshold
:param min_probability: if specified, filter out regions with probability lower than the specified threshold
:param top_k: if specified, output only top k regions
:return: list of decoded regions
"""
predicted_labels = np.round(classifier_probabilities)
# obtain indices, probs and regions with applied diffs
positives_indices = np.argwhere(predicted_labels == 1)
positives_probs = [classifier_probabilities[tuple(ix)] for ix in positives_indices]
positive_regions = [dataset.apply_diff(dataset.get_anchor(ix), regression_predictions[tuple(ix)])
for ix in positives_indices]
# zip and sort the predictions by probs
positives = zip(positives_indices, positives_probs, positive_regions)
positives = sorted(positives, key=lambda t: t[1], reverse=True)
# non-maximum suppression
if non_maximum_suppression is not None:
ix = 0
while True:
if ix >= len(positives):
break
best = positives[ix][2]
positives = positives[:ix + 1] + [region for region in positives[ix + 1:]
if dataset.anchor_region_overlap(best, region[2]) < non_maximum_suppression]
ix += 1
# min_probability filtering
if min_probability is not None:
positives = [positive for positive in positives if positive[1] > min_probability]
# top-k filtering
if top_k is not None:
positives = positives[:top_k]
positive_regions = [positive[2] for positive in positives]
return positive_regions