Skip to content

Instantly share code, notes, and snippets.

@AruniRC
Created February 22, 2018 16:10
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save AruniRC/c629c2df0e68e23aff7dcaeef87c72d4 to your computer and use it in GitHub Desktop.
Save AruniRC/c629c2df0e68e23aff7dcaeef87c72d4 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
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
@prachyboon
Copy link

Hi, Prof. I have a question in line73: scipy.optimize.linear_sum_assignment(1 - iou_matrix). how this line work for matching multiple bbs correctly. I am finding the method to compare iou of bounding boxes from 2 images and your method is work! however, I quite don't understand this line completly. kindly you explain/guide it.
2nd question, I am wondering on, can we compare 2 images which have different size as 1st image is the original one and 2nd is a crop from 1st image. if there are the bounding on 2 images can we compare iou matching among boxes.
(not sure but it should be work by normalized value like YOLO format).
Thx.

@C0NGTRI123
Copy link

Hi, Prof. I have a question in line73: scipy.optimize.linear_sum_assignment(1 - iou_matrix). how this line work for matching multiple bbs correctly. I am finding the method to compare iou of bounding boxes from 2 images and your method is work! however, I quite don't understand this line completly. kindly you explain/guide it. 2nd question, I am wondering on, can we compare 2 images which have different size as 1st image is the original one and 2nd is a crop from 1st image. if there are the bounding on 2 images can we compare iou matching among boxes. (not sure but it should be work by normalized value like YOLO format). Thx.

1nd question. You should read carefully a Hungarian algorithm, this algorithm to calculate min cost pair, in here they will calculate min cost predict and ground truth. And when to use scipy.optimize.linear_sum_assignment(1 - iou_matrix) it think if iou is approximate 0, they become to approximate 1 and opposite if iou is big, they become to approximate small. And this is conditional for problem to find scipy.optimize.linear_sum_assignment(1 - iou_matrix) min and deduce iou max
2nd question. I'm thinking for this

@prachyboon
Copy link

Hi, Prof. I have a question in line73: scipy.optimize.linear_sum_assignment(1 - iou_matrix). how this line work for matching multiple bbs correctly. I am finding the method to compare iou of bounding boxes from 2 images and your method is work! however, I quite don't understand this line completly. kindly you explain/guide it. 2nd question, I am wondering on, can we compare 2 images which have different size as 1st image is the original one and 2nd is a crop from 1st image. if there are the bounding on 2 images can we compare iou matching among boxes. (not sure but it should be work by normalized value like YOLO format). Thx.

1nd question. You should read carefully a Hungarian algorithm, this algorithm to calculate min cost pair, in here they will calculate min cost predict and ground truth. And when to use scipy.optimize.linear_sum_assignment(1 - iou_matrix) it think if iou is approximate 0, they become to approximate 1 and opposite if iou is big, they become to approximate small. And this is conditional for problem to find scipy.optimize.linear_sum_assignment(1 - iou_matrix) min and deduce iou max 2nd question. I'm thinking for this

So, for 1st question, min cost pair method would give probably best match results between boxes in two images?
Hows about 2nd question? I think it can not measure as exact IoU, just approximately?

@C0NGTRI123
Copy link

images
I don't know it catch best result? When I try use in my project to evaluate match pair prediction and ground truth based on IoU, it still good but some my result it not catch boxes high iou, I dont know why they don't catch them but generally they match one-to-one so good, it can catch 90-95% to correct. If you want to know more, you can search deepsort in tracking, because they use hungarian algrithm to match one-to-one prediction and ground truth

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment