跳转到内容

MINC/教程/编程03

来自维基教科书,开放的世界,开放的书籍

一个功能齐全且实用的示例

[编辑 | 编辑源代码]

conglomerate包中可以找到两个程序:print_volume_valueprint_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_valueprint_world_value中存在的功能。但是,它说明了minc2相对于volume_io(这两个程序使用的旧库)的一个优势:它快得多,对于此示例,速度提高了一个数量级。

华夏公益教科书