Spaces:
Sleeping
Sleeping
File size: 5,588 Bytes
95db528 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
import numpy as np
def convert_locations_to_boxes(locations, priors, center_variance, size_variance):
"""
Convert regression location results of SSD into boxes in the form of (center_x, center_y, h, w).
Parameters
----------
locations: numpy.ndarray
Regression location results, sized [num_priors,4].
priors: numpy.ndarray
Prior boxes in center-offset form, sized [num_priors,4].
center_variance: float
The center variance for decoding.
size_variance: float
The size variance for decoding.
Returns
-------
boxes: numpy.ndarray
Boxes in corner form, sized [num_priors,4].
"""
# priors can have one dimension less.
if len(priors.shape) + 1 == len(locations.shape):
priors = np.expand_dims(priors, 0)
return np.concatenate(
[
locations[..., :2] * center_variance * priors[..., 2:] + priors[..., :2],
np.exp(locations[..., 2:] * size_variance) * priors[..., 2:],
],
axis=len(locations.shape) - 1,
)
def convert_boxes_to_locations(center_form_boxes, center_form_priors, center_variance, size_variance):
"""
Convert boxes to locations with respect to priors, which are encoded as (cx, cy, w, h).
Parameters
----------
center_form_boxes: numpy.ndarray
Boxes to be converted to locations, sized [num_priors,4].
center_form_priors: numpy.ndarray
Prior boxes in center-form, sized [num_priors,4].
center_variance: float
The center variance for encoding.
size_variance: float
The size variance for encoding.
Returns
-------
locations: numpy.ndarray
Encoded locations, sized [num_priors,4].
"""
if len(center_form_priors.shape) + 1 == len(center_form_boxes.shape):
center_form_priors = np.expand_dims(center_form_priors, 0)
return np.concatenate(
[
(center_form_boxes[..., :2] - center_form_priors[..., :2]) / center_form_priors[..., 2:] / center_variance,
np.log(center_form_boxes[..., 2:] / center_form_priors[..., 2:]) / size_variance,
],
axis=len(center_form_boxes.shape) - 1,
)
def area_of(left_top, right_bottom):
"""
Compute the areas of rectangles given two corners.
Parameters
----------
left_top: numpy.ndarray
Left top corner of the rectangles, sized [N,2].
right_bottom: numpy.ndarray
Right bottom corner of the rectangles, sized [N,2].
Returns
-------
area: numpy.ndarray
Computed areas, sized [N,].
"""
hw = np.clip(right_bottom - left_top, 0.0, None)
return hw[..., 0] * hw[..., 1]
def iou_of(boxes0, boxes1, eps=1e-5):
"""Return intersection-over-union (Jaccard index) of boxes.
Args:
boxes0 (N, 4): ground truth boxes.
boxes1 (N or 1, 4): predicted boxes.
eps: a small number to avoid 0 as denominator.
Returns:
iou (N): IoU values.
"""
overlap_left_top = np.maximum(boxes0[..., :2], boxes1[..., :2])
overlap_right_bottom = np.minimum(boxes0[..., 2:], boxes1[..., 2:])
overlap_area = area_of(overlap_left_top, overlap_right_bottom)
area0 = area_of(boxes0[..., :2], boxes0[..., 2:])
area1 = area_of(boxes1[..., :2], boxes1[..., 2:])
return overlap_area / (area0 + area1 - overlap_area + eps)
def center_form_to_corner_form(locations):
"""
Convert center-form boxes to corner-form.
Parameters
----------
locations: numpy.ndarray
Center-form boxes to be converted to corner-form, sized [num_priors,4].
Returns
-------
boxes: numpy.ndarray
Corner-form boxes, sized [num_priors,4].
"""
return np.concatenate(
[locations[..., :2] - locations[..., 2:] / 2, locations[..., :2] + locations[..., 2:] / 2],
len(locations.shape) - 1,
)
def corner_form_to_center_form(boxes):
"""
Convert corner-form boxes to center-form.
Parameters
----------
boxes: numpy.ndarray
Corner-form boxes to be converted to center-form, sized [num_priors,4].
Returns
-------
locations: numpy.ndarray
Center-form boxes, sized [num_priors,4].
"""
return np.concatenate(
[(boxes[..., :2] + boxes[..., 2:]) / 2, boxes[..., 2:] - boxes[..., :2]], len(boxes.shape) - 1
)
def hard_nms(box_scores, iou_threshold, top_k=-1, candidate_size=200):
"""
Perform hard non-maximum-supression to filter out boxes with iou greater
than threshold
Parameters
----------
box_scores: numpy.ndarray
boxes in corner-form and probabilities.
iou_threshold: float
intersection over union threshold.
top_k: int
keep top_k results. If k <= 0, keep all the results.
candidate_size: int
only consider the candidates with the highest scores.
Returns
-------
picked: numpy.ndarray
a list of indexes of the kept boxes
"""
scores = box_scores[:, -1]
boxes = box_scores[:, :-1]
picked = []
indexes = np.argsort(scores)
indexes = indexes[-candidate_size:]
while len(indexes) > 0:
current = indexes[-1]
picked.append(current)
if 0 < top_k == len(picked) or len(indexes) == 1:
break
current_box = boxes[current, :]
indexes = indexes[:-1]
rest_boxes = boxes[indexes, :]
iou = iou_of(
rest_boxes,
np.expand_dims(current_box, axis=0),
)
indexes = indexes[iou <= iou_threshold]
return box_scores[picked, :]
|