reconSCFpyr.m 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. % RES = reconSCFpyr(PYR, INDICES, LEVS, BANDS, TWIDTH)
  2. %
  3. % The inverse of buildSCFpyr: Reconstruct image from its complex steerable pyramid representation,
  4. % in the Fourier domain.
  5. %
  6. % The image is reconstructed by forcing the complex subbands to be analytic
  7. % (zero on half of the 2D Fourier plane, as they are supossed to be unless
  8. % they have being modified), and reconstructing from the real part of those
  9. % analytic subbands. That is equivalent to compute the Hilbert transforms of
  10. % the imaginary parts of the subbands, average them with their real
  11. % counterparts, and then reconstructing from the resulting real subbands.
  12. %
  13. % PYR is a vector containing the N pyramid subbands, ordered from fine
  14. % to coarse. INDICES is an Nx2 matrix containing the sizes of
  15. % each subband. This is compatible with the MatLab Wavelet toolbox.
  16. %
  17. % LEVS (optional) should be a list of levels to include, or the string
  18. % 'all' (default). 0 corresonds to the residual highpass subband.
  19. % 1 corresponds to the finest oriented scale. The lowpass band
  20. % corresponds to number spyrHt(INDICES)+1.
  21. %
  22. % BANDS (optional) should be a list of bands to include, or the string
  23. % 'all' (default). 1 = vertical, rest proceeding anti-clockwise.
  24. %
  25. % TWIDTH is the width of the transition region of the radial lowpass
  26. % function, in octaves (default = 1, which gives a raised cosine for
  27. % the bandpass filters).
  28. % Javier Portilla, 7/04, basing on Eero Simoncelli's Matlab Pyrtools code
  29. % and our common code on texture synthesis (textureSynthesis.m).
  30. function res = reconSCFpyr(pyr, indices, levs, bands, twidth)
  31. %%------------------------------------------------------------
  32. %% DEFAULTS:
  33. if ~exist('levs'),
  34. levs = 'all';
  35. end
  36. if ~exist('bands')
  37. bands = 'all';
  38. end
  39. if ~exist('twidth'),
  40. twidth = 1;
  41. elseif (twidth <= 0)
  42. fprintf(1,'Warning: TWIDTH must be positive. Setting to 1.\n');
  43. twidth = 1;
  44. end
  45. %%------------------------------------------------------------
  46. pind = indices;
  47. Nsc = log2(pind(1,1)/pind(end,1));
  48. Nor = (size(pind,1)-2)/Nsc;
  49. for nsc = 1:Nsc,
  50. firstBnum = (nsc-1)*Nor+2;
  51. %% Re-create analytic subbands
  52. dims = pind(firstBnum,:);
  53. ctr = ceil((dims+0.5)/2);
  54. ang = mkAngle(dims, 0, ctr);
  55. ang(ctr(1),ctr(2)) = -pi/2;
  56. for nor = 1:Nor,
  57. nband = (nsc-1)*Nor+nor+1;
  58. ind = pyrBandIndices(pind,nband);
  59. ch = pyrBand(pyr, pind, nband);
  60. ang0 = pi*(nor-1)/Nor;
  61. xang = mod(ang-ang0+pi, 2*pi) - pi;
  62. amask = 2*(abs(xang) < pi/2) + (abs(xang) == pi/2);
  63. amask(ctr(1),ctr(2)) = 1;
  64. amask(:,1) = 1;
  65. amask(1,:) = 1;
  66. amask = fftshift(amask);
  67. ch = ifft2(amask.*fft2(ch)); % "Analytic" version
  68. %f = 1.000008; % With this factor the reconstruction SNR goes up around 6 dB!
  69. f = 1;
  70. ch = f*0.5*real(ch); % real part
  71. pyr(ind) = ch;
  72. end % nor
  73. end % nsc
  74. res = reconSFpyr(pyr, indices, levs, bands, twidth);