Exemplo n.º 1
0
/* returns a new Kernel struct (pointer)                */
Kernel  *new_kernel(int nelems)
{
   int      i, j;
   Kernel  *tmp;

   ALLOC_VAR_SIZED_STRUCT(tmp, VIO_Real, 10);

   /* allocate and initialise the Kernel Array */
   SET_ARRAY_SIZE(tmp->K, 0, nelems, 10);
   for(i = 0; i < nelems; i++){
      ALLOC(tmp->K[i], KERNEL_DIMS + 1);

      for(j = 0; j < KERNEL_DIMS; j++){
         tmp->K[i][j] = 0.0;
         }
      tmp->K[i][KERNEL_DIMS] = 1.0;

      }
   tmp->nelems = nelems;

   return tmp;
   }
Exemplo n.º 2
0
/* resulting groups are sorted WRT size          */
Volume  *group_kernel(Kernel * K, Volume * vol, double bg)
{
   int      x, y, z;
   int      sizes[MAX_VAR_DIMS];
   progress_struct progress;
   Volume   tmp_vol;
   Kernel  *k1, *k2;

   unsigned int *equiv;
   unsigned int *counts;
   unsigned int *trans;
   unsigned int neighbours[K->nelems];

   /* counters */
   unsigned int c;
   unsigned int value;
   unsigned int group_idx;             /* label for the next group     */
   unsigned int num_groups;

   unsigned int min_label;
   unsigned int curr_label;
   unsigned int prev_label;
   unsigned int num_matches;

   /* structure for group data */
   Group_info *group_data;

   /* split the Kernel into forward and backwards kernels */
   k1 = new_kernel(K->nelems);
   k2 = new_kernel(K->nelems);
   split_kernel(K, k1, k2);

   setup_pad_values(k1);
   setup_pad_values(k2);

   if(verbose){
      fprintf(stdout, "Group kernel - background %g\n", bg);
      fprintf(stdout, "forward direction kernel:\n");
      print_kernel(k1);
      fprintf(stdout, "\nreverse direction kernel:\n");
      print_kernel(k2);
      }

   get_volume_sizes(*vol, sizes);
   initialize_progress_report(&progress, FALSE, sizes[2], "Groups");

   /* copy and then zero out the original volume */
   tmp_vol = copy_volume(*vol);
   for(z = sizes[0]; z--;){
      for(y = sizes[1]; y--;){
         for(x = sizes[2]; x--;){
            set_volume_voxel_value(*vol, z, y, x, 0, 0, 0);
            }
         }
      }

   /* pass 1 - forward direction (we assume a symmetric kernel) */

   /* our first group is given the label 1 */
   group_idx = 1;

   /* initialise the equiv and counts arrays */
   SET_ARRAY_SIZE(equiv, 0, group_idx, 500);
   equiv[0] = 0;

   SET_ARRAY_SIZE(counts, 0, group_idx, 500);
   counts[0] = 0;

   for(z = -k1->pre_pad[2]; z < sizes[0] - k1->post_pad[2]; z++){
      for(y = -k1->pre_pad[1]; y < sizes[1] - k1->post_pad[1]; y++){
         for(x = -k1->pre_pad[0]; x < sizes[2] - k1->post_pad[0]; x++){

            if(get_volume_voxel_value(tmp_vol, z, y, x, 0, 0) != bg){

               /* search this voxels neighbours */
               num_matches = 0;
               min_label = INT_MAX;

               for(c = 0; c < k1->nelems; c++){
                  value = (unsigned int)get_volume_voxel_value(*vol,
                                                               z + k1->K[c][2],
                                                               y + k1->K[c][1],
                                                               x + k1->K[c][0],
                                                               0 + k1->K[c][3],
                                                               0 + k1->K[c][4]);
                  if(value != 0){
                     if(value < min_label){
                        min_label = value;
                        }
                     neighbours[num_matches] = value;
                     num_matches++;
                     }
                  }

               switch (num_matches){
               case 0:
                  /* no neighbours, make a new label and increment */
                  set_volume_voxel_value(*vol, z, y, x, 0, 0, (Real) group_idx);

                  SET_ARRAY_SIZE(equiv, group_idx, group_idx + 1, 500);
                  equiv[group_idx] = group_idx;

                  SET_ARRAY_SIZE(counts, group_idx, group_idx + 1, 500);
                  counts[group_idx] = 1;

                  group_idx++;
                  break;

               case 1:
                  /* only one neighbour, no equivalences needed */
                  set_volume_voxel_value(*vol, z, y, x, 0, 0, (Real) min_label);
                  counts[min_label]++;
                  break;

               default:
                  /* more than one neighbour */

                  /* first sort the neighbours array */
                  qsort(&neighbours[0], (size_t) num_matches, sizeof(unsigned int),
                        &compare_ints);

                  /* find the minimum possible label for this voxel,    */
                  /* this is done by descending through each neighbours */
                  /* equivalences until an equivalence equal to itself  */
                  /* is found                                           */
                  prev_label = -1;
                  for(c = 0; c < num_matches; c++){
                     curr_label = neighbours[c];

                     /* recurse this label if we haven't yet */
                     if(curr_label != prev_label){
                        while(equiv[curr_label] != equiv[equiv[curr_label]]){
                           curr_label = equiv[curr_label];
                           }

                        /* check against the current minimum value */
                        if(equiv[curr_label] < min_label){
                           min_label = equiv[curr_label];
                           }
                        }

                     prev_label = neighbours[c];
                     }

                  /* repeat, setting equivalences to the min_label */
                  prev_label = -1;
                  for(c = 0; c < num_matches; c++){
                     curr_label = neighbours[c];

                     if(curr_label != prev_label){
                        while(equiv[curr_label] != equiv[equiv[curr_label]]){
                           curr_label = equiv[curr_label];

                           equiv[curr_label] = min_label;
                           }

                        /* set the label itself */
                        if(equiv[neighbours[c]] != min_label){
                           equiv[neighbours[c]] = min_label;
                           }
                        }

                     prev_label = neighbours[c];
                     }

                  /* finally set the voxel in question to the minimum value */
                  set_volume_voxel_value(*vol, z, y, x, 0, 0, (Real) min_label);
                  counts[min_label]++;
                  break;
                  }                       /* end case */

               }
            }
         }
      update_progress_report(&progress, z + 1);
      }
   terminate_progress_report(&progress);

   /* reduce the equiv and counts array */
   num_groups = 0;
   for(c = 0; c < group_idx; c++){

      /* if this equivalence is not resolved yet */
      if(c != equiv[c]){

         /* find the min label value */
         min_label = equiv[c];
         while(min_label != equiv[min_label]){
            min_label = equiv[min_label];
            }

         /* update the label and its counters */
         equiv[c] = min_label;
         counts[min_label] += counts[c];
         counts[c] = 0;
         }
      else {
         num_groups++;
         }
      }

   /* Allocate space for the array of groups */
   group_data = (Group_info *) malloc(num_groups * sizeof(Group_info));

   num_groups = 0;
   for(c = 0; c < group_idx; c++){
      if(counts[c] > 0){
         /* allocate space for this element */
         group_data[num_groups] = malloc(sizeof(group_info_struct));

         group_data[num_groups]->orig_label = equiv[c];
         group_data[num_groups]->count = counts[c];
         num_groups++;
         }
      }

   /* sort the groups by the count size */
   if(verbose){
      fprintf(stdout, "Found %d unique groups from %d, sorting...\n", num_groups,
              group_idx);
      }
   qsort(group_data, num_groups, sizeof(Group_info), &compare_groups);

   /* set up the transpose array */
   trans = (unsigned int *)malloc(sizeof(unsigned int) * group_idx);
   for(c = 0; c < num_groups; c++){
      trans[group_data[c]->orig_label] = c + 1; /* +1 to bump past 0 */
      }

   /* pass 2 - resolve equivalences in the output data */
   if(verbose){
      fprintf(stdout, "Resolving equivalences...\n");
      }
   for(z = sizes[0]; z--;){
      for(y = sizes[1]; y--;){
         for(x = sizes[2]; x--;){
            value = (unsigned int)get_volume_voxel_value(*vol, z, y, x, 0, 0);
            if(value != 0){
               value = trans[equiv[value]];
               set_volume_voxel_value(*vol, z, y, x, 0, 0, (Real) value);
               }
            }
         }
      }

   /* tidy up */
   delete_volume(tmp_vol);
   for(c = 0; c < num_groups; c++){
      free(group_data[c]);
      }
   free(group_data);
   free(trans);
   free(k1);
   free(k2);

   return (vol);
   }
