Example #1
0
Graph* Stack_Label_Field_Neighbor_Graph(Stack *stack, int threshold,
    Objlabel_Workspace *ow)
{
  TZ_ASSERT(stack->kind == GREY16, "Invalid stack kind");
  STACK_OBJLABEL_OPEN_WORKSPACE(stack, ow);


  Graph *graph = Make_Graph(0, 1, TRUE);
  graph->nvertex = Stack_Max(stack, NULL) + 1;

  Graph_Workspace *gw = New_Graph_Workspace();

  uint16_t *signal_array = (uint16_t*) stack->array;

  int neighbor_offset[26];
  int is_in_bound[26];

  Stack_Neighbor_Offset(ow->conn, stack->width, stack->height, neighbor_offset);

  /* Identify number of objects */
  int object_number = 0;
  int width = stack->width;
  int height = stack->height;
  int depth = stack->depth;
  size_t voxelNumber = Stack_Voxel_Number(stack);
  size_t index;

  //Stack *mask = Make_Stack(GREY, width, height, depth);

  for (index = 0; index < voxelNumber; ++index) {
    if (object_number < signal_array[index]) {
      object_number = signal_array[index];
    }

    if (ow->init_chord == TRUE) {
      ow->chord->array[index] = -1;
    }

    //mask->array[index] = 0;
  }

  //uint8_t *visited = mask->array;

  Int_Arraylist *seed_head = Make_Int_Arraylist(object_number + 1, 0);
  Int_Arraylist *seed_tail = Make_Int_Arraylist(object_number + 1, 0);
  Int_Arraylist *seed_point = Make_Int_Arraylist(object_number + 1, 0);
  int i;
  for (i = 0; i < seed_head->length; ++i) {
    seed_head->array[i] = -1;
    seed_point->array[i] = -1;
    seed_tail->array[i] = -1;
  }

  int *seed_queue = ow->chord->array;

  /* Initialize the seeds for each object */
  for (index = 0; index < voxelNumber; ++index) {
    uint16_t object_label = signal_array[index];
    int *current_seed_head = seed_head->array + object_label;
    int *current_seed_tail = seed_tail->array + object_label;
    int *current_seed_point = seed_point->array + object_label;
    int nbound = Stack_Neighbor_Bound_Test_I(ow->conn, width, height, depth,
        index, is_in_bound);
    if (is_border_voxel(signal_array, index, ow->conn,
          neighbor_offset, is_in_bound, nbound) == TRUE) { 
      //visited[index] = 1;
      if (*current_seed_head < 0) {
        *current_seed_head = index;
        *current_seed_tail = index;
        *current_seed_point = *current_seed_head;
      } else {
        seed_queue[*current_seed_point] = index;
        *current_seed_point = index;
      }
    }
  }

  int current_level = 0;
  /* While the current growing level is below the threshold */
  while (current_level < threshold) {
    /* Grow each object */
    uint16_t object_label;
    for (object_label = 1; object_label <= object_number; ++object_label) {
      int current_tail = seed_tail->array[object_label];
      int new_tail = current_tail;
      int seed = seed_head->array[object_label];
      while (seed >= 0) {
        int nbound = Stack_Neighbor_Bound_Test_I(ow->conn, width, height, depth,
            seed, is_in_bound);
        int j;
        for (j = 0; j < ow->conn; ++j) {
          if (nbound == ow->conn || is_in_bound[j]) {
            int neighbor_index = seed + neighbor_offset[j];
            uint16_t neighbor_label = signal_array[neighbor_index];
            if (neighbor_label == 0) {
              seed_queue[new_tail] = neighbor_index;
              new_tail = neighbor_index;
              signal_array[neighbor_index] = object_label;
              //visited[neighbor_index] = 1;
            } else if (neighbor_label != object_label) {
              /* If x-y does not exist */
              if (Graph_Edge_Index_U(object_label, neighbor_label, gw)
                  < 0) {
                double weight = current_level * 2;
                if (object_label > neighbor_label) {
                  weight += 1.0;
                }
                Graph_Add_Weighted_Edge(graph, 
                    object_label, neighbor_label, weight);
                Graph_Expand_Edge_Table(object_label, neighbor_label,
                    graph->nedge - 1, gw);
              }
            }
          }
        }
        if (seed == current_tail) {
          break;
        }
        seed = seed_queue[seed];
      }

      if (current_tail >= 0) {
        seed_head->array[object_label] = seed_queue[current_tail];
        seed_tail->array[object_label] = new_tail;
      }
    }

    ++current_level;
  }

  Kill_Int_Arraylist(seed_head);
  Kill_Int_Arraylist(seed_tail);
  Kill_Int_Arraylist(seed_point);

  Kill_Graph_Workspace(gw);

  STACK_OBJLABEL_CLOSE_WORKSPACE(ow);

  //Kill_Stack(mask);

  return graph;
}
Example #2
0
Int_Arraylist* Stack_Sp_Grow(const Stack *stack, const size_t *seeds, 
			     int nseed, const size_t *targets, int ntarget, 
			     Sp_Grow_Workspace *sgw)
{
  size_t nvoxel = Stack_Voxel_Number(stack);
  sgw->width = stack->width;
  sgw->height = stack->height;
  sgw->depth = stack->depth;

  /* allocate workspace */
  if (sgw->size < nvoxel) {
    sgw->dist = (double*) Guarded_Realloc(sgw->dist, sizeof(double) * nvoxel,
					  "Stack_Sp_Grow");
    sgw->path = (int*) Guarded_Realloc(sgw->path, sizeof(int) * nvoxel,
				       "Stack_Sp_Grow");
    sgw->checked = (int*) Guarded_Realloc(sgw->checked, sizeof(int) * nvoxel,
					  "Stack_Sp_Grow");
    sgw->flag = (uint8_t*) Guarded_Realloc(sgw->flag, sizeof(uint8_t) * nvoxel,
					  "Stack_Sp_Grow");
    if (sgw->lengthBufferEnabled) {
      sgw->length = (double*) Guarded_Realloc(
          sgw->length, sizeof(double) * nvoxel, "Stack_Sp_Grow");
    }
  } else {
    if (sgw->dist == NULL) {
      sgw->dist = (double*) Guarded_Malloc(sizeof(double) * nvoxel,
					   "Stack_Sp_Grow");
    }
    if (sgw->path == NULL) {
      sgw->path = (int*) Guarded_Malloc(sizeof(int) * nvoxel,
					"Stack_Sp_Grow");
    }
    if (sgw->checked == NULL) {
      sgw->checked = (int*) Guarded_Malloc(sizeof(int) * nvoxel,
					   "Stack_Sp_Grow");
    }
    if (sgw->flag == NULL) {
      sgw->flag = (uint8_t*) Guarded_Malloc(sizeof(uint8_t) * nvoxel,
					   "Stack_Sp_Grow");    
    }

    if (sgw->lengthBufferEnabled) {
      if (sgw->length == NULL) {
        sgw->length = (double*) Guarded_Malloc(
            sizeof(double) * nvoxel, "Stack_Sp_Grow");
      }
    }
  }

  sgw->size = nvoxel;
  
  /* initialize */
  size_t s;
  for (s = 0; s < nvoxel; s++) {
    sgw->dist[s] = Infinity;
    if (sgw->length != NULL) {
      sgw->length[s] = 0.0;
    }
    sgw->path[s] = -1;
    sgw->checked[s] = 0;
    sgw->flag[s] = 0;
  }

  if (sgw->mask != NULL) {
    memcpy(sgw->flag, sgw->mask, nvoxel);
  }

  /* Recruit seeds (source) */
  int i;
  for (i = 0; i < nseed; i++) {
    if (sgw->sp_option == 1) {
      sgw->dist[seeds[i]] = -Stack_Array_Value(stack, seeds[i]);
    } else {
      sgw->dist[seeds[i]] = 0.0;
    }
    sgw->checked[seeds[i]] = 1;
    sgw->flag[seeds[i]] = SP_GROW_SOURCE;
  }
  
  if (sgw->mask != NULL) {
    for (s = 0; s < nvoxel; s++) {
      if (sgw->flag[s] == SP_GROW_SOURCE) {
        if (sgw->sp_option == 1) {
          sgw->dist[s] = -Stack_Array_Value(stack, s);
        } else {
          sgw->dist[s] = 0.0;
        }
        sgw->checked[s] = 1;	
      }
    }
  }

  Int_Arraylist *result = New_Int_Arraylist();

  for (i = 0; i < ntarget; i++) {
    if (sgw->flag[targets[i]] == 2) { /* overlap of source and target */
      Int_Arraylist_Add(result, targets[i]);
      sgw->value = 0.0;
      return result;
    }
    sgw->flag[targets[i]] = SP_GROW_TARGET;
  }

  int width = Stack_Width(stack);
  int height = Stack_Height(stack);
  int depth = Stack_Depth(stack);

  double dist[26];
  Stack_Neighbor_Dist_R(sgw->conn, sgw->resolution, dist);

  int is_in_bound[26];
  int neighbors[26];
  Stack_Neighbor_Offset(sgw->conn, Stack_Width(stack), Stack_Height(stack), 
			neighbors);			

  BOOL stop = FALSE;

  /* Check neighbors of seeds */
  int j;
  //  for (i = 0; i < nseed; i++) {
  // size_t r = seeds[i];

  /* alloc <heap> */
  Int_Arraylist *heap = New_Int_Arraylist();

  size_t r;
  for (r = 0; r < nvoxel; r++) {
    if (sgw->flag[r] == SP_GROW_SOURCE) { /* seeds */
      int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, depth, 
          r, is_in_bound);

      if (nbound == sgw->conn) { /* all neighbors are in bound */
        for (j = 0; j < sgw->conn; j++) {
          size_t nbr_index = r + neighbors[j];
          if (sgw->checked[nbr_index] != 1) {
            update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw);
          }
        }
      } else if (nbound > 0) {
        for (j = 0; j < sgw->conn; j++) {
          if (is_in_bound[j]) {
            size_t nbr_index = r + neighbors[j];
            if (sgw->checked[nbr_index] != 1) {
              update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw);
            }
          }
        }
      }
    }
  }

  //Verify_Int_Heap_I(heap, sgw->dist);

  ssize_t last_r = -1;

  while (stop == FALSE) {
    ssize_t r = extract_min(sgw->dist, sgw->checked, sgw->size, heap);

    if (r >= 0) {
      last_r = r;
      if (sgw->flag[r] == 0) { /* normal voxel */
        int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, 
            depth, r, is_in_bound);

        if (nbound == sgw->conn) { /* all neighbors are in bound */
          for (j = 0; j < sgw->conn; j++) {
            size_t nbr_index = r + neighbors[j];
            if (sgw->checked[nbr_index] != 1) {
              update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw);
            }
          }
        } else if (nbound > 0) {
          for (j = 0; j < sgw->conn; j++) {
            if (is_in_bound[j]) {
              size_t nbr_index = r + neighbors[j];
              if (sgw->checked[nbr_index] != 1) {
                update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw);
              }
            }
          }
        }
        //Print_Int_Heap(heap, "%d");
        //Verify_Int_Heap_I(heap, sgw->dist);
      } else if (sgw->flag[r] == SP_GROW_TARGET) { /* target reached */
        //Int_Arraylist_Add(result, r);
        stop = TRUE;
      } else if (sgw->flag[r] == SP_GROW_CONDUCTOR) { 
        /* 0-distance region (super conductor) */
        int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, 
            depth, r, is_in_bound);
        size_t tail_index = r;
        size_t old_tail_index = tail_index;
        size_t cur_index = r;
