buildSCFpyr.m 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. % [PYR, INDICES, STEERMTX, HARMONICS] = buildSCFpyr(IM, HEIGHT, ORDER, TWIDTH)
  2. %
  3. % This is a modified version of buildSFpyr, that constructs a
  4. % complex-valued steerable pyramid using Hilbert-transform pairs
  5. % of filters. Note that the imaginary parts will *not* be steerable.
  6. %
  7. % To reconstruct from this representation, either call reconSFpyr
  8. % on the real part of the pyramid, *or* call reconSCFpyr which will
  9. % use both real and imaginary parts (forcing analyticity).
  10. %
  11. % Description of this transform appears in: Portilla & Simoncelli,
  12. % Int'l Journal of Computer Vision, 40(1):49-71, Oct 2000.
  13. % Further information: http://www.cns.nyu.edu/~eero/STEERPYR/
  14. % Original code: Eero Simoncelli, 5/97.
  15. % Modified by Javier Portilla to return complex (quadrature pair) channels,
  16. % 9/97.
  17. function [pyr,pind,steermtx,harmonics] = buildSCFpyr(im, ht, order, twidth)
  18. %-----------------------------------------------------------------
  19. %% DEFAULTS:
  20. max_ht = floor(log2(min(size(im)))) - 2;
  21. if (exist('ht') ~= 1)
  22. ht = max_ht;
  23. else
  24. if (ht > max_ht)
  25. error(sprintf('Cannot build pyramid higher than %d levels.',max_ht));
  26. end
  27. end
  28. if (exist('order') ~= 1)
  29. order = 3;
  30. elseif ((order > 15) | (order < 0))
  31. fprintf(1,'Warning: ORDER must be an integer in the range [0,15]. Truncating.\n');
  32. order = min(max(order,0),15);
  33. else
  34. order = round(order);
  35. end
  36. nbands = order+1;
  37. if (exist('twidth') ~= 1)
  38. twidth = 1;
  39. elseif (twidth <= 0)
  40. fprintf(1,'Warning: TWIDTH must be positive. Setting to 1.\n');
  41. twidth = 1;
  42. end
  43. %-----------------------------------------------------------------
  44. %% Steering stuff:
  45. if (mod((nbands),2) == 0)
  46. harmonics = [0:(nbands/2)-1]'*2 + 1;
  47. else
  48. harmonics = [0:(nbands-1)/2]'*2;
  49. end
  50. steermtx = steer2HarmMtx(harmonics, pi*[0:nbands-1]/nbands, 'even');
  51. %-----------------------------------------------------------------
  52. dims = size(im);
  53. ctr = ceil((dims+0.5)/2);
  54. [xramp,yramp] = meshgrid( ([1:dims(2)]-ctr(2))./(dims(2)/2), ...
  55. ([1:dims(1)]-ctr(1))./(dims(1)/2) );
  56. angle = atan2(yramp,xramp);
  57. log_rad = sqrt(xramp.^2 + yramp.^2);
  58. log_rad(ctr(1),ctr(2)) = log_rad(ctr(1),ctr(2)-1);
  59. log_rad = log2(log_rad);
  60. %% Radial transition function (a raised cosine in log-frequency):
  61. [Xrcos,Yrcos] = rcosFn(twidth,(-twidth/2),[0 1]);
  62. Yrcos = sqrt(Yrcos);
  63. YIrcos = sqrt(1.0 - Yrcos.^2);
  64. lo0mask = pointOp(log_rad, YIrcos, Xrcos(1), Xrcos(2)-Xrcos(1), 0);
  65. imdft = fftshift(fft2(im));
  66. lo0dft = imdft .* lo0mask;
  67. [pyr,pind] = buildSCFpyrLevs(lo0dft, log_rad, Xrcos, Yrcos, angle, ht, nbands);
  68. hi0mask = pointOp(log_rad, Yrcos, Xrcos(1), Xrcos(2)-Xrcos(1), 0);
  69. hi0dft = imdft .* hi0mask;
  70. hi0 = ifft2(ifftshift(hi0dft));
  71. pyr = [real(hi0(:)) ; pyr];
  72. pind = [size(hi0); pind];