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 }