-
Notifications
You must be signed in to change notification settings - Fork 71
/
deep_pyramid.m
108 lines (91 loc) · 3.27 KB
/
deep_pyramid.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
function [pyra, im_pyra] = deep_pyramid(im, cnn_model)
% [pyra, im_pyra] = deep_pyramid(im, cnn_model, cache_opts)
%
% im: a color image
% cnn_model: a handle to the model loaded into caffe
% AUTORIGHTS
% ---------------------------------------------------------
% Copyright (c) 2014, Ross Girshick
%
% This file is part of the DeepPyramid code and is available
% under the terms of the Simplified BSD License provided in
% LICENSE. Please retain this notice and LICENSE if you use
% this file (or any portion of it) in your project.
% ---------------------------------------------------------
[pyra, im_pyra] = feat_pyramid(im, cnn_model);
imsize = size(im);
pyra.imsize = imsize(1:2);
pyra.num_levels = cnn_model.pyra.num_levels;
pyra.stride = cnn_model.pyra.stride;
pyra.valid_levels = true(pyra.num_levels, 1);
pyra.padx = 0;
pyra.pady = 0;
% ------------------------------------------------------------------------
function [pyra, im_pyra] = feat_pyramid(im, cnn_model)
% ------------------------------------------------------------------------
% Compute a feature pyramid with caffe
if cnn_model.init_key ~= caffe('get_init_key')
error('You probably need to load the cnn model into caffe.');
end
% we're assuming the input height and width are the same
assert(cnn_model.pyra.dimx == cnn_model.pyra.dimy);
% compute output width and height
sz_w = (cnn_model.pyra.dimx - 1) / cnn_model.pyra.stride + 1;
sz_h = sz_w;
sz_l = cnn_model.pyra.num_levels;
sz_c = cnn_model.pyra.num_channels;
%th = tic;
[batch, scales, level_sizes] = image_pyramid(im, cnn_model);
%fprintf('prep: %.3fs\n', toc(th));
%th = tic;
feat = caffe('forward', {batch});
% standard song and dance of swapping width and height between caffe and matlab
feat = permute(reshape(feat{1}, [sz_w sz_h sz_c sz_l]), [2 1 3 4]);
%fprintf('fwd: %.3fs\n', toc(th));
pyra.feat = feat;
pyra.scales = scales;
pyra.level_sizes = level_sizes;
im_pyra = batch;
% ------------------------------------------------------------------------
function [batch, scales, level_sizes] = image_pyramid(im, cnn_model)
% ------------------------------------------------------------------------
% Construct an image pyramid that's ready for feeding directly into caffe
% forward
batch_width = cnn_model.pyra.dimx;
batch_height = cnn_model.pyra.dimy;
num_levels = cnn_model.pyra.num_levels;
stride = cnn_model.pyra.stride;
im = single(im);
% Convert to BGR
im = im(:,:,[3 2 1]);
% Subtract mean (mean of the image mean--one mean per channel)
im = bsxfun(@minus, im, cnn_model.mu);
% scale = base scale relative to input image
im_sz = size(im);
if im_sz(1) > im_sz(2)
height = batch_height;
width = NaN;
scale = height / im_sz(1);
else
height = NaN;
width = batch_width;
scale = width / im_sz(2);
end
im_orig = im;
batch = zeros(batch_width, batch_height, 3, num_levels, 'single');
alpha = cnn_model.pyra.scale_factor;
scales = scale*(alpha.^-(0:num_levels-1))';
level_sizes = zeros(num_levels, 2);
for i = 0:num_levels-1
if i == 0
im = imresize(im_orig, [height width], 'bilinear');
else
im = imresize(im_orig, scales(i+1), 'bilinear');
end
im_sz = size(im);
im_sz = im_sz(1:2);
level_sizes(i+1, :) = ceil((im_sz - 1) / stride + 1);
% Make width the fastest dimension (for caffe)
im = permute(im, [2 1 3]);
batch(1:im_sz(2), 1:im_sz(1), :, i+1) = im;
end