-
Notifications
You must be signed in to change notification settings - Fork 8
/
buildSFpyr.m
executable file
·102 lines (84 loc) · 3.18 KB
/
buildSFpyr.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
% [PYR, INDICES, STEERMTX, HARMONICS] = buildSFpyr(IM, HEIGHT, ORDER, TWIDTH)
%
% Construct a steerable pyramid on matrix IM, in the Fourier domain.
% This is similar to buildSpyr, except that:
%
% + Reconstruction is exact (within floating point errors)
% + It can produce any number of orientation bands.
% - Typically slower, especially for non-power-of-two sizes.
% - Boundary-handling is circular.
%
% HEIGHT (optional) specifies the number of pyramid levels to build. Default
% is maxPyrHt(size(IM),size(FILT));
%
% The squared radial functions tile the Fourier plane, with a raised-cosine
% falloff. Angular functions are cos(theta-k\pi/(K+1))^K, where K is
% the ORDER (one less than the number of orientation bands, default= 3).
%
% TWIDTH is the width of the transition region of the radial lowpass
% function, in octaves (default = 1, which gives a raised cosine for
% the bandpass filters).
%
% PYR is a vector containing the N pyramid subbands, ordered from fine
% to coarse. INDICES is an Nx2 matrix containing the sizes of
% each subband. This is compatible with the MatLab Wavelet toolbox.
% See the function STEER for a description of STEERMTX and HARMONICS.
% Eero Simoncelli, 5/97.
% See http://www.cns.nyu.edu/~eero/STEERPYR/ for more
% information about the Steerable Pyramid image decomposition.
function [pyr,pind,steermtx,harmonics] = buildSFpyr(im, ht, order, twidth)
%-----------------------------------------------------------------
%% DEFAULTS:
max_ht = floor(log2(min(size(im)))) - 2;
if (exist('ht') ~= 1)
ht = max_ht;
else
if (ht > max_ht)
error(sprintf('Cannot build pyramid higher than %d levels.',max_ht));
end
end
if (exist('order') ~= 1)
order = 3;
elseif ((order > 15) | (order < 0))
fprintf(1,'Warning: ORDER must be an integer in the range [0,15]. Truncating.\n');
order = min(max(order,0),15);
else
order = round(order);
end
nbands = order+1;
if (exist('twidth') ~= 1)
twidth = 1;
elseif (twidth <= 0)
fprintf(1,'Warning: TWIDTH must be positive. Setting to 1.\n');
twidth = 1;
end
%-----------------------------------------------------------------
%% Steering stuff:
if (mod((nbands),2) == 0)
harmonics = [0:(nbands/2)-1]'*2 + 1;
else
harmonics = [0:(nbands-1)/2]'*2;
end
steermtx = steer2HarmMtx(harmonics, pi*[0:nbands-1]/nbands, 'even');
%-----------------------------------------------------------------
dims = size(im);
ctr = ceil((dims+0.5)/2);
[xramp,yramp] = meshgrid( ([1:dims(2)]-ctr(2))./(dims(2)/2), ...
([1:dims(1)]-ctr(1))./(dims(1)/2) );
angle = atan2(yramp,xramp);
log_rad = sqrt(xramp.^2 + yramp.^2);
log_rad(ctr(1),ctr(2)) = log_rad(ctr(1),ctr(2)-1);
log_rad = log2(log_rad);
%% Radial transition function (a raised cosine in log-frequency):
[Xrcos,Yrcos] = rcosFn(twidth,(-twidth/2),[0 1]);
Yrcos = sqrt(Yrcos);
YIrcos = sqrt(1.0 - Yrcos.^2);
lo0mask = pointOp(log_rad, YIrcos, Xrcos(1), Xrcos(2)-Xrcos(1), 0);
imdft = fftshift(fft2(im));
lo0dft = imdft .* lo0mask;
[pyr,pind] = buildSFpyrLevs(lo0dft, log_rad, Xrcos, Yrcos, angle, ht, nbands);
hi0mask = pointOp(log_rad, Yrcos, Xrcos(1), Xrcos(2)-Xrcos(1), 0);
hi0dft = imdft .* hi0mask;
hi0 = ifft2(ifftshift(hi0dft));
pyr = [real(hi0(:)) ; pyr];
pind = [size(hi0); pind];