evaluation/UAV-benchmark-MOTD_v1.0/utils/evalRes.m (82 lines of code) (raw):

function [gt,dt] = evalRes( gt0, dt0, thr, mul ) % 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 % get parameters if(nargin<3 || isempty(thr)), thr=.7; end if(nargin<4 || isempty(mul)), mul=0; end % if gt0 and dt0 are cell arrays run on each element in turn if( iscell(gt0) && iscell(dt0) ), n=length(gt0); assert(length(dt0)==n); gt=cell(1,n); dt=gt; for i=1:n, [gt{i},dt{i}] = evalRes(gt0{i},dt0{i},thr,mul); end; return; end % check inputs if(isempty(gt0)), gt0=zeros(0,5); end if(isempty(dt0)), dt0=zeros(0,5); end assert( size(dt0,2)==5 ); nd=size(dt0,1); assert( size(gt0,2)==5 ); ng=size(gt0,1); % sort dt highest score first, sort gt ignore last [~,ord]=sort(dt0(:,5),'descend'); dt0=dt0(ord,:); [~,ord]=sort(gt0(:,5),'ascend'); gt0=gt0(ord,:); gt=gt0; gt(:,5)=-gt(:,5); dt=dt0; dt=[dt zeros(nd,1)]; % Attempt to match each (sorted) dt to each (sorted) gt oa = compOas( dt(:,1:4), gt(:,1:4), gt(:,5)==-1 ); for d=1:nd bstOa=thr; bstg=0; bstm=0; % info about best match so far for g=1:ng % if this gt already matched, continue to next gt m=gt(g,5); if( m==1 && ~mul ), continue; end % if dt already matched, and on ignore gt, nothing more to do if( bstm~=0 && m==-1 ), break; end % compute overlap area, continue to next gt unless better match made if(oa(d,g)<bstOa), continue; end % match successful and best so far, store appropriately bstOa=oa(d,g); bstg=g; if(m==0), bstm=1; else bstm=-1; end end; g=bstg; m=bstm; % store type of match for both dt and gt if(m==-1), dt(d,6)=m; elseif(m==1), gt(g,5)=m; dt(d,6)=m; end end