idamnjanovic@60
|
1 function [varargout] = reggrid(sz,num,mode)
|
idamnjanovic@60
|
2 %REGGRID Regular sampling grid.
|
idamnjanovic@60
|
3 % [I1,I2,...,Ip] = REGGRID([N1 N2 ... Np], NUM) returns the indices
|
idamnjanovic@60
|
4 % of a regular uniform sampling grid over a p-dimensional matrix with
|
idamnjanovic@60
|
5 % dimensions N1xN2x...xNp. NUM is the minimal number of required samples,
|
idamnjanovic@60
|
6 % and it is ensured that the actual number of samples, given by
|
idamnjanovic@60
|
7 % length(I1)xlength(I2)x...xlength(Ip), is at least as large as NUM.
|
idamnjanovic@60
|
8 %
|
idamnjanovic@60
|
9 % [I1,I2,...,Ip] = REGGRID([N1 N2 ... Np], NUM,'MODE') specifies the
|
idamnjanovic@60
|
10 % method for distributing the samples along each dimension. Valid modes
|
idamnjanovic@60
|
11 % include 'eqdist' (the default mode) and 'eqnum'. 'eqdist' indicates an
|
idamnjanovic@60
|
12 % equal distance between the samples in each dimension, while 'eqnum'
|
idamnjanovic@60
|
13 % indicates an equal number of samples in each dimension.
|
idamnjanovic@60
|
14 %
|
idamnjanovic@60
|
15 % Notes about MODE:
|
idamnjanovic@60
|
16 %
|
idamnjanovic@60
|
17 % 1. The 'eqnum' mode will generally fail when the p-th root of NUM
|
idamnjanovic@60
|
18 % (i.e. NUM^(1/p)) is larger than min([N1 N2 ... Np]). Thus 'eqdist' is
|
idamnjanovic@60
|
19 % the more useful choice for sampling an arbitrary number of samples
|
idamnjanovic@60
|
20 % from the matrix (up to the total number of matrix entries).
|
idamnjanovic@60
|
21 %
|
idamnjanovic@60
|
22 % 2. In both modes, the equality (of the distance between samples, or
|
idamnjanovic@60
|
23 % the number of samples in each dimension) is only approximate. This is
|
idamnjanovic@60
|
24 % because REGGRID attempts to maintain the appropriate equality while at
|
idamnjanovic@60
|
25 % the same time find a sampling pattern where the total number of
|
idamnjanovic@60
|
26 % samples is as close as possible to NUM. In general, the larger {Ni}
|
idamnjanovic@60
|
27 % and NUM are, the tighter the equality.
|
idamnjanovic@60
|
28 %
|
idamnjanovic@60
|
29 % Example: Sample a set of blocks uniformly from a 2D image.
|
idamnjanovic@60
|
30 %
|
idamnjanovic@60
|
31 % n = 512; blocknum = 20000; blocksize = [8 8];
|
idamnjanovic@60
|
32 % im = rand(n,n);
|
idamnjanovic@60
|
33 % [i1,i2] = reggrid(size(im)-blocksize+1, blocknum);
|
idamnjanovic@60
|
34 % blocks = sampgrid(im, blocksize, i1, i2);
|
idamnjanovic@60
|
35 %
|
idamnjanovic@60
|
36 % See also SAMPGRID.
|
idamnjanovic@60
|
37
|
idamnjanovic@60
|
38 % Ron Rubinstein
|
idamnjanovic@60
|
39 % Computer Science Department
|
idamnjanovic@60
|
40 % Technion, Haifa 32000 Israel
|
idamnjanovic@60
|
41 % ronrubin@cs
|
idamnjanovic@60
|
42 %
|
idamnjanovic@60
|
43 % November 2007
|
idamnjanovic@60
|
44
|
idamnjanovic@60
|
45 dim = length(sz);
|
idamnjanovic@60
|
46
|
idamnjanovic@60
|
47 if (nargin<3)
|
idamnjanovic@60
|
48 mode = 'eqdist';
|
idamnjanovic@60
|
49 end
|
idamnjanovic@60
|
50
|
idamnjanovic@60
|
51 if (any(sz<1))
|
idamnjanovic@60
|
52 error(['Invalid matrix size : [' num2str(sz) ']']);
|
idamnjanovic@60
|
53 end
|
idamnjanovic@60
|
54
|
idamnjanovic@60
|
55 if (num > prod(sz))
|
idamnjanovic@60
|
56 warning(['Invalid number of samples, returning maximum number of samples.']);
|
idamnjanovic@60
|
57 elseif (num <= 0)
|
idamnjanovic@60
|
58 if (num < 0)
|
idamnjanovic@60
|
59 warning('Invalid number of samples, assuming 0 samples.');
|
idamnjanovic@60
|
60 end
|
idamnjanovic@60
|
61 for i = 1:length(sz)
|
idamnjanovic@60
|
62 varargout{i} = [];
|
idamnjanovic@60
|
63 end
|
idamnjanovic@60
|
64 return;
|
idamnjanovic@60
|
65 end
|
idamnjanovic@60
|
66
|
idamnjanovic@60
|
67
|
idamnjanovic@60
|
68 if (strcmp(mode,'eqdist'))
|
idamnjanovic@60
|
69
|
idamnjanovic@60
|
70 % approximate distance between samples: total volume divided by number of
|
idamnjanovic@60
|
71 % samples gives the average volume per sample. then, taking the p-th root
|
idamnjanovic@60
|
72 % gives the average distance between samples
|
idamnjanovic@60
|
73 d = (prod(sz)/num)^(1/dim);
|
idamnjanovic@60
|
74
|
idamnjanovic@60
|
75 % compute the initial guess for number of samples in each dimension.
|
idamnjanovic@60
|
76 % then, while total number of samples is too large, decrese the number of
|
idamnjanovic@60
|
77 % samples by one in the dimension where the samples are the most crowded.
|
idamnjanovic@60
|
78 % finally, do the opposite process until just passing num, so the final
|
idamnjanovic@60
|
79 % number of samples is the closest to num from above.
|
idamnjanovic@60
|
80
|
idamnjanovic@60
|
81 n = min(max(round(sz/d),1),sz); % set n so that it saturates at 1 and sz
|
idamnjanovic@60
|
82
|
idamnjanovic@60
|
83 active_dims = find(n>1); % dimensions where the sample num can be reduced
|
idamnjanovic@60
|
84 while(prod(n)>num && ~isempty(active_dims))
|
idamnjanovic@60
|
85 [y,id] = min((sz(active_dims)-1)./n(active_dims));
|
idamnjanovic@60
|
86 n(active_dims(id)) = n(active_dims(id))-1;
|
idamnjanovic@60
|
87 if (n(active_dims(id)) < 2)
|
idamnjanovic@60
|
88 active_dims = find(n>1);
|
idamnjanovic@60
|
89 end
|
idamnjanovic@60
|
90 end
|
idamnjanovic@60
|
91
|
idamnjanovic@60
|
92 active_dims = find(n<sz); % dimensions where the sample num can be increased
|
idamnjanovic@60
|
93 while(prod(n)<num && ~isempty(active_dims))
|
idamnjanovic@60
|
94 [y,id] = max((sz(active_dims)-1)./n(active_dims));
|
idamnjanovic@60
|
95 n(active_dims(id)) = n(active_dims(id))+1;
|
idamnjanovic@60
|
96 if (n(active_dims(id)) >= sz(active_dims(id)))
|
idamnjanovic@60
|
97 active_dims = find(n<sz);
|
idamnjanovic@60
|
98 end
|
idamnjanovic@60
|
99 end
|
idamnjanovic@60
|
100
|
idamnjanovic@60
|
101 for i = 1:dim
|
idamnjanovic@60
|
102 varargout{i} = round((1:n(i))/n(i)*sz(i));
|
idamnjanovic@60
|
103 varargout{i} = varargout{i} - floor((varargout{i}(1)-1)/2);
|
idamnjanovic@60
|
104 end
|
idamnjanovic@60
|
105
|
idamnjanovic@60
|
106 elseif (strcmp(mode,'eqnum'))
|
idamnjanovic@60
|
107
|
idamnjanovic@60
|
108 % same idea as above
|
idamnjanovic@60
|
109 n = min(max( ones(size(sz)) * round(num^(1/dim)) ,1),sz);
|
idamnjanovic@60
|
110
|
idamnjanovic@60
|
111 active_dims = find(n>1);
|
idamnjanovic@60
|
112 while(prod(n)>num && ~isempty(active_dims))
|
idamnjanovic@60
|
113 [y,id] = min((sz(active_dims)-1)./n(active_dims));
|
idamnjanovic@60
|
114 n(active_dims(id)) = n(active_dims(id))-1;
|
idamnjanovic@60
|
115 if (n(active_dims(id)) < 2)
|
idamnjanovic@60
|
116 active_dims = find(n>1);
|
idamnjanovic@60
|
117 end
|
idamnjanovic@60
|
118 end
|
idamnjanovic@60
|
119
|
idamnjanovic@60
|
120 active_dims = find(n<sz);
|
idamnjanovic@60
|
121 while(prod(n)<num && ~isempty(active_dims))
|
idamnjanovic@60
|
122 [y,id] = max((sz(active_dims)-1)./n(active_dims));
|
idamnjanovic@60
|
123 n(active_dims(id)) = n(active_dims(id))+1;
|
idamnjanovic@60
|
124 if (n(active_dims(id)) >= sz(active_dims(id)))
|
idamnjanovic@60
|
125 active_dims = find(n<sz);
|
idamnjanovic@60
|
126 end
|
idamnjanovic@60
|
127 end
|
idamnjanovic@60
|
128
|
idamnjanovic@60
|
129 for i = 1:dim
|
idamnjanovic@60
|
130 varargout{i} = round((1:n(i))/n(i)*sz(i));
|
idamnjanovic@60
|
131 varargout{i} = varargout{i} - floor((varargout{i}(1)-1)/2);
|
idamnjanovic@60
|
132 end
|
idamnjanovic@60
|
133 else
|
idamnjanovic@60
|
134 error('Invalid sampling mode');
|
idamnjanovic@60
|
135 end
|
idamnjanovic@60
|
136
|