跳轉到內容

MINC/教程/程式設計06

來自華夏公益教科書,自由的教科書

超立方體部分 2

[編輯 | 編輯原始碼]

繼續學習超立方體:我們將再次使用相同的技巧,為每個體素加一。我們將以略微不同的方式進行:這次我們將獲取並設定每個切片的超立方體,使用更少的記憶體。而且,為了獲得更多 mincy 的好處,我們將使用切片縮放進行輸出。

#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, new_volume;
  midimhandle_t dimensions[3], *dimensions_new;
  double        min, max;
  int           result, i, slice;
  unsigned long start[3], count[3];
  unsigned int  sizes[3];
  double        *slab;

  if (argc != 3) {
    fprintf(stderr, "Usage: input.mnc output.mnc\n");
  }

  /* 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);
    return(1);
  }

  /* get the dimension sizes */
  miget_volume_dimensions(minc_volume, MI_DIMCLASS_SPATIAL,
			  MI_DIMATTR_ALL, MI_DIMORDER_FILE,
			  3, dimensions);
  miget_dimension_sizes(dimensions, 3, sizes);
  printf("Volume sizes: %u %u %u\n", sizes[0], sizes[1], sizes[2]);

  /* allocate new dimensions */
  dimensions_new = malloc(sizeof(midimhandle_t) * 3);

  /* copy the dimensions */
  for(i=0; i < 3; i++) {
    micopy_dimension(dimensions[i], &dimensions_new[i]);
  }

此程式碼與上次教程中的程式碼相同。

 /* create the new volume */
  if (micreate_volume(argv[2], 3, dimensions_new, MI_TYPE_UBYTE,
		      MI_CLASS_REAL, NULL, &new_volume) != MI_NOERROR) {
    fprintf(stderr, "Error creating new volume\n");
    return(1);
  }
  /* indicate that we will be using slice scaling */
  miset_slice_scaling_flag(new_volume, TRUE);

  /* set valid range */
  miset_volume_valid_range(new_volume, 255, 0);
  
  /* create the data for the new volume */
  if (micreate_volume_image(new_volume) != MI_NOERROR) {
    fprintf(stderr, "Error creating volume data\n");
    return(1);
  }

這次我們在開始處理實際資料之前建立了體積。我們還使用 miset_slice_scaling_flag 設定切片縮放 - 請注意,這必須在 micreate_volume_image 之前進行。其餘部分與之前相同。

  /* now go into a slice loop - get each slice as a hyperslab. *
   * First allocate enough memory to hold one slice of data */
  slab = malloc(sizeof(double) * sizes[1] * sizes[2]);

  /* the start and counts */
  start[0] = start[1] = start[2] = 0;

  /* always one slice */
  count[0] = 1;
  count[1] = (unsigned long) sizes[1];
  count[2] = (unsigned long) sizes[2];

  /* start the loop itself */
  for (slice=0; slice < sizes[0]; slice++) {
    /* set the slice start */
    start[0] = (unsigned long) slice;
    if (miget_real_value_hyperslab(minc_volume, MI_TYPE_DOUBLE,
				   start, count, slab) != MI_NOERROR) {
      fprintf(stderr, "Error getting hyperslab for slice %d\n", slice);
      return(1);
    }
    
    /* set min and max to the first voxel of the slice plus 1 
     *  (since we add one to everything anyway) */
    min = slab[0]+1;
    max = slab[0]+1;
    
    /* loop over all voxels in slice */
    for (i=0; i < sizes[1] * sizes[2]; i++) {
      /* increment voxel by 1 */
      slab[i] += 1;
    
      /* check if min or max should be changed */
      if (slab[i]+1 < min) {
	min = slab[i]+1;
      }
      else if (slab[i]+1 > max) {
	max = slab[i]+1;
      }
    }
    /* set the slice scaling */
    miset_slice_range(new_volume, start, 3, max, min);

    /* put the hyperslab into the new volume */
    if (miset_real_value_hyperslab(new_volume, MI_TYPE_DOUBLE,
				   start, count, slab) != MI_NOERROR) {
      fprintf(stderr, "Error setting hyperslab\n");
      return(1);
    }
  }