Exemplo n.º 3
0
/* reads in a Kernel from a file                        */
VIO_Status input_kernel(const char *kernel_file, Kernel * kernel)
{
   int      i, j;

   VIO_STR   line;
   VIO_STR   type_name;
   VIO_STR   str;
   VIO_Real     tmp_real;
   FILE    *file;

   /* parameter checking */
   if(kernel_file == NULL){
      print_error("input_kernel(): passed NULL FILE.\n");
      return (VIO_ERROR);
      }

   file = fopen(kernel_file, "r");
   if(file == NULL){
      print_error("input_kernel(): error opening Kernel file.\n");
      return (VIO_ERROR);
      }

   /* okay read the header */
   if(mni_input_string(file, &line, (char)0, (char)0) != VIO_OK){
      delete_string(line);
      print_error("input_kernel(): could not read header in file.\n");
      return (VIO_ERROR);
      }

   if(!equal_strings(line, KERNEL_FILE_HEADER)){
      delete_string(line);
      print_error("input_kernel(): invalid header in file.\n");
      return (VIO_ERROR);
      }

   /* --- read the type of Kernel */
   if(mni_input_keyword_and_equal_sign(file, KERNEL_TYPE, FALSE) != VIO_OK){
      return (VIO_ERROR);
      }

   if(mni_input_string(file, &type_name, (char)';', (char)0) != VIO_OK){
      print_error("input_kernel(): missing kernel type.\n");
      return (VIO_ERROR);
      }

   if(mni_skip_expected_character(file, (char)';') != VIO_OK){
      return (VIO_ERROR);
      }

   if(!equal_strings(type_name, NORMAL_KERNEL)){
      print_error("input_kernel(): invalid kernel type.\n");
      delete_string(type_name);
      return (VIO_ERROR);
      }
   delete_string(type_name);

   /* --- read the next string */
   if(mni_input_string(file, &str, (char)'=', (char)0) != VIO_OK)
      return (VIO_ERROR);

   if(!equal_strings(str, KERNEL)){
      print_error("Expected %s =\n", KERNEL);
      delete_string(str);
      return (VIO_ERROR);
      }
   delete_string(str);

   if(mni_skip_expected_character(file, (char)'=') != VIO_OK){
      return (VIO_ERROR);
      }

   /* now read the elements (lines) of the kernel */
   if(verbose){
      fprintf(stderr, "Reading [%s]", kernel_file);
      }
   for(i = 0; i < MAX_KERNEL_ELEMS; i++){

      /* allocate a bit of memory */
      SET_ARRAY_SIZE(kernel->K, kernel->nelems, kernel->nelems + 1, 10);
      ALLOC(kernel->K[i], KERNEL_DIMS + 1);

      /* get the 5 dimension vectors and the coefficient */
      for(j = 0; j < 6; j++){
         if(mni_input_real(file, &tmp_real) == VIO_OK){
            kernel->K[i][j] = tmp_real;
            }
         else {
            /* check for end */
            if(mni_skip_expected_character(file, (char)';') == VIO_OK){
               kernel->nelems = i;
               if(verbose){
                  fprintf(stderr, " %dx%d Kernel elements read\n", i, kernel->nelems);
                  }
               return (VIO_OK);
               }
            else {
               print_error("input_kernel(): error reading kernel [%d,%d]\n", i + 1,
                           j + 1);
               return (VIO_ERROR);
               }
            }
         }
      kernel->nelems++;

      if(verbose){
         fprintf(stderr, ".");
         fflush(stderr);
         }
      }

   /* SHOLDN'T BE REACHED */
   print_error("input_kernel(): Glark! Something is amiss in the State of Kansas\n");
   return (VIO_ERROR);
   }
