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(這兩個程式使用的舊庫)的一個優勢:它快得多,對於此示例,速度提高了一個數量級。