#ifdef _DEBUG_2
        printf("r: %lu\n", r);
#endif

#define UPDATE_SUPER_CONDUCTOR				\
        size_t nbr_index = cur_index + neighbors[j];	\
        if (sgw->flag[nbr_index] == 4) {				\
          if (sgw->checked[nbr_index] > 1) {				\
            Int_Heap_Remove_I_At(heap, nbr_index, sgw->dist,		\
                sgw->checked);				\
          }								\
          tail_index = update_neighbor(cur_index, tail_index, nbr_index,sgw); \
        } else {							\
          update_waiting(stack, cur_index, nbr_index, dist[j], heap, result,sgw); \
        }

        if (nbound == sgw->conn) { /* all neighbors are in bound */
          for (j = 0; j < sgw->conn; j++) {
            UPDATE_SUPER_CONDUCTOR
          }
        } else if (nbound > 0) {
          for (j = 0; j < sgw->conn; j++) {
            if (is_in_bound[j]) {
              UPDATE_SUPER_CONDUCTOR
            }
          }
        }

        int count = 0;
        while (tail_index != old_tail_index) {
          old_tail_index = tail_index;

          size_t cur_index = tail_index;
          while (sgw->checked[cur_index] != 1) {
            int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, 
                depth, cur_index, 
                is_in_bound);
            if (nbound == sgw->conn) { /* all neighbors are in bound */
              for (j = 0; j < sgw->conn; j++) {
                UPDATE_SUPER_CONDUCTOR
              }
            } else if (nbound > 0) {
              for (j = 0; j < sgw->conn; j++) {
                if (is_in_bound[j]) {
                  UPDATE_SUPER_CONDUCTOR
                }
              }
            }

            sgw->checked[cur_index] = 1;
            size_t tmp_index = cur_index;
            cur_index = sgw->path[cur_index];
            sgw->path[tmp_index] = r;
            count++;
          }
        }
