MINC/教程/编程03
外观
在conglomerate包中可以找到两个程序:print_volume_value和print_world_value。要使用它们,您需要指定一个minc体积和xyz坐标,无论是体素(体积)还是世界空间,它将返回该位置的实际值。在这里,我们将把这些功能合并到一个单独的minc2程序中。
代码将在下面完整展示,并在页面末尾进行注释。用法如下
> minc2_tutorial3 input.mnc v|w c1 c2 c3
其中v或w指定c1 c2 c3中是否指定了世界坐标或体素坐标。
#include <minc2.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
int main(int argc, char **argv) {
mihandle_t minc_volume;
midimhandle_t dimensions[3];
double voxel;
int result, i;
double world_location[3];
double dvoxel_location[3];
unsigned long voxel_location[3];
unsigned int sizes[3];
char *usage;
char voxel_or_world;
usage = "minc2_tutorial3 input.mnc v|w x y z";
if (argc != 6) {
fprintf(stderr, "USAGE: %s\n", usage);
return(1);
}
/* open the volume - first command line argument */
result = miopen_volume(argv[1], MI2_OPEN_READ, &minc_volume);
/* check for error on opening */
if (result != MI_NOERROR) {
fprintf(stderr, "Error opening input file: %d.\n", result);
fprintf(stderr, "%s", usage);
return(1);
}
/* check for whether voxel or world coordinates are specified */
voxel_or_world = argv[2][0];
/* handle the case of world coordinates */
if (strcmp(&voxel_or_world, "w") == 0) {
/* get the world coordinates from the command line */
world_location[0] = atof(argv[3]);
world_location[1] = atof(argv[4]);
world_location[2] = atof(argv[5]);
/* convert world coordinates to voxel coordinates */
result = miconvert_world_to_voxel(minc_volume, world_location,
dvoxel_location);
if (result != MI_NOERROR) {
fprintf(stderr,
"Error converting world coordinates to voxel coordinates\n");
fprintf(stderr, "%s", usage);
return(1);
}
}
/* handle the case of voxel coordinates */
else if (strcmp(&voxel_or_world, "v") == 0) {
dvoxel_location[0] = atof(argv[3]);
dvoxel_location[1] = atof(argv[4]);
dvoxel_location[2] = atof(argv[5]);
/* convert the voxel coordinates to world coordinates */
miconvert_voxel_to_world(minc_volume, dvoxel_location,
world_location);
}
/* only v and w are allowed for this argument */
else {
fprintf(stderr, "Must specify v or w for voxel or world\n");
return(1);
}
/* miconvert_world_to_voxel needs an array of doubles *
* but miget_real_value needs unsigned longs - so we cast */
for (i=0; i<3; i++) {
voxel_location[i] = (unsigned long) dvoxel_location[i];
}
/* get the dimension sizes and make sure that *
* we are using legal coordinates */
miget_volume_dimensions(minc_volume, MI_DIMCLASS_SPATIAL,
MI_DIMATTR_ALL, MI_DIMORDER_FILE,
3, dimensions);
result = miget_dimension_sizes(dimensions, 3, sizes);
printf("Volume sizes: %u %u %u\n", sizes[0], sizes[1], sizes[2]);
/* die with an error if voxel coordinates are out of bounds */
for(i=0; i<3; i++) {
assert(voxel_location[i] >= 0 && voxel_location[i] < sizes[i]);
}
/* print the world to voxel mapping */
printf("Voxel location of xyz %f %f %f: %lu %lu %lu\n",
world_location[0], world_location[1], world_location[2],
voxel_location[0], voxel_location[1], voxel_location[2]);
/* print the value at that location */
miget_real_value(minc_volume, voxel_location, 3, &voxel);
printf("Voxel at xyz %f %f %f was: %f\n",
world_location[0], world_location[1], world_location[2], voxel);
return(0);
}
大多数代码您已经在之前的两个示例中见过。还有一些额外的minc库调用 - 第一个是miconvert_voxel_to_world,它与miconvert_world_to_voxel相反。还有两个处理维度的函数。第一个是miget_volume_dimensions,它将与指定minc体积相关的维度放入midimhandle_t变量中。此函数有几个参数;目前,注意上面使用的默认值在大多数情况下都足够了(详细信息将在后面的教程中讨论)。下一个函数至关重要 - miget_dimension_sizes返回每个维度中的元素数量。这是循环遍历体素的关键信息,将在后面说明。
如上所述,此代码再现了print_volume_value和print_world_value中存在的功能。但是,它说明了minc2相对于volume_io(这两个程序使用的旧库)的一个优势:它快得多,对于此示例,速度提高了一个数量级。