def compute_iou_dt_gt(self, dt, gt, is_crowd):
     if self.is_rotated(dt) or self.is_rotated(gt):
         # TODO: take is_crowd into consideration
         assert all(c == 0 for c in is_crowd)
         dt = RotatedBoxes(self.boxlist_to_tensor(dt, output_box_dim=5))
         gt = RotatedBoxes(self.boxlist_to_tensor(gt, output_box_dim=5))
         return pairwise_iou_rotated(dt, gt)
     else:
         # This is the same as the classical COCO evaluation
         return maskUtils.iou(dt, gt, is_crowd)
예제 #2
0
def evalRes(gt0, dt0, thr, mul=0):
    """Evaluates detections against ground truth data
    % Uses modified Pascal criteria that allows for "ignore" regions. The
    % Pascal criteria states that a ground truth bounding box (gtBb) and a
    % detected bounding box (dtBb) match if their overlap area (oa):
    %  oa(gtBb,dtBb) = area(intersect(gtBb,dtBb)) / area(union(gtBb,dtBb))
    % is over a sufficient threshold (typically .5). In the modified criteria,
    % the dtBb can match any subregion of a gtBb set to "ignore". Choosing
    % gtBb' in gtBb that most closely matches dtBb can be done by using
    % gtBb'=intersect(dtBb,gtBb). Computing oa(gtBb',dtBb) is equivalent to
    %  oa'(gtBb,dtBb) = area(intersect(gtBb,dtBb)) / area(dtBb)
    % For gtBb set to ignore the above formula for oa is used.
    %
    % Highest scoring detections are matched first. Matches to standard,
    % (non-ignore) gtBb are preferred. Each dtBb and gtBb may be matched at
    % most once, except for ignore-gtBb which can be matched multiple times.
    % Unmatched dtBb are false-positives, unmatched gtBb are false-negatives.
    % Each match between a dtBb and gtBb is a true-positive, except matches
    % between dtBb and ignore-gtBb which do not affect the evaluation criteria.
    %
    % In addition to taking gt/dt results on a single image, evalRes() can take
    % cell arrays of gt/dt bbs, in which case evaluation proceeds on each
    % element. Use bbGt>loadAll() to load gt/dt for multiple images.
    %
    % Each gt/dt output row has a flag match that is either -1/0/1:
    %  for gt: -1=ignore,  0=fn [unmatched],  1=tp [matched]
    %  for dt: -1=ignore,  0=fp [unmatched],  1=tp [matched]
    %
    % USAGE
    %  [gt, dt] = bbGt( 'evalRes', gt0, dt0, [thr], [mul] )
    %
    % INPUTS
    %  gt0  - [mx5] ground truth array with rows [x y w h ignore]
    %  dt0  - [nx5] detection results array with rows [x y w h score]
    %  thr  - [.5] the threshold on oa for comparing two bbs
    %  mul  - [0] if true allow multiple matches to each gt
    %
    % OUTPUTS
    %  gt   - [mx5] ground truth results [x y w h match]
    %  dt   - [nx6] detection results [x y w h score match]
    %
    % EXAMPLE
    %
    % See also bbGt, bbGt>compOas, bbGt>loadAll"""

    # if gt0 and dt0 are cell arrays run on each element in turn
    if isinstance(gt0, list) and isinstance(dt0, list):
        n = len(gt0)
        assert len(dt0) == n
        gt = [None for _ in range(n)]
        dt = [None for _ in range(n)]
        for i in range(n):
            gt[i], dt[i] = evalRes(gt0[i], dt0[i], thr, mul)
        return gt, dt
    # check inputs
    gt0 = np.zeros([0, 5]) if gt0.shape[0] == 0 else gt0
    dt0 = np.zeros([0, 5]) if dt0.shape[0] == 0 else dt0
    assert gt0.shape[1] == 5
    assert dt0.shape[1] == 5
    nd, ng = dt0.shape[0], gt0.shape[0]

    # sort dt highest score first, sort gt ignore last
    dt0 = dt0[np.argsort(-dt0[:, 4]), :]
    gt0 = gt0[np.argsort(gt0[:, 4]), :]
    gt, dt = gt0, np.hstack([dt0, np.zeros([nd, 1])])
    gt[:, 4] = -gt[:, 4]
    # Attempt to match each (sorted) dt to each (sorted) gt
    # ious = compiou(dt[:, 0:4].astype(np.float32), gt[:, 0:4].astype(np.float32), gt[:, 4] == -1)
    ious = maskUtils.iou(dt[:, 0:4].astype(np.float32),
                         gt[:, 0:4].astype(np.float32), gt[:, 4] == -1)
    for d in range(nd):
        bstOa = thr
        bstg = 0
        bstm = 0  # % info about best match so far
        for g in range(ng):
            # if this gt already matched, continue to next gt
            m = gt[g, 4]
            if m == 1 and not mul: continue
            # if dt already matched, and on ignore gt, nothing more to do
            if bstm != 0 and m == -1: break
            # compute overlap area, continue to next gt unless better match made
            if ious[d, g] < bstOa: continue
            # match successful and best so far, store appropriately
            bstOa = ious[d, g]
            bstg = g
            if m == 0:
                bstm = 1
            else:  # false positive
                bstm = -1
        g = bstg
        m = bstm
        #  store type of match for both dt and gt
        if m == -1:
            dt[d, 5] = m
        elif m == 1:
            gt[g, 4] = m
            dt[d, 5] = m
    return gt, dt