showSpyr.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. % RANGE = showSpyr (PYR, INDICES, RANGE, GAP, LEVEL_SCALE_FACTOR)
  2. %
  3. % Display a steerable pyramid, specified by PYR and INDICES
  4. % (see buildSpyr), in the current figure. The highpass band is not shown.
  5. %
  6. % RANGE is a 2-vector specifying the values that map to black and
  7. % white, respectively. These values are scaled by
  8. % LEVEL_SCALE_FACTOR^(lev-1) for bands at each level. Passing a value
  9. % of 'auto1' sets RANGE to the min and max values of MATRIX. 'auto2'
  10. % sets RANGE to 3 standard deviations below and above 0.0. In both of
  11. % these cases, the lowpass band is independently scaled. A value of
  12. % 'indep1' sets the range of each subband independently, as in a call
  13. % to showIm(subband,'auto1'). Similarly, 'indep2' causes each subband
  14. % to be scaled independently as if by showIm(subband,'indep2').
  15. % The default value for RANGE is 'auto2'.
  16. %
  17. % GAP (optional, default=1) specifies the gap in pixels to leave
  18. % between subbands.
  19. %
  20. % LEVEL_SCALE_FACTOR indicates the relative scaling between pyramid
  21. % levels. This should be set to the sum of the kernel taps of the
  22. % lowpass filter used to construct the pyramid (default is 2, which is
  23. % correct for L2-normalized filters.
  24. % Eero Simoncelli, 2/97.
  25. function [range] = showSpyr(pyr, pind, range, gap, scale);
  26. nbands = spyrNumBands(pind);
  27. %------------------------------------------------------------
  28. %% OPTIONAL ARGS:
  29. if (exist('range') ~= 1)
  30. range = 'auto2';
  31. end
  32. if (exist('gap') ~= 1)
  33. gap = 1;
  34. end
  35. if (exist('scale') ~= 1)
  36. scale = 2;
  37. end
  38. %------------------------------------------------------------
  39. ht = spyrHt(pind);
  40. nind = size(pind,1);
  41. %% Auto range calculations:
  42. if strcmp(range,'auto1')
  43. range = ones(nind,1);
  44. band = spyrHigh(pyr,pind);
  45. [mn,mx] = range2(band);
  46. for lnum = 1:ht
  47. for bnum = 1:nbands
  48. band = spyrBand(pyr,pind,lnum,bnum)/(scale^(lnum-1));
  49. range((lnum-1)*nbands+bnum+1) = scale^(lnum-1);
  50. [bmn,bmx] = range2(band);
  51. mn = min(mn, bmn);
  52. mx = max(mx, bmx);
  53. end
  54. end
  55. range = range * [mn mx]; % outer product
  56. band = pyrLow(pyr,pind);
  57. [mn,mx] = range2(band);
  58. range(nind,:) = [mn, mx];
  59. elseif strcmp(range,'indep1')
  60. range = zeros(nind,2);
  61. for bnum = 1:nind
  62. band = pyrBand(pyr,pind,bnum);
  63. [mn,mx] = range2(band);
  64. range(bnum,:) = [mn mx];
  65. end
  66. elseif strcmp(range,'auto2')
  67. range = ones(nind,1);
  68. band = spyrHigh(pyr,pind);
  69. sqsum = sum(sum(band.^2)); numpixels = prod(size(band));
  70. for lnum = 1:ht
  71. for bnum = 1:nbands
  72. band = spyrBand(pyr,pind,lnum,bnum)/(scale^(lnum-1));
  73. sqsum = sqsum + sum(sum(band.^2));
  74. numpixels = numpixels + prod(size(band));
  75. range((lnum-1)*nbands+bnum+1) = scale^(lnum-1);
  76. end
  77. end
  78. stdev = sqrt(sqsum/(numpixels-1));
  79. range = range * [ -3*stdev 3*stdev ]; % outer product
  80. band = pyrLow(pyr,pind);
  81. av = mean2(band); stdev = sqrt(var2(band));
  82. range(nind,:) = [av-2*stdev,av+2*stdev];
  83. elseif strcmp(range,'indep2')
  84. range = zeros(nind,2);
  85. for bnum = 1:(nind-1)
  86. band = pyrBand(pyr,pind,bnum);
  87. stdev = sqrt(var2(band));
  88. range(bnum,:) = [ -3*stdev 3*stdev ];
  89. end
  90. band = pyrLow(pyr,pind);
  91. av = mean2(band); stdev = sqrt(var2(band));
  92. range(nind,:) = [av-2*stdev,av+2*stdev];
  93. elseif isstr(range)
  94. error(sprintf('Bad RANGE argument: %s',range))
  95. elseif ((size(range,1) == 1) & (size(range,2) == 2))
  96. scales = scale.^[0:(ht-1)];
  97. scales = ones(nbands,1) * scales; %outer product
  98. scales = [1; scales(:); scale^ht]; %tack on highpass and lowpass
  99. range = scales * range; % outer product
  100. band = pyrLow(pyr,pind);
  101. range(nind,:) = range(nind,:) + mean2(band) - mean(range(nind,:));
  102. end
  103. % CLEAR FIGURE:
  104. clf;
  105. colormap(gray);
  106. cmap = get(gcf,'Colormap');
  107. nshades = size(cmap,1);
  108. % Find background color index:
  109. clr = get(gcf,'Color');
  110. bg = 1;
  111. dist = norm(cmap(bg,:)-clr);
  112. for n = 1:nshades
  113. ndist = norm(cmap(n,:)-clr);
  114. if (ndist < dist)
  115. dist = ndist;
  116. bg = n;
  117. end
  118. end
  119. %% Compute positions of subbands:
  120. llpos = ones(nind,2);
  121. if (nbands == 2)
  122. ncols = 1; nrows = 2;
  123. else
  124. ncols = ceil((nbands+1)/2); nrows = ceil(nbands/2);
  125. end
  126. relpos = [ (1-nrows):0, zeros(1,(ncols-1)); ...
  127. zeros(1,nrows), -1:-1:(1-ncols) ]';
  128. if (nbands > 1)
  129. mvpos = [-1 -1];
  130. else
  131. mvpos = [0 -1];
  132. end
  133. basepos = [0 0];
  134. for lnum = 1:ht
  135. ind1 = (lnum-1)*nbands + 2;
  136. sz = pind(ind1,:)+gap;
  137. basepos = basepos + mvpos .* sz;
  138. if (nbands < 5) % to align edges...
  139. sz = sz + gap*(ht-lnum+1);
  140. end
  141. llpos(ind1:ind1+nbands-1,:) = relpos * diag(sz) + ones(nbands,1)*basepos;
  142. end
  143. % lowpass band
  144. sz = pind(nind-1,:)+gap;
  145. basepos = basepos + mvpos .* sz;
  146. llpos(nind,:) = basepos;
  147. %% Make position list positive, and allocate appropriate image:
  148. llpos = llpos - ones(nind,1)*min(llpos) + 1;
  149. llpos(1,:) = [1 1];
  150. urpos = llpos + pind - 1;
  151. d_im = bg + zeros(max(urpos));
  152. %% Paste bands into image, (im-r1)*(nshades-1)/(r2-r1) + 1.5
  153. for bnum=2:nind
  154. mult = (nshades-1) / (range(bnum,2)-range(bnum,1));
  155. d_im(llpos(bnum,1):urpos(bnum,1), llpos(bnum,2):urpos(bnum,2)) = ...
  156. mult*pyrBand(pyr,pind,bnum) + (1.5-mult*range(bnum,1));
  157. end
  158. hh = image(d_im);
  159. axis('off');
  160. pixelAxes(size(d_im),'full');
  161. set(hh,'UserData',range);