Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added two filtering options to pLoad to set the "ignore" flag when us… #22

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 61 additions & 5 deletions detector/bbGt.m
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,20 @@
% .oRng - [] range of acceptable obj orientations (angles)
% .xRng - [] range of x coordinates of bb extent
% .yRng - [] range of y coordinates of bb extent
% .zRng - [] range of acceptable z point coordinates
% .vRng - [] range of acceptable obj occlusion levels
% .name - [] regexp on image source name to ignore
% .invName - [0] invert behavior of name, setting non-matches ignore
% .database - [] regexp on database name to ignore
% .invData - [0] invert behavior of database, setting non-matches to
% ignore
% .ignDiff - [1] ignore labels marked as "difficult" in Pascal VOC
% format (1). Has no effect in other formats. Valid values
% and effects on use of difficult lables are
% 0 - labels are used as normal
% 1 - labels are set to ignore
% -1 - difficult labels are used, and all labels not set as
% difficult are set to ignore
%
% OUTPUTS
% objs - loaded objects
Expand All @@ -210,11 +223,16 @@

% get parameters
df={'format',0,'ellipse',1,'squarify',[],'lbls',[],'ilbls',[],'hRng',[],...
'wRng',[],'aRng',[],'arRng',[],'oRng',[],'xRng',[],'yRng',[],'vRng',[]};
[format,ellipse,sqr,lbls,ilbls,hRng,wRng,aRng,arRng,oRng,xRng,yRng,vRng]...
'wRng',[],'aRng',[],'arRng',[],'oRng',[],'xRng',[],'yRng',[],...
'zRng',[],'vRng',[],...
'name',[],'invName',0,'database',[],'invData',0,'ignDiff',1};
[format,ellipse,sqr,lbls,ilbls,hRng,wRng,aRng,arRng,oRng,xRng,yRng,zRng,vRng,...
name,invName,database,invData,ignDiff]...
= getPrmDflt(varargin,df,1);

% load objs
nameVal = [];
dbVal = [];
if( format==0 )
% load objs stored in default format
fId=fopen(fName);
Expand All @@ -237,19 +255,41 @@
% load objs stored in PASCAL VOC format
if(exist('PASreadrecord.m','file')~=2)
error('bbLoad() requires the PASCAL VOC code.'); end
os=PASreadrecord(fName); os=os.objects;
parsed=PASreadrecord(fName);
nameVal = parsed.source.image;
dbVal = parsed.database;
os=parsed.objects;
n=length(os); objs=create(n);
if(~isfield(os,'occluded')), for i=1:n, os(i).occluded=0; end; end
for i=1:n
if(isfield(os(i),'point')) && isfield(os(i).point, 'z')
objs(i).z=os(i).point.z;
else
objs(i).z=nan;
end;
end
for i=1:n
bb=os(i).bbox; bb(3)=bb(3)-bb(1); bb(4)=bb(4)-bb(2); objs(i).bb=bb;
objs(i).lbl=os(i).class; objs(i).ign=os(i).difficult;
objs(i).lbl=os(i).class;
switch ignDiff
case 1
objs(i).ign=os(i).difficult;
case -1
objs(i).ign=not(os(i).difficult);
case 0
otherwise
error('Invalid value for ignDiff')
end
objs(i).occ=os(i).occluded || os(i).truncated;
if(objs(i).occ), objs(i).bbv=bb; end
end
elseif( format==2 )
if(exist('VOCreadxml.m','file')~=2)
error('bbLoad() requires the ImageNet dev code.'); end
os=VOCreadxml(fName); os=os.annotation;
parsed=VOCreadxml(fName);
nameVal = parsed.annotation.source.image;
dbVal = parsed.annotation.source.database;
os=parsed.annotation;
if(isfield(os,'object')), os=os.object; else os=[]; end
n=length(os); objs=create(n);
for i=1:n
Expand All @@ -260,6 +300,20 @@
else error('bbLoad() unknown format: %i',format);
end

% Filter on image source and database name
filteredAll = false;
if ~isempty(nameVal) && ~isempty(name)
match = regexp(nameVal, name, 'once');
filteredAll = filteredAll | xor(numel(match), invName);
end
if ~isempty(dbVal) && ~isempty(database)
match = regexp(dbVal, database, 'once');
filteredAll = filteredAll | xor(numel(match), invData);
end
if filteredAll
for i=1:n, objs(i).ign = 1; end
end

