Mercurial > hg > minc-tools
comparison progs/mincmorph/kernel_io.c @ 2637:0b9a5b816213
* added mincmorph
* updated README and COPYING
author | Andrew L Janke <a.janke@gmail.com> |
---|---|
date | Wed, 14 Mar 2012 02:57:00 +1000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2636:b0e5228b9c74 | 2637:0b9a5b816213 |
---|---|
1 /* kernel_io.c - reads kernel files */ | |
2 | |
3 #include <volume_io.h> | |
4 #include "kernel_io.h" | |
5 #define MAX_KERNEL_ELEMS 1000 | |
6 | |
7 extern int verbose; | |
8 | |
9 static const STRING KERNEL_FILE_HEADER = "MNI Morphology Kernel File"; | |
10 static const STRING KERNEL_TYPE = "Kernel_Type"; | |
11 static const STRING NORMAL_KERNEL = "Normal_Kernel"; | |
12 static const STRING KERNEL = "Kernel"; | |
13 | |
14 /* inbuilt kernels */ | |
15 int n_inbuilt_kern = 4; | |
16 | |
17 /* returns a new Kernel struct (pointer) */ | |
18 Kernel *new_kernel(int nelems) | |
19 { | |
20 int i, j; | |
21 Kernel *tmp; | |
22 | |
23 ALLOC_VAR_SIZED_STRUCT(tmp, Real, 10); | |
24 | |
25 /* allocate and initialise the Kernel Array */ | |
26 SET_ARRAY_SIZE(tmp->K, 0, nelems, 10); | |
27 for(i = 0; i < nelems; i++){ | |
28 ALLOC(tmp->K[i], KERNEL_DIMS + 1); | |
29 | |
30 for(j = 0; j < KERNEL_DIMS; j++){ | |
31 tmp->K[i][j] = 0.0; | |
32 } | |
33 tmp->K[i][KERNEL_DIMS] = 1.0; | |
34 | |
35 } | |
36 tmp->nelems = nelems; | |
37 | |
38 return tmp; | |
39 } | |
40 | |
41 /* reads in a Kernel from a file */ | |
42 Status input_kernel(const char *kernel_file, Kernel * kernel) | |
43 { | |
44 int i, j; | |
45 | |
46 STRING line; | |
47 STRING type_name; | |
48 STRING str; | |
49 Real tmp_real; | |
50 FILE *file; | |
51 | |
52 /* parameter checking */ | |
53 if(kernel_file == NULL){ | |
54 print_error("input_kernel(): passed NULL FILE.\n"); | |
55 return (ERROR); | |
56 } | |
57 | |
58 file = fopen(kernel_file, "r"); | |
59 if(file == NULL){ | |
60 print_error("input_kernel(): error opening Kernel file.\n"); | |
61 return (ERROR); | |
62 } | |
63 | |
64 /* okay read the header */ | |
65 if(mni_input_string(file, &line, (char)0, (char)0) != OK){ | |
66 delete_string(line); | |
67 print_error("input_kernel(): could not read header in file.\n"); | |
68 return (ERROR); | |
69 } | |
70 | |
71 if(!equal_strings(line, KERNEL_FILE_HEADER)){ | |
72 delete_string(line); | |
73 print_error("input_kernel(): invalid header in file.\n"); | |
74 return (ERROR); | |
75 } | |
76 | |
77 /* --- read the type of Kernel */ | |
78 if(mni_input_keyword_and_equal_sign(file, KERNEL_TYPE, FALSE) != OK){ | |
79 return (ERROR); | |
80 } | |
81 | |
82 if(mni_input_string(file, &type_name, (char)';', (char)0) != OK){ | |
83 print_error("input_kernel(): missing kernel type.\n"); | |
84 return (ERROR); | |
85 } | |
86 | |
87 if(mni_skip_expected_character(file, (char)';') != OK){ | |
88 return (ERROR); | |
89 } | |
90 | |
91 if(!equal_strings(type_name, NORMAL_KERNEL)){ | |
92 print_error("input_kernel(): invalid kernel type.\n"); | |
93 delete_string(type_name); | |
94 return (ERROR); | |
95 } | |
96 delete_string(type_name); | |
97 | |
98 /* --- read the next string */ | |
99 if(mni_input_string(file, &str, (char)'=', (char)0) != OK) | |
100 return (ERROR); | |
101 | |
102 if(!equal_strings(str, KERNEL)){ | |
103 print_error("Expected %s =\n", KERNEL); | |
104 delete_string(str); | |
105 return (ERROR); | |
106 } | |
107 delete_string(str); | |
108 | |
109 if(mni_skip_expected_character(file, (char)'=') != OK){ | |
110 return (ERROR); | |
111 } | |
112 | |
113 /* now read the elements (lines) of the kernel */ | |
114 if(verbose){ | |
115 fprintf(stderr, "Reading [%s]", kernel_file); | |
116 } | |
117 for(i = 0; i < MAX_KERNEL_ELEMS; i++){ | |
118 | |
119 /* allocate a bit of memory */ | |
120 SET_ARRAY_SIZE(kernel->K, kernel->nelems, kernel->nelems + 1, 10); | |
121 ALLOC(kernel->K[i], KERNEL_DIMS + 1); | |
122 | |
123 /* get the 5 dimension vectors and the coefficient */ | |
124 for(j = 0; j < 6; j++){ | |
125 if(mni_input_real(file, &tmp_real) == OK){ | |
126 kernel->K[i][j] = tmp_real; | |
127 } | |
128 else { | |
129 /* check for end */ | |
130 if(mni_skip_expected_character(file, (char)';') == OK){ | |
131 kernel->nelems = i; | |
132 if(verbose){ | |
133 fprintf(stderr, " %dx%d Kernel elements read\n", i, kernel->nelems); | |
134 } | |
135 return (OK); | |
136 } | |
137 else { | |
138 print_error("input_kernel(): error reading kernel [%d,%d]\n", i + 1, | |
139 j + 1); | |
140 return (ERROR); | |
141 } | |
142 } | |
143 } | |
144 kernel->nelems++; | |
145 | |
146 if(verbose){ | |
147 fprintf(stderr, "."); | |
148 fflush(stderr); | |
149 } | |
150 } | |
151 | |
152 /* SHOLDN'T BE REACHED */ | |
153 print_error("input_kernel(): Glark! Something is amiss in the State of Kansas\n"); | |
154 return (ERROR); | |
155 } | |
156 | |
157 /* pretty print a kernel */ | |
158 int print_kernel(Kernel * kernel) | |
159 { | |
160 int i, j; | |
161 | |
162 fprintf(stderr, " x y z t v coeff\n"); | |
163 fprintf(stderr, " -----------------------------------------------\n"); | |
164 for(i = 0; i < kernel->nelems; i++){ | |
165 fprintf(stderr, "[%02d]", i); | |
166 for(j = 0; j < KERNEL_DIMS + 1; j++){ | |
167 fprintf(stderr, "%8.02f", kernel->K[i][j]); | |
168 } | |
169 fprintf(stderr, "\n"); | |
170 } | |
171 | |
172 return (TRUE); | |
173 } | |
174 | |
175 int setup_pad_values(Kernel * kernel) | |
176 { | |
177 int c, n; | |
178 | |
179 /* init padding values */ | |
180 for(n = 0; n < KERNEL_DIMS; n++){ | |
181 kernel->pre_pad[n] = 0; | |
182 kernel->post_pad[n] = 0; | |
183 } | |
184 | |
185 /* find the padding sizes */ | |
186 for(c = 0; c < kernel->nelems; c++){ | |
187 for(n = 0; n < KERNEL_DIMS; n++){ | |
188 if(kernel->K[c][n] < kernel->pre_pad[n]){ | |
189 kernel->pre_pad[n] = kernel->K[c][n]; | |
190 } | |
191 | |
192 if(kernel->K[c][n] > kernel->post_pad[n]){ | |
193 kernel->post_pad[n] = kernel->K[c][n]; | |
194 } | |
195 } | |
196 } | |
197 | |
198 return (TRUE); | |
199 } | |
200 | |
201 /* 2D 4 connectivity kernel */ | |
202 /* x y z t v coeff */ | |
203 /* ----------------------------------------------- */ | |
204 /* [00] 1.00 0.00 0.00 0.00 0.00 1.00 */ | |
205 /* [01] -1.00 0.00 0.00 0.00 0.00 1.00 */ | |
206 /* [02] 0.00 1.00 0.00 0.00 0.00 1.00 */ | |
207 /* [03] 0.00 -1.00 0.00 0.00 0.00 1.00 */ | |
208 Kernel *get_2D04_kernel(void) | |
209 { | |
210 Kernel *K = new_kernel(4); | |
211 | |
212 K->K[0][0] = 1.0; | |
213 K->K[1][0] = -1.0; | |
214 | |
215 K->K[2][1] = 1.0; | |
216 K->K[3][1] = -1.0; | |
217 | |
218 return K; | |
219 } | |
220 | |
221 /* 2D 8 connectivity kernel */ | |
222 /* x y z t v coeff */ | |
223 /* ----------------------------------------------- */ | |
224 /* [00] 1.00 1.00 0.00 0.00 0.00 1.00 */ | |
225 /* [01] 1.00 0.00 0.00 0.00 0.00 1.00 */ | |
226 /* [02] 1.00 -1.00 0.00 0.00 0.00 1.00 */ | |
227 /* */ | |
228 /* [03] 0.00 1.00 0.00 0.00 0.00 1.00 */ | |
229 /* [04] 0.00 -1.00 0.00 0.00 0.00 1.00 */ | |
230 /* */ | |
231 /* [05] -1.00 1.00 0.00 0.00 0.00 1.00 */ | |
232 /* [06] -1.00 0.00 0.00 0.00 0.00 1.00 */ | |
233 /* [07] -1.00 -1.00 0.00 0.00 0.00 1.00 */ | |
234 Kernel *get_2D08_kernel(void) | |
235 { | |
236 Kernel *K = new_kernel(8); | |
237 | |
238 K->K[0][0] = 1.0; | |
239 K->K[0][1] = 1.0; | |
240 | |
241 K->K[1][0] = 1.0; | |
242 | |
243 K->K[2][0] = 1.0; | |
244 K->K[2][1] = -1.0; | |
245 | |
246 K->K[3][1] = 1.0; | |
247 | |
248 K->K[4][1] = -1.0; | |
249 | |
250 K->K[5][0] = -1.0; | |
251 K->K[5][1] = 1.0; | |
252 | |
253 K->K[6][0] = -1.0; | |
254 | |
255 K->K[7][0] = -1.0; | |
256 K->K[7][1] = -1.0; | |
257 | |
258 return K; | |
259 } | |
260 | |
261 /* 3D 6 connectivity kernel */ | |
262 /* x y z t v coeff */ | |
263 /* ----------------------------------------------- */ | |
264 /* [00] 1.00 0.00 0.00 0.00 0.00 1.00 */ | |
265 /* [01] -1.00 0.00 0.00 0.00 0.00 1.00 */ | |
266 /* [02] 0.00 1.00 0.00 0.00 0.00 1.00 */ | |
267 /* [03] 0.00 -1.00 0.00 0.00 0.00 1.00 */ | |
268 /* [04] 0.00 0.00 1.00 0.00 0.00 1.00 */ | |
269 /* [05] 0.00 0.00 -1.00 0.00 0.00 1.00 */ | |
270 Kernel *get_3D06_kernel(void) | |
271 { | |
272 Kernel *K = new_kernel(6); | |
273 | |
274 K->K[0][0] = 1.0; | |
275 K->K[1][0] = -1.0; | |
276 | |
277 K->K[2][1] = 1.0; | |
278 K->K[3][1] = -1.0; | |
279 | |
280 K->K[4][2] = 1.0; | |
281 K->K[5][2] = -1.0; | |
282 | |
283 return K; | |
284 } | |
285 | |
286 /* 3D 26 connectivity kernel */ | |
287 /* x y z t v coeff */ | |
288 /* ----------------------------------------------- */ | |
289 /* [00] 1.00 1.00 1.00 0.00 0.00 1.00 */ | |
290 /* [01] 1.00 1.00 0.00 0.00 0.00 1.00 */ | |
291 /* [02] 1.00 1.00 -1.00 0.00 0.00 1.00 */ | |
292 | |
293 /* [03] 1.00 0.00 1.00 0.00 0.00 1.00 */ | |
294 /* [04] 1.00 0.00 0.00 0.00 0.00 1.00 */ | |
295 /* [05] 1.00 0.00 -1.00 0.00 0.00 1.00 */ | |
296 | |
297 /* [06] 1.00 -1.00 1.00 0.00 0.00 1.00 */ | |
298 /* [07] 1.00 -1.00 0.00 0.00 0.00 1.00 */ | |
299 /* [08] 1.00 -1.00 -1.00 0.00 0.00 1.00 */ | |
300 | |
301 /* [09] 0.00 1.00 1.00 0.00 0.00 1.00 */ | |
302 /* [10] 0.00 1.00 0.00 0.00 0.00 1.00 */ | |
303 /* [11] 0.00 1.00 -1.00 0.00 0.00 1.00 */ | |
304 | |
305 /* [12] 0.00 0.00 1.00 0.00 0.00 1.00 */ | |
306 /* ---- 0.00 0.00 0.00 0.00 0.00 ---- */ | |
307 /* [13] 0.00 0.00 -1.00 0.00 0.00 1.00 */ | |
308 | |
309 /* [14] 0.00 -1.00 1.00 0.00 0.00 1.00 */ | |
310 /* [15] 0.00 -1.00 0.00 0.00 0.00 1.00 */ | |
311 /* [16] 0.00 -1.00 -1.00 0.00 0.00 1.00 */ | |
312 | |
313 /* [17] -1.00 1.00 1.00 0.00 0.00 1.00 */ | |
314 /* [18] -1.00 1.00 0.00 0.00 0.00 1.00 */ | |
315 /* [19] -1.00 1.00 -1.00 0.00 0.00 1.00 */ | |
316 | |
317 /* [20] -1.00 0.00 1.00 0.00 0.00 1.00 */ | |
318 /* [21] -1.00 0.00 0.00 0.00 0.00 1.00 */ | |
319 /* [22] -1.00 0.00 -1.00 0.00 0.00 1.00 */ | |
320 | |
321 /* [23] -1.00 -1.00 1.00 0.00 0.00 1.00 */ | |
322 /* [24] -1.00 -1.00 0.00 0.00 0.00 1.00 */ | |
323 /* [25] -1.00 -1.00 -1.00 0.00 0.00 1.00 */ | |
324 Kernel *get_3D26_kernel(void) | |
325 { | |
326 Kernel *K = new_kernel(26); | |
327 | |
328 K->K[0][0] = 1.0; | |
329 K->K[0][1] = 1.0; | |
330 K->K[0][2] = 1.0; | |
331 | |
332 K->K[1][0] = 1.0; | |
333 K->K[1][1] = 1.0; | |
334 | |
335 K->K[2][0] = 1.0; | |
336 K->K[2][1] = 1.0; | |
337 K->K[2][2] = -1.0; | |
338 | |
339 K->K[3][0] = 1.0; | |
340 K->K[3][2] = 1.0; | |
341 | |
342 K->K[4][0] = 1.0; | |
343 | |
344 K->K[5][0] = 1.0; | |
345 K->K[5][2] = -1.0; | |
346 | |
347 K->K[6][0] = 1.0; | |
348 K->K[6][1] = -1.0; | |
349 K->K[6][2] = 1.0; | |
350 | |
351 K->K[7][0] = 1.0; | |
352 K->K[7][1] = -1.0; | |
353 | |
354 K->K[8][0] = 1.0; | |
355 K->K[8][1] = -1.0; | |
356 K->K[8][2] = -1.0; | |
357 | |
358 K->K[9][1] = 1.0; | |
359 K->K[9][2] = 1.0; | |
360 | |
361 K->K[10][1] = 1.0; | |
362 | |
363 K->K[11][1] = 1.0; | |
364 K->K[11][2] = -1.0; | |
365 | |
366 K->K[12][2] = 1.0; | |
367 | |
368 K->K[13][2] = -1.0; | |
369 | |
370 K->K[14][1] = -1.0; | |
371 K->K[14][2] = 1.0; | |
372 | |
373 K->K[15][1] = -1.0; | |
374 | |
375 K->K[16][1] = -1.0; | |
376 K->K[16][2] = -1.0; | |
377 | |
378 K->K[17][0] = -1.0; | |
379 K->K[17][1] = 1.0; | |
380 K->K[17][2] = 1.0; | |
381 | |
382 K->K[18][0] = -1.0; | |
383 K->K[18][1] = 1.0; | |
384 | |
385 K->K[19][0] = -1.0; | |
386 K->K[19][1] = 1.0; | |
387 K->K[19][2] = -1.0; | |
388 | |
389 K->K[20][0] = -1.0; | |
390 K->K[20][2] = 1.0; | |
391 | |
392 K->K[21][0] = -1.0; | |
393 | |
394 K->K[22][0] = -1.0; | |
395 K->K[22][2] = -1.0; | |
396 | |
397 K->K[23][0] = -1.0; | |
398 K->K[23][1] = -1.0; | |
399 K->K[23][2] = 1.0; | |
400 | |
401 K->K[24][0] = -1.0; | |
402 K->K[24][1] = -1.0; | |
403 | |
404 K->K[25][0] = -1.0; | |
405 K->K[25][1] = -1.0; | |
406 K->K[25][2] = -1.0; | |
407 | |
408 return K; | |
409 } |