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