buildSFpyr.m 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. % [PYR, INDICES, STEERMTX, HARMONICS] = buildSFpyr(IM, HEIGHT, ORDER, TWIDTH)
  2. %
  3. % Construct a steerable pyramid on matrix IM, in the Fourier domain.
  4. % This is similar to buildSpyr, except that:
  5. %
  6. % + Reconstruction is exact (within floating point errors)
  7. % + It can produce any number of orientation bands.
  8. % - Typically slower, especially for non-power-of-two sizes.
  9. % - Boundary-handling is circular.
  10. %
  11. % HEIGHT (optional) specifies the number of pyramid levels to build. Default
  12. % is maxPyrHt(size(IM),size(FILT));
  13. %
  14. % The squared radial functions tile the Fourier plane, with a raised-cosine
  15. % falloff. Angular functions are cos(theta-k\pi/(K+1))^K, where K is
  16. % the ORDER (one less than the number of orientation bands, default= 3).
  17. %
  18. % TWIDTH is the width of the transition region of the radial lowpass
  19. % function, in octaves (default = 1, which gives a raised cosine for
  20. % the bandpass filters).
  21. %
  22. % PYR is a vector containing the N pyramid subbands, ordered from fine
  23. % to coarse. INDICES is an Nx2 matrix containing the sizes of
  24. % each subband. This is compatible with the MatLab Wavelet toolbox.
  25. % See the function STEER for a description of STEERMTX and HARMONICS.
  26. % Eero Simoncelli, 5/97.
  27. % See http://www.cns.nyu.edu/~eero/STEERPYR/ for more
  28. % information about the Steerable Pyramid image decomposition.
  29. function [pyr,pind,steermtx,harmonics] = buildSFpyr(im, ht, order, twidth)
  30. %-----------------------------------------------------------------
  31. %% DEFAULTS:
  32. max_ht = floor(log2(min(size(im)))) - 2;
  33. if (exist('ht') ~= 1)
  34. ht = max_ht;
  35. else
  36. if (ht > max_ht)
  37. error(sprintf('Cannot build pyramid higher than %d levels.',max_ht));
  38. end
  39. end
  40. if (exist('order') ~= 1)
  41. order = 3;
  42. elseif ((order > 15) | (order < 0))
  43. fprintf(1,'Warning: ORDER must be an integer in the range [0,15]. Truncating.\n');
  44. order = min(max(order,0),15);
  45. else
  46. order = round(order);
  47. end
  48. nbands = order+1;
  49. if (exist('twidth') ~= 1)
  50. twidth = 1;
  51. elseif (twidth <= 0)
  52. fprintf(1,'Warning: TWIDTH must be positive. Setting to 1.\n');
  53. twidth = 1;
  54. end
  55. %-----------------------------------------------------------------
  56. %% Steering stuff:
  57. if (mod((nbands),2) == 0)
  58. harmonics = [0:(nbands/2)-1]'*2 + 1;
  59. else
  60. harmonics = [0:(nbands-1)/2]'*2;
  61. end
  62. steermtx = steer2HarmMtx(harmonics, pi*[0:nbands-1]/nbands, 'even');
  63. %-----------------------------------------------------------------
  64. dims = size(im);
  65. ctr = ceil((dims+0.5)/2);
  66. [xramp,yramp] = meshgrid( ([1:dims(2)]-ctr(2))./(dims(2)/2), ...
  67. ([1:dims(1)]-ctr(1))./(dims(1)/2) );
  68. angle = atan2(yramp,xramp);
  69. log_rad = sqrt(xramp.^2 + yramp.^2);
  70. log_rad(ctr(1),ctr(2)) = log_rad(ctr(1),ctr(2)-1);
  71. log_rad = log2(log_rad);
  72. %% Radial transition function (a raised cosine in log-frequency):
  73. [Xrcos,Yrcos] = rcosFn(twidth,(-twidth/2),[0 1]);
  74. Yrcos = sqrt(Yrcos);
  75. YIrcos = sqrt(1.0 - Yrcos.^2);
  76. lo0mask = pointOp(log_rad, YIrcos, Xrcos(1), Xrcos(2)-Xrcos(1), 0);
  77. imdft = fftshift(fft2(im));
  78. lo0dft = imdft .* lo0mask;
  79. [pyr,pind] = buildSFpyrLevs(lo0dft, log_rad, Xrcos, Yrcos, angle, ht, nbands);
  80. hi0mask = pointOp(log_rad, Yrcos, Xrcos(1), Xrcos(2)-Xrcos(1), 0);
  81. hi0dft = imdft .* hi0mask;
  82. hi0 = ifft2(ifftshift(hi0dft));
  83. pyr = [real(hi0(:)) ; pyr];
  84. pind = [size(hi0); pind];