1 /*================================================================
\r
2 * function [i,j] = cimgnbmap([nr,nc], nb_r, sample_rate)
\r
3 * computes the neighbourhood index matrix of an image,
\r
4 * with each neighbourhood sampled.
\r
6 * [nr,nc] = image size
\r
7 * nb_r = neighbourhood radius, could be [r_i,r_j] for i,j
\r
8 * sample_rate = sampling rate, default = 1
\r
10 * [i,j] = each is a column vector, give indices of neighbour pairs
\r
12 * i is of total length of valid elements, 0 for first row
\r
13 * j is of length nr * nc + 1
\r
15 * See also: imgnbmap.c, id2cind.m
\r
18 * [i,j] = imgnbmap(10, 20); % [10,10] are assumed
\r
20 * Stella X. Yu, Nov 12, 2001.
\r
26 [i,j] = cimgnbmap([nr,nc], nbr);
\r
27 mask = csparse(i,j,ones(length(i),1),nr*nc);
\r
28 show_dist_w(rand(nr,nc),mask)
\r
30 *=================================================================*/
\r
43 /* declare variables */
\r
44 int nr, nc, np, nb, total;
\r
45 double *dim, sample_rate;
\r
46 int r_i, r_j, a1, a2, b1, b2, self, neighbor;
\r
47 int i, j, k, s, t, nsamp, th_rand, no_sample;
\r
51 /* check argument */
\r
53 mexErrMsgTxt("Two input arguments required");
\r
56 mexErrMsgTxt("Too many output arguments.");
\r
59 /* get image size */
\r
62 dim = (double *)mxGetData(in[0]);
\r
71 /* get neighbourhood size */
\r
74 dim = (double*)mxGetData(in[1]);
\r
81 if (r_i<0) { r_i = 0; }
\r
82 if (r_j<0) { r_j = 0; }
\r
84 /* get sample rate */
\r
86 sample_rate = (mxGetM(in[2])==0) ? 1: mxGetScalar(in[2]);
\r
90 /* prepare for random number generator */
\r
91 if (sample_rate<1) {
\r
92 srand( (unsigned)time( NULL ) );
\r
93 th_rand = (int)ceil((double)RAND_MAX * sample_rate);
\r
101 /* figure out neighbourhood size */
\r
103 nb = (r_i + r_i + 1) * (r_j + r_j + 1);
\r
107 nb = (int)ceil((double)nb * sample_rate);
\r
109 /* intermediate data structure */
\r
110 p = (unsigned long *)mxCalloc(np * (nb+1), sizeof(unsigned long));
\r
112 mexErrMsgTxt("Not enough space for my computation.");
\r
117 for (j=0; j<nc; j++) {
\r
118 for (i=0; i<nr; i++) {
\r
122 /* put self in, otherwise the index is not ordered */
\r
123 p[self] = p[self] + 1;
\r
124 p[self+p[self]*np] = self;
\r
129 if (b2>=nc) { b2 = nc-1; }
\r
133 if (a1<0) { a1 = 0; }
\r
135 if (a2>=nr) { a2 = nr-1; }
\r
137 /* number of more samples needed */
\r
138 nsamp = nb - p[self];
\r
147 while (k<nsamp && t<=b2) {
\r
148 if (no_sample || (rand()<th_rand)) {
\r
150 neighbor = s + t * nr;
\r
152 p[self] = p[self] + 1;
\r
153 p[self+p[self]*np] = neighbor;
\r
155 p[neighbor] = p[neighbor] + 1;
\r
156 p[neighbor+p[neighbor]*np] = self;
\r
165 total = total + p[self];
\r
170 out[0] = mxCreateNumericMatrix(total, 1, mxUINT32_CLASS, mxREAL);
\r
171 out[1] = mxCreateNumericMatrix(np+1, 1, mxUINT32_CLASS, mxREAL);
\r
172 unsigned int *qi = (unsigned int *)mxGetData(out[0]);
\r
173 unsigned int *qj = (unsigned int *)mxGetData(out[1]);
\r
174 if (out[0]==NULL || out[1]==NULL) {
\r
175 mexErrMsgTxt("Not enough space for the output matrix.");
\r
179 for (j=0; j<np; j++) {
\r
182 for (t=0; t<p[j]; t++) {
\r