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

function [metrics, metricsInfo, additionalInfo] = CLEAR_MOT_HUN(gtMat, resMat, threshold, world) % compute CLEAR MOT and other metrics % % metrics contains the following % [1] recall - percentage of detected targets % [2] precision - percentage of correctly detected targets % [3] FAR - number of false alarms per frame % [4] GT - number of ground truth trajectories % [5-7] MT, PT, ML - number of mostly tracked, partially tracked and mostly lost trajectories % [8] falsepositives- number of false positives (FP) % [9] missed - number of missed targets (FN) % [10] idswitches - number of id switches (IDs) % [11] FRA - number of fragmentations % [12] MOTA - Multi-object tracking accuracy in [0,100] % [13] MOTP - Multi-object tracking precision in [0,100] (3D) / [td,100] (2D) % [14] MOTAL - Multi-object tracking accuracy in [0,100] with log10(idswitches) % % % (C) Anton Milan, 2012-2014 metricsInfo.names.long = {'Recall','Precision','False Alarm Rate', ... 'GT Tracks','Mostly Tracked','Partially Tracked','Mostly Lost', ... 'False Positives', 'False Negatives', 'ID Switches', 'Fragmentations', ... 'MOTA','MOTP', 'MOTA Log'}; metricsInfo.names.short = {'Rcll','Prcn','FAR', ... 'GT','MT','PT','ML', ... 'FP', 'FN', 'IDs', 'FM', ... 'MOTA','MOTP', 'MOTAL'}; metricsInfo.widths.long = [6 9 16 9 14 17 11 13 15 15 11 14 5 5 8]; metricsInfo.widths.short = [5 5 5 3 3 3 3 2 4 4 3 3 5 5 5]; metricsInfo.format.long = {'.1f','.1f','.2f', ... 'i','i','i','i', ... 'i','i','i','i','i', ... '.1f','.1f','.1f'}; metricsInfo.format.short=metricsInfo.format.long; additionalInfo=[]; % Normalize IDs [~, ~, ic] = unique(gtMat(:,2)); gtMat(:,2) = ic; [~, ~, ic2] = unique(resMat(:,2)); resMat(:,2) = ic2; % Evaluate VERBOSE = false; [mme, c, fp, m, g, d, alltracked, allfalsepos] = clearMOTMex(gtMat, resMat, threshold, world, VERBOSE); Fgt = max(gtMat(:,1)); % Assumes first gt frame is 1 Ngt = length(unique(gtMat(:,2))); F = max(resMat(:,1)); missed=sum(m); falsepositives=sum(fp); idswitches=sum(mme); % Sanity check % gti = convertMatToStruct(gtMat, -1); % sti = convertMatToStruct(resMat, Fgt); % options = struct; % if world, options.eval3d = true; else, options.eval3d = false; end % options.td = threshold; % options.VERBOSE = VERBOSE; % [mme2, c2, fp2, m2, g2, d2, alltracked2, allfalsepos2] = clearMOTLoopMatlab(gti, sti, options); % assert(isequal(g,g2),'cpp vs matlab: GT discrepancy'); % assert(isequal(fp,fp2),'cpp vs matlab: FP discrepancy'); % assert(isequal(m,m2), 'cpp vs matlab: FN discrepancy'); % assert(isequal(c,c2), 'cpp vs matlab: TP discrepancy'); % assert(isequal(mme,mme2), 'cpp vs matlab: IDS discrepancy'); % assert(isempty(find(abs(d-d2)>1e-6)), 'cpp vs matlab: Dist discrepancy'); MOTP=(1-sum(sum(d))/sum(c)) * 100; % avg distance to [0,100] if world, MOTP = MOTP / threshold; end if isnan(MOTP), MOTP=0; end % force to 0 if no matches found MOTAL=(1-((sum(m)+sum(fp)+log10(sum(mme)+1))/sum(g)))*100; MOTA=(1-((sum(m)+sum(fp)+(sum(mme)))/sum(g)))*100; recall=sum(c)/sum(g)*100; precision=sum(c)/(sum(fp)+sum(c))*100; if isnan(precision), precision=0; end % force to 0 if no matches found FAR=sum(fp)/Fgt; %% MT PT ML MTstatsa=zeros(1,Ngt); for i=1:Ngt gtframes = gtMat(gtMat(:,2)==i,1); gttotallength=numel(gtframes); trlengtha=numel(find(alltracked(gtframes,i)>0)); if trlengtha/gttotallength < 0.2 MTstatsa(i)=3; elseif F>=find(gtMat(gtMat(:,2)==i,1),1,'last') && trlengtha/gttotallength <= 0.8 MTstatsa(i)=2; elseif trlengtha/gttotallength >= 0.8 MTstatsa(i)=1; end end % MTstatsa MT=numel(find(MTstatsa==1)); PT=numel(find(MTstatsa==2)); ML=numel(find(MTstatsa==3)); %% fragments fr=zeros(1,Ngt); for i=1:Ngt b=alltracked(find(alltracked(:,i),1,'first'):find(alltracked(:,i),1,'last'),i); b(~~b)=1; fr(i)=numel(find(diff(b)==-1)); end FRA=sum(fr); % assert(Ngt==MT+PT+ML,'Hmm... Not all tracks classified correctly.'); metrics=[recall, precision, FAR, Ngt, MT, PT, ML, falsepositives, missed, idswitches, FRA, MOTA, MOTP, MOTAL]; additionalInfo.alltracked=alltracked; additionalInfo.allfalsepos=allfalsepos; additionalInfo.m = m; additionalInfo.fp = fp; additionalInfo.mme = mme; additionalInfo.g = g; additionalInfo.c = c; additionalInfo.Fgt = Fgt; additionalInfo.Ngt = Ngt; additionalInfo.d = d; additionalInfo.MT = MT; additionalInfo.PT = PT; additionalInfo.ML = ML; additionalInfo.FRA = FRA; additionalInfo.td = threshold; end