Spaces:
Sleeping
Sleeping
| 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, :] | |