% only keep objects whose lbl is in lbls or ilbls
if(~isempty(lbls) || ~isempty(ilbls)), K=true(n,1);
for i=1:n, K(i)=any(strcmp(objs(i).lbl,[lbls ilbls])); end
Expand Down Expand Up @@ -293,6 +347,8 @@
v=(bbv(3)*bbv(4))/(bb(3)*bb(4)); end
objs(i).ign = objs(i).ign || v<vRng(1) || v>vRng(2); end
end
if(~isempty(zRng)), for i=1:n, v=objs(i).z; % Handle NaN entries
objs(i).ign = objs(i).ign || ~(v>zRng(1) && v<zRng(2)); end; end

% finally get extent of each bounding box (not trivial if ang~=0)
if(nargout<=1), return; end; if(n==0), bbs=zeros(0,5); return; end
Expand Down
11 changes: 11 additions & 0 deletions external/VOCdevkit/VOCcode/PASemptyobject.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function object=PASemptyobject
object.label='';
object.orglabel='';
object.bbox=[];
object.polygon=[];
object.mask='';
object.class='';
object.view='';
object.truncated=false;
object.difficult=false;
return
6 changes: 6 additions & 0 deletions external/VOCdevkit/VOCcode/PASemptyrecord.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function record=PASemptyrecord
record.imgname='';
record.imgsize=[];
record.database='';
record.objects=PASemptyobject;
return
7 changes: 7 additions & 0 deletions external/VOCdevkit/VOCcode/PASerrmsg.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function PASerrmsg(PASerr,SYSerr)
fprintf('Pascal Error Message: %s\n',PASerr);
fprintf('System Error Message: %s\n',SYSerr);
k=input('Enter K for keyboard, any other key to continue or ^C to quit ...','s');
if (~isempty(k)), if (lower(k)=='k'), keyboard; end; end;
fprintf('\n');
return
11 changes: 11 additions & 0 deletions external/VOCdevkit/VOCcode/PASreadrecord.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function rec = PASreadrecord(path)

if length(path)<4
error('unable to determine format: %s',path);
end

if strcmp(path(end-3:end),'.txt')
rec=PASreadrectxt(path);
else
rec=VOCreadrecxml(path);
end
99 changes: 99 additions & 0 deletions external/VOCdevkit/VOCcode/PASreadrectxt.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
function record=PASreadrectxt(filename)
[fd,syserrmsg]=fopen(filename,'rt');
if (fd==-1),
PASmsg=sprintf('Could not open %s for reading',filename);
PASerrmsg(PASmsg,syserrmsg);
end;

matchstrs=initstrings;
record=PASemptyrecord;
notEOF=1;
while (notEOF),
line=fgetl(fd);
notEOF=ischar(line);
if (notEOF),
matchnum=match(line,matchstrs);
switch matchnum,
case 1, [imgname]=strread(line,matchstrs(matchnum).str);
record.imgname=char(imgname);
case 2, [x,y,c]=strread(line,matchstrs(matchnum).str);
record.imgsize=[x y c];
case 3, [database]=strread(line,matchstrs(matchnum).str);
record.database=char(database);
case 4, [obj,lbl,xmin,ymin,xmax,ymax]=strread(line,matchstrs(matchnum).str);
record.objects(obj).label=char(lbl);
record.objects(obj).bbox=[min(xmin,xmax),min(ymin,ymax),max(xmin,xmax),max(ymin,ymax)];
case 5, tmp=findstr(line,' : ');
[obj,lbl]=strread(line(1:tmp),matchstrs(matchnum).str);
record.objects(obj).label=char(lbl);
record.objects(obj).polygon=sscanf(line(tmp+3:end),'(%d, %d) ')';
case 6, [obj,lbl,mask]=strread(line,matchstrs(matchnum).str);
record.objects(obj).label=char(lbl);
record.objects(obj).mask=char(mask);
case 7, [obj,lbl,orglbl]=strread(line,matchstrs(matchnum).str);
lbl=char(lbl);
record.objects(obj).label=lbl;
record.objects(obj).orglabel=char(orglbl);
if strcmp(lbl(max(end-8,1):end),'Difficult')
record.objects(obj).difficult=true;
lbl(end-8:end)=[];
else
record.objects(obj).difficult=false;
end
if strcmp(lbl(max(end-4,1):end),'Trunc')
record.objects(obj).truncated=true;
lbl(end-4:end)=[];
else
record.objects(obj).truncated=false;
end
t=find(lbl>='A'&lbl<='Z');
t=t(t>=4);
if ~isempty(t)
record.objects(obj).view=lbl(t(1):end);
lbl(t(1):end)=[];
else
record.objects(obj).view='';
end
record.objects(obj).class=lbl(4:end);

otherwise, %fprintf('Skipping: %s\n',line);
end;
end;
end;
fclose(fd);
return

