From d40360bd4c80c8396f4192cab7fcdfc8bb35e302 Mon Sep 17 00:00:00 2001 From: pdollar Date: Fri, 31 Oct 2014 14:02:22 -0700 Subject: [PATCH] detector/: support for LDCF (NIPS2014 paper) --- detector/acfDemoCal.m | 8 +++++++- detector/acfDemoInria.m | 10 +++++++++- detector/acfDetect.m | 13 +++++++++--- detector/acfTrain.m | 44 +++++++++++++++++++++++++++++++++++++---- 4 files changed, 66 insertions(+), 9 deletions(-) diff --git a/detector/acfDemoCal.m b/detector/acfDemoCal.m index ea1e85c0..5bbd4e52 100644 --- a/detector/acfDemoCal.m +++ b/detector/acfDemoCal.m @@ -38,11 +38,17 @@ pLoad={'lbls',{'person'},'ilbls',{'people'},'squarify',{3,.41}}; opts.pLoad = [pLoad 'hRng',[50 inf], 'vRng',[1 1] ]; +%% optionally set up opts for LDCF version of detector (see acfTrain) +if( 0 ) + % NEED TO SETUP LDCF PARAMS HERE [FOR NOW MANUALLY ALTER ACFTRAIN] + opts.name='models/LdcfCaltech'; +end + %% train detector (see acfTrain) detector = acfTrain( opts ); %% modify detector (see acfModify) -pModify=struct('cascThr',-1,'cascCal',.005); +pModify=struct('cascThr',-1,'cascCal',.01); detector=acfModify(detector,pModify); %% run detector on a sample image (see acfDetect) diff --git a/detector/acfDemoInria.m b/detector/acfDemoInria.m index 3ba09c21..f41b7f1c 100644 --- a/detector/acfDemoInria.m +++ b/detector/acfDemoInria.m @@ -35,11 +35,19 @@ opts.negImgDir=[dataDir 'train/neg']; opts.pBoost.pTree.fracFtrs=1/16; opts.pLoad={'squarify',{3,.41}}; opts.name='models/AcfInria'; +%% optionally set up opts for LDCF version of detector (see acfTrain) +if( 0 ) + % NEED TO SETUP LDCF PARAMS HERE [FOR NOW MANUALLY ALTER ACFTRAIN] + opts.pJitter=struct('flip',1,'nTrn',3,'mTrn',1); opts.seed=1; + opts.pBoost.pTree.maxDepth=3; opts.pBoost.discrete=0; + opts.pPyramid.pChns.shrink=2; opts.name='models/LdcfInria'; +end + %% train detector (see acfTrain) detector = acfTrain( opts ); %% modify detector (see acfModify) -pModify=struct('cascThr',-1,'cascCal',0); +pModify=struct('cascThr',-1,'cascCal',.01); detector=acfModify(detector,pModify); %% run detector on a sample image (see acfDetect) diff --git a/detector/acfDetect.m b/detector/acfDetect.m index 5769172c..eeae639f 100644 --- a/detector/acfDetect.m +++ b/detector/acfDetect.m @@ -31,7 +31,7 @@ % % See also acfTrain, acfModify, bbGt>loadAll, bbNms % -% Piotr's Computer Vision Matlab Toolbox Version 3.20 +% Piotr's Computer Vision Matlab Toolbox Version NEW % Copyright 2014 Piotr Dollar. [pdollar-at-gmail.com] % Licensed under the Simplified BSD License [see external/bsd.txt] @@ -61,9 +61,16 @@ imreadf=opts.imreadf; imreadp=opts.imreadp; shrink=pPyramid.pChns.shrink; pad=pPyramid.pad; separate=nDs>1 && isfield(pNms,'separate') && pNms.separate; -% perform actual computations +% read image and compute features (including optionally applying FB) if(all(ischar(I))), I=feval(imreadf,I,imreadp{:}); end -P = chnsPyramid(I,pPyramid); bbs = cell(P.nScales,nDs); +P=chnsPyramid(I,pPyramid); bbs=cell(P.nScales,nDs); +if(isfield(opts,'FB') && ~isempty(opts.FB)), shrink=shrink*2; + for i=1:P.nScales, FB=opts.FB; C=repmat(P.data{i},[1 1 size(FB,4)]); + for j=1:size(C,3), C(:,:,j)=conv2(C(:,:,j),FB(:,:,j),'same'); end + P.data{i}=imResample(C,.5); + end +end +% apply sliding window classifiers for i=1:P.nScales for j=1:nDs, opts=Ds{j}.opts; modelDsPad=opts.modelDsPad; modelDs=opts.modelDs; diff --git a/detector/acfTrain.m b/detector/acfTrain.m index fe08253b..3505a5e5 100644 --- a/detector/acfTrain.m +++ b/detector/acfTrain.m @@ -130,7 +130,7 @@ % sample positives and compute features if( stage==0 ) Is1 = sampleWins( detector, stage, 1 ); - X1 = chnsCompute1( Is1, opts ); + X1 = chnsCompute1( Is1, opts ); X1a=X1; X1 = reshape(X1,[],size(X1,4))'; end @@ -140,6 +140,14 @@ t=chnsCompute(t,opts.pPyramid.pChns); detector.info=t.info; end + % compute local correlations and recompute features + if( stage==0 && isempty(opts.FB) && 0 ) % OFF + opts.FB = chnsCorrelation( X1a, 5, 4, 5000 ); + detector.opts.FB = opts.FB; + X1 = chnsCompute1( Is1, opts ); + X1 = reshape(X1,[],size(X1,4))'; + end; clear X1a; + % compute lambdas if( stage==0 && isempty(opts.pPyramid.lambdas) ) fprintf('Computing lambdas... '); start=clock; @@ -184,7 +192,7 @@ function opts = initializeOpts( varargin ) % Initialize opts struct. dfs= { 'pPyramid',{}, 'modelDs',[100 41], 'modelDsPad',[128 64], ... - 'pNms',struct(), 'stride',4, 'cascThr',-1, 'cascCal',.005, ... + 'FB',[], 'pNms',struct(), 'stride',4, 'cascThr',-1, 'cascCal',.005, ... 'nWeak',128, 'pBoost', {}, 'seed',0, 'name','', 'posGtDir','', ... 'posImgDir','', 'negImgDir','', 'posWinDir','', 'negWinDir','', ... 'imreadf',@imread, 'imreadp',{}, 'pLoad',{}, 'nPos',inf, 'nNeg',5000, ... @@ -291,14 +299,42 @@ function chns = chnsCompute1( Is, opts ) % Compute single scale channels of dimensions modelDsPad. if(isempty(Is)), chns=[]; return; end -fprintf('Extracting features... '); start=clock; +fprintf('Extracting features... '); start=clock; FB=opts.FB; pChns=opts.pPyramid.pChns; smooth=opts.pPyramid.smooth; dsTar=opts.modelDsPad/pChns.shrink; ds=size(Is); ds(1:end-1)=1; Is=squeeze(mat2cell2(Is,ds)); n=length(Is); chns=cell(1,n); parfor i=1:n C=chnsCompute(Is{i},pChns); C=convTri(cat(3,C.data{:}),smooth); - ds=size(C); cr=ds(1:2)-dsTar; s=floor(cr/2)+1; e=ceil(cr/2); + if(~isempty(FB)), C=repmat(C,[1 1 size(FB,4)]); + for j=1:size(C,3), C(:,:,j)=conv2(C(:,:,j),FB(:,:,j),'same'); end; end + if(~isempty(FB)), C=imResample(C,.5); shr=2; else shr=1; end + ds=size(C); cr=ds(1:2)-dsTar/shr; s=floor(cr/2)+1; e=ceil(cr/2); C=C(s(1):end-e(1),s(2):end-e(2),:); chns{i}=C; end; chns=cat(4,chns{:}); fprintf('done (time=%.0fs).\n',etime(clock,start)); end + +function FB = chnsCorrelation( chns, wFilters, nFilters, maxImg ) +% Compute FB capturing local correlations for each channel. +fprintf('Computing correlations... '); start=clock; +[~,~,m,n]=size(chns); w=wFilters; wp=w*2-1; +if(n>maxImg), chns=chns(:,:,:,randperm(n,maxImg)); n=maxImg; end +FB=zeros(w,w,m,nFilters,'single'); +for i=1:m + % compute local auto-scorrelation using Wiener-Khinchin theorem + mus=squeeze(mean(mean(chns(:,:,i,:)))); sig=cell(1,n); + parfor j=1:n + T=fftshift(ifft2(abs(fft2(chns(:,:,i,j)-mean(mus))).^2)); + sig{j}=T(floor(end/2)+1-w+(1:wp),floor(end/2)+1-w+(1:wp)); + end + sig=double(mean(cat(4,sig{mus>1/50}),4)); + sig=reshape(full(convmtx2(sig,w,w)),wp+w-1,wp+w-1,[]); + sig=reshape(sig(w:wp,w:wp,:),w^2,w^2); sig=(sig+sig')/2; + % compute FB for each channel from sig (sorted by eigenvalue) + [FBk,D]=eig(sig); FBk=reshape(FBk,w,w,[]); + [~,ord]=sort(diag(D),'descend'); + FBk=flipdim(flipdim(FBk,1),2); %#ok + FB(:,:,i,:)=FBk(:,:,ord(1:nFilters)); +end +fprintf('done (time=%.0fs).\n',etime(clock,start)); +end