跳轉到內容

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

華夏公益教科書