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