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

function [metrics, metricsInfo, additionalInfo]=CLEAR_MOD_HUN(gt,det,options) % compute CLEAR Detection metrics according to % PERFORMANCE EVALUATION PROTOCOL FOR FACE, PERSON AND % VEHICLE DETECTION & TRACKING IN VIDEO ANALYSIS AND % CONTENT EXTRACTION (VACE-II) % CLEAR – CLASSIFICATION OF EVENTS, ACTIVITIES AND RELATIONSHIPS % Submitted to Advanced Research and Development Activity % metrics contains the following % [1] recall - recall = percentage of detected targets % [2] precision - precision = percentage of correctly detected targets % [3] FAR - number of false alarms per frame % [4] GT - number of GT boxes % [5] truepositivies- number of true positives (TP) % [6] falsepositives- number of false positives (FP) % [7] missed - number of missed targets (FN) % [8] MODA - N-MODA % [9] MODP - N-MODP % % % % % (C) Anton Milan, 2017 % % Input % MOTChallenge CSV format % gt - ground truth % det - detection result % default options: 2D if nargin<3 options.eval3d=0; % only bounding box overlap options.td=.5; % threshold 50% end if ~isfield(options,'td') if options.eval3d options.td=1000; error('not implemented'); else options.td=0.5; end end td=options.td; % if X,Y not existent, assume 2D % if ~isfield(gtInfo,'X'), gtInfo.X=gtInfo.Xi; end % if ~isfield(gtInfo,'Y'), gtInfo.Y=gtInfo.Yi; end % if ~isfield(stateInfo,'X'), stateInfo.X=stateInfo.Xi; end % if ~isfield(stateInfo,'Y'), stateInfo.Y=stateInfo.Yi; end % % gtInd=~~gtInfo.X; % stInd=~~stateInfo.X; % % [Fgt, Ngt]=size(gtInfo.X); % [F, N]=size(stateInfo.X); Fgt=max(gt(:,1)); Ngt=max(gt(:,2)); F=max(det(:,1)); N=max(det(:,2)); % % % if stateInfo shorter, pad with zeros % if F<Fgt % missingFrames = F+1:Fgt; % stateInfo.Xi(missingFrames,:)=0; % stateInfo.Yi(missingFrames,:)=0; % stateInfo.W(missingFrames,:)=0; % stateInfo.H(missingFrames,:)=0; % end % [1] recall - recall = percentage of detected targets % [2] precision - precision = percentage of correctly detected targets % [3] FAR - number of false alarms per frame % [4] falsepositives- number of false positives (FP) % [5] missed - number of missed targets (FN) % [6] MODA - N-MODA % [7] MODP - N-MODP % [8] MODP-t % [9] MODA-t metricsInfo.names.long = {'Recall','Precision','False Alarm Rate', ... 'Ground Truth', 'True Positives', 'False Positives', 'False Negatives', 'MODA','MODP'}; metricsInfo.names.short = {'Rcll','Prcn','FAR', ... 'GT', 'TP', 'FP', 'FN', 'MODA','MODP'}; metricsInfo.widths.long = [6 9 16 15 15 15 15 5 5]; metricsInfo.widths.short = [5 5 5 6 6 6 6 5 5]; metricsInfo.format.long = {'.1f','.1f','.2f', ... 'i','i','i','i', '.1f','.1f'}; metricsInfo.format.short=metricsInfo.format.long; metrics=zeros(1,7); metrics(5)=size(gt,1); % False Negatives (missed) additionalInfo=[]; % nothing to be done, if state is empty if ~N, return; end % mapping M=zeros(F,Ngt); % mme=zeros(1,F); % ID Switchtes (mismatches) c=zeros(1,F); % matches found fp=zeros(1,F); % false positives m=zeros(1,F); % misses = false negatives g=zeros(1,F); d=zeros(F,Ngt); % all distances; ious=Inf*ones(F,Ngt); % all overlaps % matched=@matched2d; % if options.eval3d, matched=@matched3d; end alltracked=zeros(F,Ngt); allfalsepos=zeros(F,N); for t=1:F % if ~mod(t,1000), fprintf('.'); end % print every 1000th frame % mapping for current frame % if t>1 % mappings=find(M(t-1,:)); % for map=mappings % if gtInd(t,map) && stInd(t,M(t-1,map)) && matched(gtInfo,stateInfo,t,map,M(t-1,map),td) % M(t,map)=M(t-1,map); % end % end % end % GTsInFrame=find(~M(t,:) & gtInd(t,:)); % DetsInFrame=setdiff(find(stInd(t,:)),M(t,:)); % stIndInT = find(stInd(t,:)); % GTsInFrame=find(~M(t,:) & gtInd(t,:)); % DetsInFrame=stIndInT; % if ~isempty(stIndInT) && any(M(t,:)) % DetsInFrame=setdiff(stIndInT,M(t,:)); % end GTsInFrame = find(gt(:,1)==t); DetsInFrame = find(det(:,1)==t); % reshape to ensure horizontal vector in empty case DetsInFrame=reshape(DetsInFrame,1,length(DetsInFrame)); GTsInFrame=reshape(GTsInFrame,1,length(GTsInFrame)); Ngtt=length(GTsInFrame); Nt = length(DetsInFrame); g(t)=Ngtt; if options.eval3d alldist=Inf*ones(Ngtt, Nt); mindist=0; for o=1:Ngtt GT=[gt(GTsInFrame(o),8), gt(GTsInFrame(o),9)]; for e=1:Nt E=[det(DetsInFrame,8), det(DetsInFrame(e),9)]; alldist(ocnt,ecnt)=norm(GT-E); end end tmpai=alldist; tmpai(tmpai>td)=Inf; [Mtch,~]=Hungarian(tmpai); [u,v]=find(Mtch); for mmm=1:length(u) M(t,u(mmm))=v(mmm); end else if ~isempty(GTsInFrame) && ~isempty(DetsInFrame) allisects=zeros(Ngtt,Nt); maxisect=Inf; for o=1:Ngtt GT=gt(GTsInFrame(o),[3:6]); for e=1:Nt E=det(DetsInFrame(e),[3:6]); allisects(o,e)=boxiou(GT(1),GT(2),GT(3),GT(4),E(1),E(2),E(3),E(4)); end end tmpai=allisects; tmpai=1-tmpai; tmpai(tmpai>td)=Inf; % do Hungarian matching only if there is anything to match if numel(find(~isinf(tmpai)))>0 [Mtch,~]=Hungarian(tmpai); [u,v]=find(Mtch); % M=M; for mmm=1:length(u) M(t,u(mmm))=v(mmm); end end end end curdetected=find(M(t,:)); % which GTs are detected? alldetections=1:Nt; % mappedDets=intersect(M(t,find(M(t,:))),alldetections); % falsepositives=setdiff(alldetections,mappedDets); mappedDets = []; if ~isempty(alldetections) && any(M(t,curdetected)) mappedDets=intersect(M(t,curdetected),alldetections); end falsepositives=alldetections; if ~isempty(falsepositives) && ~isempty(mappedDets) && any(mappedDets) falsepositives=setdiff(alldetections,mappedDets); end alltracked(t,:)=M(t,:); % allfalsepos(t,1:length(falsepositives))=falsepositives; allfalsepos(t,falsepositives)=falsepositives; c(t)=numel(curdetected); for ct=curdetected eid=M(t,ct); if options.eval3d d(t,ct)=norm([gt(GTsInFrame(ct),8), gt(GTsInFrame(ct),9)] - ... [det(DetsInFrame(eid),8), det(DetsInFrame(eid),9)]); else gtLeft = gt(GTsInFrame(ct), 3); gtTop = gt(GTsInFrame(ct), 4); gtWidth = gt(GTsInFrame(ct), 5); gtHeight = gt(GTsInFrame(ct), 6); stLeft = det(DetsInFrame(eid), 3); stTop = det(DetsInFrame(eid), 4); stWidth = det(DetsInFrame(eid), 5); stHeight = det(DetsInFrame(eid), 6); ious(t,ct)=boxiou(gtLeft,gtTop,gtWidth,gtHeight,stLeft,stTop,stWidth,stHeight); end end fp(t)=Nt-c(t); m(t)=g(t)-c(t); end missed=sum(m); falsepositives=sum(fp); truepositives=sum(c); % idswitches=sum(mme); if options.eval3d MODP=(1-sum(sum(d))/sum(c)/td) * 100; % avg distance to [0,100] else MODP=sum(ious(ious>=td & ious<Inf))/sum(c) * 100; % avg ol end if isnan(MODP), MODP=0; end % force to 0 if no matches found MODA=(1-((sum(m)+sum(fp))/sum(g)))*100; recall=sum(c)/sum(g)*100; precision=sum(c)/(sum(fp)+sum(c))*100; FAR=sum(fp)/Fgt; GT=sum(g); metrics=[recall, precision, FAR, GT, truepositives, falsepositives, missed, MODA, MODP]; additionalInfo.alltracked=alltracked; additionalInfo.allfalsepos=allfalsepos; additionalInfo.m = m; additionalInfo.fp = fp; additionalInfo.g = g; additionalInfo.c = c; additionalInfo.Fgt = Fgt; additionalInfo.Ngt = Ngt; additionalInfo.ious = ious; additionalInfo.td = td; end