function matchnum=match(line,matchstrs)
for i=1:length(matchstrs),
matched(i)=strncmp(line,matchstrs(i).str,matchstrs(i).matchlen);
end;
matchnum=find(matched);
if isempty(matchnum), matchnum=0; end;
if (length(matchnum)~=1),
PASerrmsg('Multiple matches while parsing','');
end;
return

function s=initstrings
s(1).matchlen=14;
s(1).str='Image filename : %q';

s(2).matchlen=10;
s(2).str='Image size (X x Y x C) : %d x %d x %d';

s(3).matchlen=8;
s(3).str='Database : %q';

s(4).matchlen=8;
s(4).str='Bounding box for object %d %q (Xmin, Ymin) - (Xmax, Ymax) : (%d, %d) - (%d, %d)';

s(5).matchlen=7;
s(5).str='Polygon for object %d %q (X, Y)';

s(6).matchlen=5;
s(6).str='Pixel mask for object %d %q : %q';

s(7).matchlen=8;
s(7).str='Original label for object %d %q : %q';

return
10 changes: 10 additions & 0 deletions external/VOCdevkit/VOCcode/VOCap.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function ap = VOCap(rec,prec)

mrec=[0 ; rec ; 1];
mpre=[0 ; prec ; 0];
for i=numel(mpre)-1:-1:1
mpre(i)=max(mpre(i),mpre(i+1));
end
i=find(mrec(2:end)~=mrec(1:end-1))+1;
ap=sum((mrec(i)-mrec(i-1)).*mpre(i));

59 changes: 59 additions & 0 deletions external/VOCdevkit/VOCcode/VOCevalaction.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
function [rec,prec,ap] = VOCevalaction(VOCopts,id,cls,draw)

% load test set
[gtimg,gtobj,gt]=textread(sprintf(VOCopts.action.clsimgsetpath,cls,VOCopts.testset),'%s %d %d');

% hash image/object ids
gtid=cell(numel(gtimg),1);
for i=1:numel(gtimg);
gtid{i}=sprintf('%s/%d',gtimg{i},gtobj(i));
end
hash=VOChash_init(gtid);

% load results
[img,obj,confidence]=textread(sprintf(VOCopts.action.respath,id,cls),'%s %d %f');

% map results to ground truth objects
out=ones(size(gt))*-inf;
tic;
for i=1:length(img)
% display progress
if toc>1
fprintf('%s: pr: %d/%d\n',cls,i,length(img));
drawnow;
tic;
end

% find ground truth object
k=sprintf('%s/%d',img{i},obj(i));
j=VOChash_lookup(hash,k);
if isempty(j)
error('unrecognized object "%s"',k);
elseif length(j)>1
error('multiple image "%s"',k);
else
out(j)=confidence(i);
end
end

% compute precision/recall

[so,si]=sort(-out);
tp=gt(si)>0;
fp=gt(si)<0;

fp=cumsum(fp);
tp=cumsum(tp);
rec=tp/sum(gt>0);
prec=tp./(fp+tp);

ap=VOCap(rec,prec);

if draw
% plot precision/recall
plot(rec,prec,'-');
grid;
xlabel 'recall'
ylabel 'precision'
title(sprintf('class: %s, subset: %s, AP = %.3f',cls,VOCopts.testset,ap));
end
54 changes: 54 additions & 0 deletions external/VOCdevkit/VOCcode/VOCevalcls.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
function [rec,prec,ap] = VOCevalcls(VOCopts,id,cls,draw)

% load test set
[gtids,gt]=textread(sprintf(VOCopts.clsimgsetpath,cls,VOCopts.testset),'%s %d');

% hash image ids
hash=VOChash_init(gtids);

% load results
[ids,confidence]=textread(sprintf(VOCopts.clsrespath,id,cls),'%s %f');

% map results to ground truth images
out=ones(size(gt))*-inf;
tic;
for i=1:length(ids)
% display progress
if toc>1
fprintf('%s: pr: %d/%d\n',cls,i,length(ids));
drawnow;
tic;
end

% find ground truth image
j=VOChash_lookup(hash,ids{i});
if isempty(j)
error('unrecognized image "%s"',ids{i});
elseif length(j)>1
error('multiple image "%s"',ids{i});
else
out(j)=confidence(i);
end
end

% compute precision/recall

[so,si]=sort(-out);
tp=gt(si)>0;
fp=gt(si)<0;

fp=cumsum(fp);
tp=cumsum(tp);
rec=tp/sum(gt>0);
prec=tp./(fp+tp);

ap=VOCap(rec,prec);

if draw
% plot precision/recall
plot(rec,prec,'-');
grid;
xlabel 'recall'
ylabel 'precision'
title(sprintf('class: %s, subset: %s, AP = %.3f',cls,VOCopts.testset,ap));
end
Loading