Exemplo n.º 4
0
VIOAPI  VIO_Status  input_tag_points(
    FILE      *file,
    int       *n_volumes_ptr,
    int       *n_tag_points,
    VIO_Real      ***tags_volume1,
    VIO_Real      ***tags_volume2,
    VIO_Real      **weights,
    int       **structure_ids,
    int       **patient_ids,
    VIO_STR    *labels[] )
{
    VIO_Status   status;
    VIO_Real     tags1[VIO_N_DIMENSIONS];
    VIO_Real     tags2[VIO_N_DIMENSIONS];
    VIO_Real     weight;
    int      structure_id, patient_id, n_volumes;
    VIO_STR   label;

    status = initialize_tag_file_input( file, &n_volumes );

    if( n_volumes_ptr != NULL )
        *n_volumes_ptr = n_volumes;

    *n_tag_points = 0;

    while( status == VIO_OK &&
           input_one_tag( file, n_volumes,
                          tags1, tags2, &weight, &structure_id, &patient_id,
                          &label, &status ) )
    {
        if( tags_volume1 != NULL )
        {
            SET_ARRAY_SIZE( *tags_volume1, *n_tag_points, *n_tag_points+1,
                            DEFAULT_CHUNK_SIZE );
            ALLOC( (*tags_volume1)[*n_tag_points], 3 );
            (*tags_volume1)[*n_tag_points][VIO_X] = tags1[VIO_X];
            (*tags_volume1)[*n_tag_points][VIO_Y] = tags1[VIO_Y];
            (*tags_volume1)[*n_tag_points][VIO_Z] = tags1[VIO_Z];
        }

        if( n_volumes == 2 && tags_volume2 != NULL )
        {
            SET_ARRAY_SIZE( *tags_volume2, *n_tag_points, *n_tag_points+1,
                            DEFAULT_CHUNK_SIZE );
            ALLOC( (*tags_volume2)[*n_tag_points], 3 );
            (*tags_volume2)[*n_tag_points][VIO_X] = tags2[VIO_X];
            (*tags_volume2)[*n_tag_points][VIO_Y] = tags2[VIO_Y];
            (*tags_volume2)[*n_tag_points][VIO_Z] = tags2[VIO_Z];
        }

        if( weights != NULL )
        {
            SET_ARRAY_SIZE( *weights, *n_tag_points, *n_tag_points+1,
                            DEFAULT_CHUNK_SIZE);
            (*weights)[*n_tag_points] = weight;
        }

        if( structure_ids != NULL )
        {
            SET_ARRAY_SIZE( *structure_ids, *n_tag_points, *n_tag_points+1,
                            DEFAULT_CHUNK_SIZE);
            (*structure_ids)[*n_tag_points] = structure_id;
        }

        if( patient_ids != NULL )
        {
            SET_ARRAY_SIZE( *patient_ids, *n_tag_points, *n_tag_points+1,
                            DEFAULT_CHUNK_SIZE);
            (*patient_ids)[*n_tag_points] = patient_id;
        }

        if( labels != NULL )
        {
            SET_ARRAY_SIZE( *labels, *n_tag_points, *n_tag_points+1,
                            DEFAULT_CHUNK_SIZE);
            (*labels)[*n_tag_points] = label;
        }
        else
            delete_string( label );

        ++(*n_tag_points);
    }

    return( status );
}
Exemplo n.º 5
0
int  main(
    int   argc,
    char  *argv[] )
{
    Volume         volume;
    STRING         input_filename, output_filename;
    int            n_slices, n_components;
    pixels_struct  *pixels;
    nc_type        vol_type;
    BOOLEAN        two_d_allowed;

    initialize_argument_processing( argc, argv );

    if( !get_string_argument( NULL, &output_filename ) ||
        !get_int_argument( 0, &n_components ) )
    {
        print( "Usage: %s output.mnc  3|4|23|24 input1.rgb input2.rgb ...\n", argv[0] );
        return( 1 );
    }

    if( n_components > 100 )
    {
        vol_type = NC_FLOAT;
        n_components -= 100;
    }
    else
        vol_type = NC_BYTE;

    if( n_components > 20 )
    {
        two_d_allowed = TRUE;
        n_components -= 20;
    }
    else
    {
        two_d_allowed = FALSE;
    }

    n_slices = 0;
    pixels = NULL;

    while( get_string_argument( "", &input_filename ) )
    {
        SET_ARRAY_SIZE( pixels, n_slices, n_slices+1, DEFAULT_CHUNK_SIZE );

        if( input_rgb_file( input_filename, &pixels[n_slices] ) != OK )
            return( 1 );

        ++n_slices;
    }

    volume = convert_pixels_to_volume( n_components, n_slices,
                                       (two_d_allowed && n_slices == 1) ? 2 : 3,
                                       vol_type, pixels );

    if( volume != NULL )
    {
        (void) output_volume( output_filename, NC_UNSPECIFIED, FALSE,
                              0.0, 0.0,
                              volume, "Converted from pixels",
                              (minc_output_options *) NULL );

        delete_volume( volume );
    }

    return( 0 );
}