-
-
Save fivejjs/c76fe74c682d82d727d9ee09568f74ec to your computer and use it in GitHub Desktop.
Object detector util: match a set of detected bounding boxes and a set of ground-truth bounding boxes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import division | |
import scipy.optimize | |
import numpy as np | |
def bbox_iou(boxA, boxB): | |
# https://www.pyimagesearch.com/2016/11/07/intersection-over-union-iou-for-object-detection/ | |
# ^^ corrected. | |
# Determine the (x, y)-coordinates of the intersection rectangle | |
xA = max(boxA[0], boxB[0]) | |
yA = max(boxA[1], boxB[1]) | |
xB = min(boxA[2], boxB[2]) | |
yB = min(boxA[3], boxB[3]) | |
interW = xB - xA + 1 | |
interH = yB - yA + 1 | |
# Correction: reject non-overlapping boxes | |
if interW <=0 or interH <=0 : | |
return -1.0 | |
interArea = interW * interH | |
boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1) | |
boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1) | |
iou = interArea / float(boxAArea + boxBArea - interArea) | |
return iou | |
def match_bboxes(bbox_gt, bbox_pred, IOU_THRESH=0.5): | |
''' | |
Given sets of true and predicted bounding-boxes, | |
determine the best possible match. | |
Parameters | |
---------- | |
bbox_gt, bbox_pred : N1x4 and N2x4 np array of bboxes [x1,y1,x2,y2]. | |
The number of bboxes, N1 and N2, need not be the same. | |
Returns | |
------- | |
(idxs_true, idxs_pred, ious, labels) | |
idxs_true, idxs_pred : indices into gt and pred for matches | |
ious : corresponding IOU value of each match | |
labels: vector of 0/1 values for the list of detections | |
''' | |
n_true = bbox_gt.shape[0] | |
n_pred = bbox_pred.shape[0] | |
MAX_DIST = 1.0 | |
MIN_IOU = 0.0 | |
# NUM_GT x NUM_PRED | |
iou_matrix = np.zeros((n_true, n_pred)) | |
for i in range(n_true): | |
for j in range(n_pred): | |
iou_matrix[i, j] = bbox_iou(bbox_gt[i,:], bbox_pred[j,:]) | |
if n_pred > n_true: | |
# there are more predictions than ground-truth - add dummy rows | |
diff = n_pred - n_true | |
iou_matrix = np.concatenate( (iou_matrix, | |
np.full((diff, n_pred), MIN_IOU)), | |
axis=0) | |
if n_true > n_pred: | |
# more ground-truth than predictions - add dummy columns | |
diff = n_true - n_pred | |
iou_matrix = np.concatenate( (iou_matrix, | |
np.full((n_true, diff), MIN_IOU)), | |
axis=1) | |
# call the Hungarian matching | |
idxs_true, idxs_pred = scipy.optimize.linear_sum_assignment(1 - iou_matrix) | |
if (not idxs_true.size) or (not idxs_pred.size): | |
ious = np.array([]) | |
else: | |
ious = iou_matrix[idxs_true, idxs_pred] | |
# remove dummy assignments | |
sel_pred = idxs_pred<n_pred | |
idx_pred_actual = idxs_pred[sel_pred] | |
idx_gt_actual = idxs_true[sel_pred] | |
ious_actual = iou_matrix[idx_gt_actual, idx_pred_actual] | |
sel_valid = (ious_actual > IOU_THRESH) | |
label = sel_valid.astype(int) | |
return idx_gt_actual[sel_valid], idx_pred_actual[sel_valid], ious_actual[sel_valid], label | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment