% [PYR, INDICES] = buildWpyr(IM, HEIGHT, FILT, EDGES) % % Construct a separable orthonormal QMF/wavelet pyramid on matrix (or vector) IM. % % HEIGHT (optional) specifies the number of pyramid levels to build. Default % is maxPyrHt(IM,FILT). You can also specify 'auto' to use this value. % % FILT (optional) can be a string naming a standard filter (see % namedFilter), or a vector which will be used for (separable) % convolution. Filter can be of even or odd length, but should be symmetric. % Default = 'qmf9'. EDGES specifies edge-handling, and % defaults to 'reflect1' (see corrDn). % % 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. % Eero Simoncelli, 6/96, based on original lisp code from 1987. function [pyr,pind] = buildWpyr(im, ht, filt, edges) if (nargin < 1) error('First argument (IM) is required'); end %------------------------------------------------------------ %% OPTIONAL ARGS: if (exist('filt') ~= 1) filt = 'qmf9'; end if (exist('edges') ~= 1) edges= 'reflect1'; end if isstr(filt) filt = namedFilter(filt); end if ( (size(filt,1) > 1) & (size(filt,2) > 1) ) error('FILT should be a 1D filter (i.e., a vector)'); else filt = filt(:); end hfilt = modulateFlip(filt); % Stagger sampling if filter is odd-length: if (mod(size(filt,1),2) == 0) stag = 2; else stag = 1; end im_sz = size(im); max_ht = maxPyrHt(im_sz, size(filt,1)); if ( (exist('ht') ~= 1) | (ht == 'auto') ) ht = max_ht; else if (ht > max_ht) error(sprintf('Cannot build pyramid higher than %d levels.',max_ht)); end end if (ht <= 0) pyr = im(:); pind = im_sz; else if (im_sz(2) == 1) lolo = corrDn(im, filt, edges, [2 1], [stag 1]); hihi = corrDn(im, hfilt, edges, [2 1], [2 1]); elseif (im_sz(1) == 1) lolo = corrDn(im, filt', edges, [1 2], [1 stag]); hihi = corrDn(im, hfilt', edges, [1 2], [1 2]); else lo = corrDn(im, filt, edges, [2 1], [stag 1]); hi = corrDn(im, hfilt, edges, [2 1], [2 1]); lolo = corrDn(lo, filt', edges, [1 2], [1 stag]); lohi = corrDn(hi, filt', edges, [1 2], [1 stag]); % horizontal hilo = corrDn(lo, hfilt', edges, [1 2], [1 2]); % vertical hihi = corrDn(hi, hfilt', edges, [1 2], [1 2]); % diagonal end [npyr,nind] = buildWpyr(lolo, ht-1, filt, edges); if ((im_sz(1) == 1) | (im_sz(2) == 1)) pyr = [hihi(:); npyr]; pind = [size(hihi); nind]; else pyr = [lohi(:); hilo(:); hihi(:); npyr]; pind = [size(lohi); size(hilo); size(hihi); nind]; end end