forked from gcheron/P-CNN
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextract_cnn_features.m
142 lines (117 loc) · 5 KB
/
extract_cnn_features.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
function extract_cnn_features(video_names,param)
% create cache folders
cdirs={'cnn_features_app','cnn_features_app/frame_features','cnn_features_app/video_features' ...
'cnn_features_flow','cnn_features_flow/frame_features','cnn_features_flow/video_features',...
'cnn_features_resnet','cnn_features_resnet/frame_features','cnn_features_resnet/video_features'};
for d=1:length(cdirs)
dname=sprintf('%s/%s',param.cachepath,cdirs{d});
if ~exist(dname,'dir'); mkdir(dname) ; end
end
fprintf('\n------ Extract CNN features ------\n')
suf={'app','flow','resnet'} ;
bodyparts={'top_left' 'top_right' 'bottom_left' 'bottom_right' 'center' 'full_image'};
if param.use_poses
bodyparts={'left_hand' 'right_hand' 'upper_body' 'full_body' 'full_image'};
else
bodyparts={'top_left' 'top_right' 'bottom_left' 'bottom_right' 'center' 'full_image'};
end
featuresSz = 0;
for i=1:3 % appearance and flow
% get folders
patchesdir = sprintf('%s/patches_%s',param.cachepath,suf{i}) ;
framefeaturesdir = sprintf('%s/cnn_features_%s/frame_features',param.cachepath,suf{i});
videofeaturesdir = sprintf('%s/cnn_features_%s/video_features',param.cachepath,suf{i});
% get list of part patches
[filelist,outlist]=get_patches_list(patchesdir,framefeaturesdir,bodyparts);
% get net
net=param.(sprintf('net_%s',suf{i}));
if param.use_gpu
if strcmp(suf{i},'resnet') ~= 1
net = vl_simplenn_tidy(net);
net = vl_simplenn_move(net, 'gpu');
featuresSz = 4096 ;
else
move(net,'gpu');
featuresSz = 2048 ;
end
end % move net on GPU if needed
bsize=param.batchsize;
nim=length(filelist);
% extract CNN features per frame
for b=1:bsize:nim
fprintf('%s -- feature extraction: %d over %d:\t',suf{i},b,nim);tic;
im = vl_imreadjpeg(filelist(b:min(b+bsize-1,nim)),'numThreads', param.nbthreads_netinput_loading) ;
im = cat(4,im{:});
im = bsxfun(@minus, im, net.meta.normalization.averageImage) ;
if param.use_gpu ; im = gpuArray(im) ; end
if strcmp(suf{i},'resnet') ~= 1
res=vl_simplenn(net,im);
fprintf('extract %.2f s\t',toc);tic;
save_feats(squeeze(res(end-2).x),outlist(b:min(b+bsize-1,nim)),param); % take features after last ReLU
else
net.eval({'data', im}) ;
res = gather(net.vars(end-2).value);
fprintf('extract %.2f s\t',toc);tic;
save_feats(squeeze(res),outlist(b:min(b+bsize-1,nim)),param); % take features after last ReLU
end
fprintf('save %.2f s\n',toc)
end
% group frame features in their corresponding video
% features(1).x <--- left hand
% features(2).x <--- rigth hand
% features(3).x <--- upper body
% features(4).x <--- full body
% features(5).x <--- full image
parfor vi=1:length(video_names)
group_cnn_features(framefeaturesdir,videofeaturesdir,video_names{vi},bodyparts,featuresSz);
end
end
function [filelist,outlist]=get_patches_list(indirname,outdirname,bodyparts)
images=dir(sprintf('%s/%s/*jpg',indirname,bodyparts{1}));
images = {images.name};
[~,resnames,~]=cellfun(@(x) fileparts(x),images,'UniformOutput',false);
resnames=strcat(resnames,repmat({'.mat'},1,length(images)));
filelist=cell(1,length(bodyparts)*length(images));
outlist=cell(1,length(bodyparts)*length(images));
for i=1:length(bodyparts)
indirpath=sprintf('%s/%s/',indirname,bodyparts{i});
destdirpath=sprintf('%s/%s/',outdirname,bodyparts{i});
if ~exist(destdirpath,'dir'); mkdir(destdirpath) ; end
pimages=repmat({indirpath},1,length(images));
qimages=repmat({destdirpath},1,length(images));
filelist(1,1+(i-1)*length(images):i*length(images)) = strcat(pimages,images);
outlist(1,1+(i-1)*length(images):i*length(images)) = strcat(qimages,resnames);
end
function save_feats(feats,outlist,param)
assert(length(outlist)==size(feats,2));
if param.use_gpu; feats=gather(feats); end
parfor i=1:length(outlist)
out=outlist{i};
features=feats(:,i)';
parsave(out,features);
end
function parsave(out,features)
save(out,'features');
function group_cnn_features(framefeaturesdir,videofeaturesdir,video_name,bodyparts,featuresSz)
% features(1).x <--- left hand
% features(2).x <--- rigth hand
% features(3).x <--- upper body
% features(4).x <--- full body
% features(5).x <--- full image
% part sub-directories to check "bodyparts"
features = [] ;
for i=1:length(bodyparts)
dirpath=sprintf('%s/%s',framefeaturesdir,bodyparts{i});
pathname=sprintf('%s/%s_im*',dirpath,video_name);
td=dir(pathname) ;
assert(~isempty(td));
x=zeros(length(td),featuresSz) ;
features(i).name=sprintf('CNNf_%s',bodyparts{i}) ;
for j=1:length(td)
samplepath=sprintf('%s/%s',dirpath,td(j).name);
tmp=load(samplepath) ;
x(j,:)=tmp.features ;
end
features(i).x=x;
end
save(sprintf('%s/%s.mat',videofeaturesdir,video_name),'features');