MINC/教程/编程06
外观
继续学习超立方体:我们将再次使用相同的技巧,为每个体素加一。我们将以略微不同的方式进行:这次我们将获取并设置每个切片的超立方体,使用更少的内存。而且,为了获得更多 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);
}