idamnjanovic@60: function [varargout] = reggrid(sz,num,mode) idamnjanovic@60: %REGGRID Regular sampling grid. idamnjanovic@60: % [I1,I2,...,Ip] = REGGRID([N1 N2 ... Np], NUM) returns the indices idamnjanovic@60: % of a regular uniform sampling grid over a p-dimensional matrix with idamnjanovic@60: % dimensions N1xN2x...xNp. NUM is the minimal number of required samples, idamnjanovic@60: % and it is ensured that the actual number of samples, given by idamnjanovic@60: % length(I1)xlength(I2)x...xlength(Ip), is at least as large as NUM. idamnjanovic@60: % idamnjanovic@60: % [I1,I2,...,Ip] = REGGRID([N1 N2 ... Np], NUM,'MODE') specifies the idamnjanovic@60: % method for distributing the samples along each dimension. Valid modes idamnjanovic@60: % include 'eqdist' (the default mode) and 'eqnum'. 'eqdist' indicates an idamnjanovic@60: % equal distance between the samples in each dimension, while 'eqnum' idamnjanovic@60: % indicates an equal number of samples in each dimension. idamnjanovic@60: % idamnjanovic@60: % Notes about MODE: idamnjanovic@60: % idamnjanovic@60: % 1. The 'eqnum' mode will generally fail when the p-th root of NUM idamnjanovic@60: % (i.e. NUM^(1/p)) is larger than min([N1 N2 ... Np]). Thus 'eqdist' is idamnjanovic@60: % the more useful choice for sampling an arbitrary number of samples idamnjanovic@60: % from the matrix (up to the total number of matrix entries). idamnjanovic@60: % idamnjanovic@60: % 2. In both modes, the equality (of the distance between samples, or idamnjanovic@60: % the number of samples in each dimension) is only approximate. This is idamnjanovic@60: % because REGGRID attempts to maintain the appropriate equality while at idamnjanovic@60: % the same time find a sampling pattern where the total number of idamnjanovic@60: % samples is as close as possible to NUM. In general, the larger {Ni} idamnjanovic@60: % and NUM are, the tighter the equality. idamnjanovic@60: % idamnjanovic@60: % Example: Sample a set of blocks uniformly from a 2D image. idamnjanovic@60: % idamnjanovic@60: % n = 512; blocknum = 20000; blocksize = [8 8]; idamnjanovic@60: % im = rand(n,n); idamnjanovic@60: % [i1,i2] = reggrid(size(im)-blocksize+1, blocknum); idamnjanovic@60: % blocks = sampgrid(im, blocksize, i1, i2); idamnjanovic@60: % idamnjanovic@60: % See also SAMPGRID. idamnjanovic@60: idamnjanovic@60: % Ron Rubinstein idamnjanovic@60: % Computer Science Department idamnjanovic@60: % Technion, Haifa 32000 Israel idamnjanovic@60: % ronrubin@cs idamnjanovic@60: % idamnjanovic@60: % November 2007 idamnjanovic@60: idamnjanovic@60: dim = length(sz); idamnjanovic@60: idamnjanovic@60: if (nargin<3) idamnjanovic@60: mode = 'eqdist'; idamnjanovic@60: end idamnjanovic@60: idamnjanovic@60: if (any(sz<1)) idamnjanovic@60: error(['Invalid matrix size : [' num2str(sz) ']']); idamnjanovic@60: end idamnjanovic@60: idamnjanovic@60: if (num > prod(sz)) idamnjanovic@60: warning(['Invalid number of samples, returning maximum number of samples.']); idamnjanovic@60: elseif (num <= 0) idamnjanovic@60: if (num < 0) idamnjanovic@60: warning('Invalid number of samples, assuming 0 samples.'); idamnjanovic@60: end idamnjanovic@60: for i = 1:length(sz) idamnjanovic@60: varargout{i} = []; idamnjanovic@60: end idamnjanovic@60: return; idamnjanovic@60: end idamnjanovic@60: idamnjanovic@60: idamnjanovic@60: if (strcmp(mode,'eqdist')) idamnjanovic@60: idamnjanovic@60: % approximate distance between samples: total volume divided by number of idamnjanovic@60: % samples gives the average volume per sample. then, taking the p-th root idamnjanovic@60: % gives the average distance between samples idamnjanovic@60: d = (prod(sz)/num)^(1/dim); idamnjanovic@60: idamnjanovic@60: % compute the initial guess for number of samples in each dimension. idamnjanovic@60: % then, while total number of samples is too large, decrese the number of idamnjanovic@60: % samples by one in the dimension where the samples are the most crowded. idamnjanovic@60: % finally, do the opposite process until just passing num, so the final idamnjanovic@60: % number of samples is the closest to num from above. idamnjanovic@60: idamnjanovic@60: n = min(max(round(sz/d),1),sz); % set n so that it saturates at 1 and sz idamnjanovic@60: idamnjanovic@60: active_dims = find(n>1); % dimensions where the sample num can be reduced idamnjanovic@60: while(prod(n)>num && ~isempty(active_dims)) idamnjanovic@60: [y,id] = min((sz(active_dims)-1)./n(active_dims)); idamnjanovic@60: n(active_dims(id)) = n(active_dims(id))-1; idamnjanovic@60: if (n(active_dims(id)) < 2) idamnjanovic@60: active_dims = find(n>1); idamnjanovic@60: end idamnjanovic@60: end idamnjanovic@60: idamnjanovic@60: active_dims = find(n= sz(active_dims(id))) idamnjanovic@60: active_dims = find(n1); idamnjanovic@60: while(prod(n)>num && ~isempty(active_dims)) idamnjanovic@60: [y,id] = min((sz(active_dims)-1)./n(active_dims)); idamnjanovic@60: n(active_dims(id)) = n(active_dims(id))-1; idamnjanovic@60: if (n(active_dims(id)) < 2) idamnjanovic@60: active_dims = find(n>1); idamnjanovic@60: end idamnjanovic@60: end idamnjanovic@60: idamnjanovic@60: active_dims = find(n= sz(active_dims(id))) idamnjanovic@60: active_dims = find(n