'Evaluate detection proposal recall metrics.
Returns:
results: dictionary of results with keys
\'ar\': average recall
\'recalls\': vector recalls at each IoU overlap threshold
\'thresholds\': vector of IoU overlap thresholds
\'gt_overlaps\': vector of all ground-truth overlaps'

def evaluate_recall(self, candidate_boxes=None, thresholds=None, area='all', limit=None):

    areas = {'all': 0, 'small': 1, 'medium': 2, 'large': 3, '96-128': 4, '128-256': 5, '256-512': 6, '512-inf': 7}
    area_ranges = [[(0 ** 2), (100000.0 ** 2)], [(0 ** 2), (32 ** 2)], [(32 ** 2), (96 ** 2)], [(96 ** 2), (100000.0 ** 2)], [(96 ** 2), (128 ** 2)], [(128 ** 2), (256 ** 2)], [(256 ** 2), (512 ** 2)], [(512 ** 2), (100000.0 ** 2)]]
    assert areas.has_key(area), 'unknown    area    range:    {}'.format(area)
    area_range = area_ranges[areas[area]]
    gt_overlaps = np.zeros(0)
    num_pos = 0
    for i in xrange(self.num_images):
        max_gt_overlaps = self.roidb[i]['gt_overlaps'].toarray().max(axis=1)
        gt_inds = np.where(((self.roidb[i]['gt_classes'] > 0) & (max_gt_overlaps == 1)))[0]
        gt_boxes = self.roidb[i]['boxes'][gt_inds, :]
        gt_areas = self.roidb[i]['seg_areas'][gt_inds]
        valid_gt_inds = np.where(((gt_areas >= area_range[0]) & (gt_areas <= area_range[1])))[0]
        gt_boxes = gt_boxes[valid_gt_inds, :]
        num_pos += len(valid_gt_inds)
        if (candidate_boxes is None):
            non_gt_inds = np.where((self.roidb[i]['gt_classes'] == 0))[0]
            boxes = self.roidb[i]['boxes'][non_gt_inds, :]
        else:
            boxes = candidate_boxes[i]
        if (boxes.shape[0] == 0):
            continue
        if ((limit is not None) and (boxes.shape[0] > limit)):
            boxes = boxes[:limit, :]
        overlaps = bbox_overlaps(boxes.astype(np.float), gt_boxes.astype(np.float))
        _gt_overlaps = np.zeros(gt_boxes.shape[0])
        for j in xrange(gt_boxes.shape[0]):
            argmax_overlaps = overlaps.argmax(axis=0)
            max_overlaps = overlaps.max(axis=0)
            gt_ind = max_overlaps.argmax()
            gt_ovr = max_overlaps.max()
            assert (gt_ovr >= 0)
            box_ind = argmax_overlaps[gt_ind]
            _gt_overlaps[j] = overlaps[(box_ind, gt_ind)]
            assert (_gt_overlaps[j] == gt_ovr)
            overlaps[box_ind, :] = (-1)
            overlaps[:, gt_ind] = (-1)
        gt_overlaps = np.hstack((gt_overlaps, _gt_overlaps))
    gt_overlaps = np.sort(gt_overlaps)
    if (thresholds is None):
        step = 0.05
        thresholds = np.arange(0.5, (0.95 + 1e-05), step)
    recalls = np.zeros_like(thresholds)
    for (i, t) in enumerate(thresholds):
        recalls[i] = ((gt_overlaps >= t).sum() / float(num_pos))
    ar = recalls.mean()
    return {'ar': ar, 'recalls': recalls, 'thresholds': thresholds, 'gt_overlaps': gt_overlaps}