對資料的迴圈變得更加複雜。我們現在為一個足以容納一個切片的超立方體分配了資料,並且我們對每個切片重用了同一個陣列。然後我們獲取每個切片的超立方體,在跟蹤切片特定的最小值和最大值的同時對體素進行相同的操作,並設定切片範圍。然後我們將修改後的超立方體放入新體積中,並繼續下一個切片。

  /* closes the volume and makes sure all data is written to file */
  miclose_volume(minc_volume);
  miclose_volume(new_volume);

  /* free memory */
  free(dimensions_new);
  free(slab);

  return(0);
}

我們以與之前相同的方式結束。

程式碼

[編輯 | 編輯原始碼]
#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, new_volume;
  midimhandle_t dimensions[3], *dimensions_new;
  double        min, max;
  int           result, i, slice;
  unsigned long start[3], count[3];
  unsigned int  sizes[3];
  double        *slab;

  if (argc != 3) {
    fprintf(stderr, "Usage: input.mnc output.mnc\n");
  }

  /* 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);
    return(1);
  }

  /* get the dimension sizes */
  miget_volume_dimensions(minc_volume, MI_DIMCLASS_SPATIAL,
			  MI_DIMATTR_ALL, MI_DIMORDER_FILE,
			  3, dimensions);
  miget_dimension_sizes(dimensions, 3, sizes);
  printf("Volume sizes: %u %u %u\n", sizes[0], sizes[1], sizes[2]);

  /* allocate new dimensions */
  dimensions_new = malloc(sizeof(midimhandle_t) * 3);

  /* copy the dimensions */
  for(i=0; i < 3; i++) {
    micopy_dimension(dimensions[i], &dimensions_new[i]);
  }


  /* create the new volume */
  if (micreate_volume(argv[2], 3, dimensions_new, MI_TYPE_UBYTE,
		      MI_CLASS_REAL, NULL, &new_volume) != MI_NOERROR) {
    fprintf(stderr, "Error creating new volume\n");
    return(1);
  }
  /* indicate that we will be using slice scaling */
  miset_slice_scaling_flag(new_volume, TRUE);

  /* set valid range */
  miset_volume_valid_range(new_volume, 255, 0);
  
  /* create the data for the new volume */
  if (micreate_volume_image(new_volume) != MI_NOERROR) {
    fprintf(stderr, "Error creating volume data\n");
    return(1);
  }



  /* now go into a slice loop - get each slice as a hyperslab. *
   * First allocate enough memory to hold one slice of data */
  slab = malloc(sizeof(double) * sizes[1] * sizes[2]);

  /* the start and counts */
  start[0] = start[1] = start[2] = 0;

  /* always one slice */
  count[0] = 1;
  count[1] = (unsigned long) sizes[1];
  count[2] = (unsigned long) sizes[2];

  /* start the loop itself */
  for (slice=0; slice < sizes[0]; slice++) {
    /* set the slice start */
    start[0] = (unsigned long) slice;
    if (miget_real_value_hyperslab(minc_volume, MI_TYPE_DOUBLE,
				   start, count, slab) != MI_NOERROR) {
      fprintf(stderr, "Error getting hyperslab for slice %d\n", slice);
      return(1);
    }
    
    /* set min and max to the first voxel of the slice plus 1 
     *  (since we add one to everything anyway) */
    min = slab[0]+1;
    max = slab[0]+1;
    
    /* loop over all voxels in slice */
    for (i=0; i < sizes[1] * sizes[2]; i++) {
      /* increment voxel by 1 */
      slab[i] += 1;
    
      /* check if min or max should be changed */
      if (slab[i]+1 < min) {
	min = slab[i]+1;
      }
      else if (slab[i]+1 > max) {
	max = slab[i]+1;
      }
    }
    /* set the slice scaling */
    miset_slice_range(new_volume, start, 3, max, min);

    /* put the hyperslab into the new volume */
    if (miset_real_value_hyperslab(new_volume, MI_TYPE_DOUBLE,
				   start, count, slab) != MI_NOERROR) {
      fprintf(stderr, "Error setting hyperslab\n");
      return(1);
    }
  }
  
  /* closes the volume and makes sure all data is written to file */
  miclose_volume(minc_volume);
  miclose_volume(new_volume);

  /* free memory */
  free(dimensions_new);
  free(slab);

  return(0);
}
華夏公益教科書