summaryrefslogtreecommitdiffstats
path: root/SD-VBS/common/toolbox/MultiNcut/cimgnbmap.c
diff options
context:
space:
mode:
authorLeo Chan <leochanj@live.unc.edu>2020-10-22 01:53:21 -0400
committerJoshua Bakita <jbakita@cs.unc.edu>2020-10-22 01:56:35 -0400
commitd17b33131c14864bd1eae275f49a3f148e21cf29 (patch)
tree0d8f77922e8d193cb0f6edab83018f057aad64a0 /SD-VBS/common/toolbox/MultiNcut/cimgnbmap.c
parent601ed25a4c5b66cb75315832c15613a727db2c26 (diff)
Squashed commit of the sb-vbs branch.
Includes the SD-VBS benchmarks modified to: - Use libextra to loop as realtime jobs - Preallocate memory before starting their main computation - Accept input via stdin instead of via argc Does not include the SD-VBS matlab code. Fixes libextra execution in LITMUS^RT.
Diffstat (limited to 'SD-VBS/common/toolbox/MultiNcut/cimgnbmap.c')
-rwxr-xr-xSD-VBS/common/toolbox/MultiNcut/cimgnbmap.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/SD-VBS/common/toolbox/MultiNcut/cimgnbmap.c b/SD-VBS/common/toolbox/MultiNcut/cimgnbmap.c
new file mode 100755
index 0000000..44af715
--- /dev/null
+++ b/SD-VBS/common/toolbox/MultiNcut/cimgnbmap.c
@@ -0,0 +1,198 @@
1/*================================================================
2* function [i,j] = cimgnbmap([nr,nc], nb_r, sample_rate)
3* computes the neighbourhood index matrix of an image,
4* with each neighbourhood sampled.
5* Input:
6* [nr,nc] = image size
7* nb_r = neighbourhood radius, could be [r_i,r_j] for i,j
8* sample_rate = sampling rate, default = 1
9* Output:
10* [i,j] = each is a column vector, give indices of neighbour pairs
11* UINT32 type
12* i is of total length of valid elements, 0 for first row
13* j is of length nr * nc + 1
14*
15* See also: imgnbmap.c, id2cind.m
16*
17* Examples:
18* [i,j] = imgnbmap(10, 20); % [10,10] are assumed
19*
20* Stella X. Yu, Nov 12, 2001.
21
22% test sequence:
23nr = 15;
24nc = 15;
25nbr = 1;
26[i,j] = cimgnbmap([nr,nc], nbr);
27mask = csparse(i,j,ones(length(i),1),nr*nc);
28show_dist_w(rand(nr,nc),mask)
29
30*=================================================================*/
31
32# include "mex.h"
33# include "math.h"
34
35void mexFunction(
36 int nargout,
37 mxArray *out[],
38 int nargin,
39 const mxArray *in[]
40)
41{
42 /* declare variables */
43 int nr, nc, np, nb, total;
44 double *dim, sample_rate;
45 int r_i, r_j, a1, a2, b1, b2, self, neighbor;
46 int i, j, k, s, t, nsamp, th_rand, no_sample;
47 /* unsigned long *p, *qi, *qj; */
48 unsigned int *p, *qi, *qj;
49
50 /* check argument */
51 if (nargin < 2) {
52 mexErrMsgTxt("Two input arguments required");
53 }
54 if (nargout> 2) {
55 mexErrMsgTxt("Too many output arguments.");
56 }
57
58 /* get image size */
59 i = mxGetM(in[0]);
60 j = mxGetN(in[0]);
61 dim = mxGetData(in[0]);
62 nr = (int)dim[0];
63 if (j>1 || i>1) {
64 nc = (int)dim[1];
65 } else {
66 nc = nr;
67 }
68 np = nr * nc;
69
70 /* get neighbourhood size */
71 i = mxGetM(in[1]);
72 j = mxGetN(in[1]);
73 dim = mxGetData(in[1]);
74 r_i = (int)dim[0];
75 if (j>1 || i>1) {
76 r_j = (int)dim[1];
77 } else {
78 r_j = r_i;
79 }
80 if (r_i<0) { r_i = 0; }
81 if (r_j<0) { r_j = 0; }
82
83 /* get sample rate */
84 if (nargin==3) {
85 sample_rate = (mxGetM(in[2])==0) ? 1: mxGetScalar(in[2]);
86 } else {
87 sample_rate = 1;
88 }
89 /* prepare for random number generator */
90 if (sample_rate<1) {
91 srand( (unsigned)time( NULL ) );
92 th_rand = (int)ceil((double)RAND_MAX * sample_rate);
93 no_sample = 0;
94 } else {
95 sample_rate = 1;
96 th_rand = RAND_MAX;
97 no_sample = 1;
98 }
99
100 /* figure out neighbourhood size */
101
102 nb = (r_i + r_i + 1) * (r_j + r_j + 1);
103 if (nb>np) {
104 nb = np;
105 }
106 nb = (int)ceil((double)nb * sample_rate);
107/*printf("nb=%d\n",nb);*/
108 /* intermediate data structure */
109 /* p = mxCalloc(np * (nb+1), sizeof(unsigned long)); */
110 p = mxCalloc(np * (nb+1), sizeof(unsigned int));
111 if (p==NULL) {
112 mexErrMsgTxt("Not enough space for my computation.");
113 }
114
115 /* computation */
116 total = 0;
117 for (j=0; j<nc; j++) {
118 /*printf("j=%d\n",j);*/
119 for (i=0; i<nr; i++) {
120
121 self = i + j * nr;
122
123 /* put self in, otherwise the index is not ordered */
124 p[self] = p[self] + 1;
125 p[self+p[self]*np] = self;
126
127 /* j range */
128 b1 = j;
129 b2 = j + r_j;
130 if (b2>=nc) { b2 = nc-1; }
131
132 /* i range */
133 a1 = i - r_i;
134 if (a1<0) { a1 = 0; }
135 a2 = i + r_i;
136 if (a2>=nr) { a2 = nr-1; }
137
138 /* number of more samples needed */
139 nsamp = nb - p[self];
140 /*if (nsamp<0)
141 {printf("nsamp=%d\n",nsamp);}*/
142 k = 0;
143 t = b1;
144 s = i + 1;
145 if (s>a2) {
146 s = a1;
147 t = t + 1;
148 }
149
150
151 while (k<nsamp && t<=b2) {
152
153 if (no_sample || (rand()<th_rand)) {
154 k = k + 1;
155 neighbor = s + t * nr;
156 p[self] = p[self] + 1;
157 p[self+p[self]*np] = neighbor;
158 p[neighbor] = p[neighbor] + 1;
159 p[neighbor+p[neighbor]*np] = self;
160 }
161
162 s = s + 1;
163 if (s>a2) {
164 s = a1;
165 t = t + 1;
166 }
167 } /* k */
168 total = total + p[self];
169 } /* i */
170
171 } /* j */
172
173 /* i, j */
174
175 out[0] = mxCreateNumericMatrix(total, 1, mxUINT32_CLASS, mxREAL);
176 out[1] = mxCreateNumericMatrix(np+1, 1, mxUINT32_CLASS, mxREAL);
177 qi = mxGetData(out[0]);
178 qj = mxGetData(out[1]);
179
180 if (out[0]==NULL || out[1]==NULL) {
181 mexErrMsgTxt("Not enough space for the output matrix.");
182 }
183
184 total = 0;
185 for (j=0; j<np; j++) {
186 qj[j] = total;
187 s = j + np;
188 for (t=0; t<p[j]; t++) {
189 qi[total] = p[s];
190 total = total + 1;
191 s = s + np;
192 }
193 }
194 qj[np] = total;
195
196 mxFree(p);
197
198}