Example #3
0
int* Stack_Graph_Shortest_Path(const Stack *stack, int start[], int end[],
			       Stack_Graph_Workspace *sgw)
{
  int start_index = Stack_Util_Offset(start[0], start[1], start[2], 
				      stack->width, stack->height, 
				      stack->depth);
  int end_index = Stack_Util_Offset(end[0], end[1], end[2], 
				    stack->width, stack->height, 
				    stack->depth);

  int nvoxel = Stack_Voxel_Number(stack);
  int *path = iarray_malloc(nvoxel);
  double *dist = darray_malloc(nvoxel);
  int *checked = iarray_malloc(nvoxel);

  int i, j;

  for (i = 0; i < nvoxel; i++) {
    dist[i] = Infinity;
    path[i] = -1;
    checked[i] = 0;
  }

  dist[start_index] = 0;
  path[start_index] = -1;
  checked[start_index] = 1;
  
  int prev_vertex = start_index;
  int cur_vertex = start_index;
  int updating_vertex;
  double tmpdist;

  int neighbor[26];
  Stack_Neighbor_Offset(sgw->conn, stack->width, stack->height, neighbor);
  const double *neighbor_dist = Stack_Neighbor_Dist(sgw->conn);

  int is_in_bound[26];
  int nbound;

  Int_Arraylist *heap = Int_Arraylist_New(1, 0);
  int cwidth = stack->width - 1;
  int cheight = stack->height - 1;
  int cdepth = stack->depth - 1;

  void *argv[3];
  double v1;
  double v2;
  double d;
  argv[0] = &v1;
  argv[1] = &v2;
  argv[2] = &d;

  for (i = 1; i < nvoxel; i++) {
    prev_vertex = cur_vertex;
    nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, cwidth, cheight, cdepth, 
					 cur_vertex, is_in_bound);
    
    if (nbound == sgw->conn) {
      for (j = 0; j < sgw->conn; j++) {
	updating_vertex = cur_vertex + neighbor[j];
	if (checked[updating_vertex] != 1) {
	  v1 = Stack_Array_Value(stack, cur_vertex);
	  v2 = Stack_Array_Value(stack, updating_vertex);
	  d = neighbor_dist[j];
	  double weight = sgw->wf(argv);
	  tmpdist = weight + dist[cur_vertex];
	  if (dist[updating_vertex] > tmpdist) {
	    dist[updating_vertex] = tmpdist;
	    path[updating_vertex] = cur_vertex;
	    
	    if (checked[updating_vertex] > 1) {
	      Int_Heap_Update_I(heap, updating_vertex, dist, checked);
	    } else {
	      Int_Heap_Add_I(heap, updating_vertex, dist, checked);
	    }
	  }
	}
      }
    } else {
      for (j = 0; j < sgw->conn; j++) {
	if (is_in_bound[j]) {
	  updating_vertex = cur_vertex + neighbor[j];
	  if (checked[updating_vertex] != 1) {
	    v1 = Stack_Array_Value(stack, cur_vertex);
	    v2 = Stack_Array_Value(stack, updating_vertex);
	    d = neighbor_dist[j];
	    double weight = sgw->wf(argv);
	    tmpdist = weight + dist[cur_vertex];
	    if (dist[updating_vertex] > tmpdist) {
	      dist[updating_vertex] = tmpdist;
	      path[updating_vertex] = cur_vertex;
	    
	      if (checked[updating_vertex] > 1) {
		Int_Heap_Update_I(heap, updating_vertex, dist, checked);
	      } else {
		Int_Heap_Add_I(heap, updating_vertex, dist, checked);
	      }
	    }
	  }
	}
      }
    }

    cur_vertex = extract_min(dist, checked, nvoxel, heap);

    if (cur_vertex == end_index) {
      break;
    }

    if (cur_vertex < 0) {
      break;
    }
  }

  Kill_Int_Arraylist(heap);
  free(checked);
  free(dist);

  return path;  
}