Exemple #1
0
void Stack_Draw_Voxel_C(Stack *stack, int x, int y, int z, int conn, 
			uint8 r, uint8 g, uint8 b)
{
  ASSERT(stack->kind == COLOR, "color stack only");

  color_t *array = (color_t *) stack->array;

  int index = Stack_Util_Offset(x, y, z, stack->width, stack->height, 
				stack->depth);
  array[index][0] = r;
  array[index][1] = g;
  array[index][2] = b;
  
  if (conn > 0) {
    int neighbor[26];
    int is_in_bound[26];
    Stack_Neighbor_Offset(conn, stack->width, stack->height, neighbor);
    int nbound = Stack_Neighbor_Bound_Test(conn, stack->width - 1, 
					   stack->height - 1,
					   stack->depth - 1,
					   x, y, z, is_in_bound);
    if (nbound == conn) {
      int i;
      for (i = 0; i < conn; i++) {
	array[index + neighbor[i]][0] = r;
	array[index + neighbor[i]][1] = g;
	array[index + neighbor[i]][2] = b;
      }
    } else {
      int i;
      for (i = 0; i < conn; i++) {
	if (is_in_bound[i]) {
	  array[index + neighbor[i]][0] = r;
	  array[index + neighbor[i]][1] = g;
	  array[index + neighbor[i]][2] = b;
	}
      }
    }
  }
}
Exemple #2
0
Stack* Stack_Boundary_Code(Stack *stack, Stack *code, Objlabel_Workspace *ow)
{
  STACK_OBJLABEL_OPEN_WORKSPACE(stack, ow);

  int nvoxel = Stack_Voxel_Number(stack);
  int i;

  if (ow->init_chord == TRUE) {
    for (i = 0; i < nvoxel; i++) {
      ow->chord->array[i] = -1;
    }
  }

  if (code == NULL) {
    code = Make_Stack(GREY16, stack->width, stack->height, stack->depth);
  }

  Zero_Stack(code);

  int neighbor[26];
  int is_in_bound[26];
  int nbound;
  BOOL is_boundary = FALSE;

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

  int prev_seed = -1;
  int offset = 0;
  int x, y, z;

  cwidth = stack->width - 1;
  cheight = stack->height - 1;
  cdepth = stack->depth - 1;

  uint16 *code_array = (uint16 *) code->array;

  for (z = 0; z < stack->depth; z++) {
    for (y = 0; y < stack->height; y++) {
      for (x = 0; x < stack->width; x++) {
	is_boundary = FALSE;
	if (stack->array[offset] == 1) {
	  nbound = Stack_Neighbor_Bound_Test(ow->conn, cwidth, cheight,
					     cdepth, x, y, z, is_in_bound);
	  if (nbound < ow->conn) {
	    is_boundary = TRUE;
	  } else {
	    for (i = 0; i < ow->conn; i++) {
	      if (stack->array[offset + neighbor[i]] == 0) {
		is_boundary = TRUE;
		break;
	      }
	    }
	  }
	}
	if (is_boundary == TRUE) {
	  code_array[offset] = 1;
	  ow->chord->array[offset] = prev_seed;
	  prev_seed = offset;
	}
	offset++;
      }
    }
  }

  int entrance = prev_seed;

  int area = stack->width * stack->height;
  int c;
  int prev;
  int nb;
  int *link = ow->chord->array;

  /* generate level field  */
  while (entrance > 0) {
    c = entrance;
    prev = -1;

    do {					
      if (code_array[c] == 1) {
	Stack_Util_Coord_A(c, stack->width, area, &x, &y, &z);
	nbound = Stack_Neighbor_Bound_Test(ow->conn, cwidth, cheight,
					     cdepth, x, y, z, is_in_bound);
	if (nbound < ow->conn) {
	  for (i = 0; i < ow->conn; i++) {
	    if (is_in_bound[i]) {
	      nb = c + neighbor[i];
	      if (stack->array[nb] && !code_array[nb]) {
		code_array[nb] = 2;
		link[nb] = prev;
		prev = nb;
	      }
	    }
	  }
	} else {
	  for (i = 0; i < nbound; i++) {
	    nb = c + neighbor[i];
	    if (stack->array[nb] && !code_array[nb]) {
	      code_array[nb] = 2;
	      link[nb] = prev;
	      prev = nb;
	    }
	  }
	}
      } else {
	for (i = 0; i < ow->conn; i++) {
	  nb = c + neighbor[i];
	  if (stack->array[nb] && !code_array[nb]) {
	    code_array[nb] = code_array[c] + 1;
	    link[nb] = prev;
	    prev = nb;
	  }
	}
      }
      c = link[c];
    } while (c >= 0);
    entrance = prev;
  }

  
  STACK_OBJLABEL_CLOSE_WORKSPACE(ow);

  return code;
}
Exemple #3
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++;
          }
        }
Exemple #4
0
ZSwcTree* ZSwcGenerator::createSurfaceSwc(const ZStack &stack, int sparseLevel)
{
  if (stack.kind() != GREY) {
    return NULL;
  }

  ZSwcTree *tree = NULL;

  if (stack.hasData()) {
    int width = stack.width();
    int height = stack.height();
    int depth = stack.depth();

    int cwidth = width - 1;
    int cheight = height - 1;
    int cdepth = depth - 1;

    const uint8_t* in_array = stack.array8();

    int conn = 6;
    size_t offset = 0;
    int neighbor[26];
    int is_in_bound[26];
    int n_in_bound;
    int count = 0;

    tree = new ZSwcTree();
    tree->forceVirtualRoot();
    Swc_Tree_Node *root = tree->root();
    Stack_Neighbor_Offset(conn, width, height, neighbor);

    for (int k = 0; k <= cdepth; k++) {
      for (int j = 0; j <= cheight; j++) {
        for (int i = 0; i <= cwidth; i++) {
//          out_array[offset] = 0;
          if (in_array[offset] > 0) {
            n_in_bound = Stack_Neighbor_Bound_Test_S(
                  conn, cwidth, cheight, cdepth, i, j, k, is_in_bound);
            bool isSurface = false;
            if (n_in_bound == conn) {
              for (int n = 0; n < n_in_bound; n++) {
                if (in_array[offset + neighbor[n]] != in_array[offset]) {
                  isSurface = true;
                  break;
                }
              }
            } else {
              isSurface = true;
            }

            if (isSurface) {
              if (count++ % sparseLevel == 0) {
                SwcTreeNode::makePointer(i + stack.getOffset().getX(),
                                         j + stack.getOffset().getY(),
                                         k + stack.getOffset().getZ(),
                                         sparseLevel * 0.7, root);
              }
            }
          }
          offset++;
        }
      }
    }

  }

#if 0
  Stack *surface = Stack_Perimeter(stack.c_stack(), NULL, 6);

#ifdef _DEBUG_2
  C_Stack::write(GET_DATA_DIR + "/test.tif", surface);
#endif


  if (surface != NULL) {
    tree = new ZSwcTree();
    tree->forceVirtualRoot();
    Swc_Tree_Node *root = tree->root();

    int width = C_Stack::width(surface);
    int height = C_Stack::height(surface);
    int depth = C_Stack::depth(surface);

    size_t offset = 0;
    int count = 0;
    for (int z = 0; z < depth; ++z) {
      for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
          if ((surface->array[offset++]) > 0) {
            if (count++ % sparseLevel == 0) {
              SwcTreeNode::makePointer(x + stack.getOffset().getX(),
                                       y + stack.getOffset().getY(),
                                       z + stack.getOffset().getZ(),
                                       sparseLevel * 0.7, root);
            }
          }
        }
      }
    }

    C_Stack::kill(surface);
  }
#endif

  return tree;
}
void Stack_Grow_Object_S(Stack *seed, Stack *mask, Objlabel_Workspace *ow)
{
  ASSERT(seed->kind = GREY, "GREY stack only");
  ASSERT(mask->kind = GREY, "GREY stack only");

  STACK_OBJLABEL_OPEN_WORKSPACE(seed, ow);
  
  int i;
  int nvoxel = Stack_Voxel_Number(seed);
  if (ow->init_chord == TRUE) {
    for (i = 0; i < nvoxel; i++) {
      ow->chord->array[i] = -1;
    }
  }

  int neighbor[26];
  int nbound;
  int is_in_bound[26];
  
  int x, y, z;
  int offset = 0;
  int qbot = -1;
  int qtop = -1;

  int cwidth = seed->width - 1;
  int cheight = seed->height - 1;
  int cdepth = seed->depth - 1;

  int *queue = ow->chord->array;
  int nidx;
  int conn = ow->conn;
 
  PROGRESS_BEGIN("Oject growing");

  Stack_Neighbor_Offset(conn, seed->width, seed->height, neighbor);
  for (z = 0; z < seed->depth; z++) {
    PROGRESS_STATUS(z * 90 / seed->depth);
    for (y = 0; y < seed->height; y++) {
      for (x = 0; x < seed->width; x++) {
	if (seed->array[offset] == 1) {
	  mask->array[offset] = 0;
	  nbound = Stack_Neighbor_Bound_Test(conn, cwidth, cheight, cdepth, 
					     x, y, z, is_in_bound);
	  if (nbound < conn) {
	    for (i = 0; i < conn; i++) {
	      if (is_in_bound[i]) {
		if (seed->array[offset + neighbor[i]] == 0) {
		  STACK_GROW_OBJECT_ENQUEUE(queue, offset);
		  break;
		}
	      }
	    }
	  } else {
	    for (i = 0; i < conn; i++) {
	      if (seed->array[offset + neighbor[i]] == 0) {
		STACK_GROW_OBJECT_ENQUEUE(queue, offset);
		break;
	      }
	    }
	  }
	}
	offset++;
      }
    }
    PROGRESS_REFRESH;
  }

  int area = seed->width * seed->height;
  while (qtop >= 0) {
    STACK_GROW_OBJECT_DEQUEUE(queue, offset);
    STACK_UTIL_COORD(offset, seed->width, area, x, y, z);
    nbound = Stack_Neighbor_Bound_Test(conn, cwidth, cheight, cdepth, 
				       x, y, z, is_in_bound);
    if (nbound < conn) {
      STACK_GROW_OBJECT_ENQUEUE_NEIGHBORS(queue, offset, 
					  (is_in_bound[i] && 
					   mask->array[nidx] == 1));
    } else {
      STACK_GROW_OBJECT_ENQUEUE_NEIGHBORS(queue, offset, 
					  (mask->array[nidx] == 1));
    }
  }

  PROGRESS_END("done");

  STACK_OBJLABEL_CLOSE_WORKSPACE(ow);
  
}
void Stack_Build_Seed_Graph(Stack *stack, int *seed, int nseed,
			    uint8_t **connmat, Objlabel_Workspace *ow)
{
  if (stack->kind != GREY16) {
    PRINT_EXCEPTION("Unsupported stack kind", "The stack must be GREY16");
    return;
  }

  STACK_OBJLABEL_OPEN_WORKSPACE(stack, ow);
  
  int i, j, k;
  int nvoxel = Stack_Voxel_Number(stack);

  if (ow->init_chord == TRUE) {
    for (i = 0; i < nvoxel; i++) {
      ow->chord->array[i] = -1;
    }
  }

  uint16 *mask = (uint16 *) stack->array;

  const int conn = 26;

  /* each seed has a queue */
  int *queue_head = iarray_malloc(nseed); /* queue_head malloced */
  int *queue_tail = iarray_malloc(nseed); /* queue_head malloced */
  int *queue_length = iarray_malloc(nseed);  /* queue_length malloced */

  /* At the beginning, each queue has one element, the corresponding seed */
  iarraycpy(queue_head, seed, 0, nseed);
  iarraycpy(queue_tail, seed, 0, nseed);

  for (i = 0; i < nseed; i++) {
    queue_length[i] = 1;
  }

  int neighbor[26];
  int bound[26];
  int nbound;
  int cwidth = stack->width - 1;
  int cheight = stack->height - 1;
  int cdepth = stack->depth - 1;

  BOOL stop = FALSE;
  int x, y, z;

  Stack_Neighbor_Offset(conn, stack->width, stack->height, neighbor);
  
#define STACK_SEED_GRAPH_UPDATE_QUEUE(test)				\
  for (k = 0; k < conn; k++) {						\
    if (test) {								\
      int checking_voxel = queue_head[i] + neighbor[k];			\
      if ((mask[checking_voxel] > 0) && (mask[checking_voxel] != label)) { \
	if (mask[checking_voxel] == 1) {				\
	  ow->chord->array[queue_tail[i]] = checking_voxel;		\
	  queue_tail[i] = checking_voxel;				\
	  mask[checking_voxel] = label;					\
	  queue_length[i]++;						\
	} else {							\
	  if (mask[checking_voxel] > label) {				\
	    connmat[i][mask[checking_voxel] - 2] = 1;			\
	  } else {							\
	    connmat[mask[checking_voxel] - 2][i] = 1;			\
	  }								\
	}								\
      }									\
    }									\
  }

  while (stop == FALSE) {
    stop = TRUE;
    for (i = 0; i < nseed; i++) {
      if (queue_length[i] > 0) {
	int label = i + 2;
	for (j = 0; j < queue_length[i]; j++) {
	  Stack_Util_Coord(queue_head[i], stack->width, stack->height, 
			   &x, &y, &z);
	  nbound = Stack_Neighbor_Bound_Test(conn, cwidth, cheight, cdepth,
					     x, y, z, bound);
	  if (nbound == conn) {
	    STACK_SEED_GRAPH_UPDATE_QUEUE(1);
	    /*
	    for (k = 0; k < conn; k++) {
	      if (1) {
		int checking_voxel = queue_head[i] + neighbor[k];
		if ((mask[checking_voxel] > 0) && (mask[checking_voxel] != label)) { 
		  if (mask[checking_voxel] == 1) {				
		    ow->chord->array[queue_tail[i]] = checking_voxel;		
		    queue_tail[i] = checking_voxel;				
		    mask[checking_voxel] = label;  
		    queue_length[i]++;		
		  } else {				
		    if (mask[checking_voxel] > label) {		
		      connmat[mask[checking_voxel] - 2][i] = 1;		
		    } else {				
		      connmat[i][mask[checking_voxel] - 2] = 1;	
		    }						
		  }						
		}								
	      }					
	    }
	    */
	  } else {
	    STACK_SEED_GRAPH_UPDATE_QUEUE(bound[k]);
	  }
	}
	queue_head[i] = ow->chord->array[queue_head[i]];
	queue_length[i]--;
	stop = FALSE;
      }
    }
  }

  free(queue_head); /* queue_head freed */
  free(queue_tail); /* queue_head freed */
  free(queue_length);  /* queue_length freed */

  STACK_OBJLABEL_CLOSE_WORKSPACE(ow);
}
int Stack_Label_Object_Level_Nw(Stack *stack, int seed, 
				int flag, int label, Stack *code, int max,
				Objlabel_Workspace *ow)
{
  STACK_OBJLABEL_OPEN_WORKSPACE(stack, ow);

  if (stack->array[seed] != flag) {
    TZ_WARN(ERROR_OTHER);
    fprintf(stderr, "The seed does not have the right flag.\n");
    return 0;
  }

  IMatrix *chord = ow->chord;

  int npixel = Get_Stack_Size(stack);

  int i;
  int c = seed; /* center pixel */
  int nb;       /* neighobr pixel */
  
  for (i = 0; i < npixel; i++) {
    chord->array[i] = -1;
  }
 
  int obj_size = 0;
  int next = c;
  uint16 *code_array = NULL;
  BOOL do_label = TRUE;

  if (code != NULL) {
    code_array = (uint16 *)code->array;
  }

  stack->array[seed] = label;

  int n_nbr = ow->conn;
  int neighbor[26];
  Stack_Neighbor_Offset(n_nbr, stack->width, stack->height, neighbor);
  
  int x, y, z;
  int is_in_bound[26];
  int n_in_bound = 0;
  int cwidth = stack->width - 1;
  int cheight = stack->height - 1;
  int cdepth = stack->depth - 1;

  do {
    Stack_Util_Coord(c, stack->width, stack->height, &x, &y, &z);
    n_in_bound = Stack_Neighbor_Bound_Test(n_nbr, cwidth, cheight, cdepth, 
					   x, y, z, is_in_bound);
					       
    /* add all unlabeled neighbors to the queue*/    
    if (n_in_bound == n_nbr) { /* no boundary check required */
      for (i = 0; i < n_nbr; i++) {
	STACK_LABEL_OBJECT_CONSTRAINT_N_UPDATE_QUEUE(stack->array);
      }
    } else {
      for (i = 0; i < n_nbr; i++) {
	if (is_in_bound[i]) {
	  STACK_LABEL_OBJECT_CONSTRAINT_N_UPDATE_QUEUE(stack->array);
	}
      }
    }

    c = chord->array[c]; /* move to next voxel */
    obj_size++;

    if (code == NULL) {
      if (obj_size >= max) {
	break;
      }
    }
  } while (c >= 0);

  STACK_OBJLABEL_CLOSE_WORKSPACE(ow);

  return obj_size;  
}
int Stack_Label_Object_Dist_N(Stack *stack, IMatrix *chord, int seed, 
			      int flag, int label, double max_dist,
			      int n_nbr)
{
  BOOL is_owner = FALSE;

  if (chord == NULL) {
    chord = Make_3d_IMatrix(stack->width, stack->height, stack->depth);
    is_owner = TRUE;
  } else {
    if (chord->ndim != 3) {
      THROW(ERROR_DATA_TYPE);
    }
    
    if ((stack->width != chord->dim[0]) || (stack->height != chord->dim[1]) 
	|| (stack->depth != chord->dim[2])) {
      THROW(ERROR_DATA_COMPTB);
    }
  }

  if (flag >= 0) {
    if (stack->array[seed] != flag) {
      TZ_WARN(ERROR_OTHER);
      fprintf(stderr, "The seed does not have the right flag.\n");
      return 0;
    }
  }

  int npixel = Get_Stack_Size(stack);

  int i;
  int c = seed; /* center pixel */
  int nb;       /* neighobr pixel */
  
  for (i = 0; i < npixel; i++) {
    chord->array[i] = -1;
  }
 
  int obj_size = 0;
  int next = c;
  BOOL do_label = TRUE;
  double max_dist_square = max_dist * max_dist;

  stack->array[seed] = label;

  int neighbor[26];
  Stack_Neighbor_Offset(n_nbr, stack->width, stack->height, neighbor);

#define STACK_LABEL_OBJECT_DIST_N_UPDATE_QUEUE				\
  {									\
    nb = c + neighbor[i];						\
    Stack_Util_Coord(nb, stack->width, stack->height, &nx, &ny, &nz);	\
    /*process unlabeled white neighbors*/				\
    dx = nx - cx;							\
    dy = ny - cy;							\
    dz = nz - cz;							\
    if (dx * dx + dy * dy + dz * dz > max_dist_square) {		\
      do_label = FALSE;							\
    } else {								\
      do_label = TRUE;							\
    }									\
    									\
    if ((((flag < 0) && (stack->array[nb] != label)) ||			\
	(stack->array[nb] == flag)) &&					\
	(chord->array[nb] == -1) && (do_label == TRUE)) {		\
      chord->array[next] = nb;						\
      next = nb;							\
      stack->array[nb] = label;						\
    }									\
  }
  
  int x, y, z;
  int cx, cy, cz;
  int nx, ny, nz;
  int dx, dy, dz;
  int is_in_bound[26];
  int n_in_bound = 0;
  int cwidth = stack->width - 1;
  int cheight = stack->height - 1;
  int cdepth = stack->depth - 1;

  Stack_Util_Coord(seed, stack->width, stack->height, &cx, &cy, &cz);

  do {
    Stack_Util_Coord(c, stack->width, stack->height, &x, &y, &z);
    n_in_bound = Stack_Neighbor_Bound_Test(n_nbr, cwidth, cheight, cdepth, 
					   x, y, z, is_in_bound);
    
    /* add all unlabeled neighbors to the queue*/    
    if (n_in_bound == n_nbr) { /* no boundary check required */
      for (i = 0; i < n_nbr; i++) {
	STACK_LABEL_OBJECT_DIST_N_UPDATE_QUEUE;
      }
    } else {
      for (i = 0; i < n_nbr; i++) {
	if (is_in_bound[i]) {
	  STACK_LABEL_OBJECT_DIST_N_UPDATE_QUEUE;
	}
      }
    }

    c = chord->array[c]; /* move to next voxel */
    obj_size++;
  } while (c >= 0);

  if (is_owner == TRUE) {
    Kill_IMatrix(chord);
  }

  return obj_size;  
}
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;
}
Exemple #10
0
int Stack_Label_Object_Level_N(Stack *stack, IMatrix *chord, int seed, 
			       int flag, int label, Stack *code, int max,
			       int n_nbr)
{
  BOOL is_owner = FALSE;

  if (chord == NULL) {
    chord = Make_3d_IMatrix(stack->width, stack->height, stack->depth);
    is_owner = TRUE;
  } else {
    if (chord->ndim != 3) {
      THROW(ERROR_DATA_TYPE);
    }

    if ((stack->width != chord->dim[0]) || (stack->height != chord->dim[1]) 
	|| (stack->depth != chord->dim[2])) {
      THROW(ERROR_DATA_COMPTB);
    }
  }

  if (stack->array[seed] != flag) {
    TZ_WARN(ERROR_OTHER);
    fprintf(stderr, "The seed does not have the right flag.\n");
    return 0;
  }

  int npixel = Get_Stack_Size(stack);

  int i;
  int c = seed; /* center pixel */
  int nb;       /* neighobr pixel */
  
  for (i = 0; i < npixel; i++) {
    chord->array[i] = -1;
  }
 
  int obj_size = 0;
  int next = c;
  uint16 *code_array = NULL;
  BOOL do_label = TRUE;

  if (code != NULL) {
    code_array = (uint16 *)code->array;
  }

  stack->array[seed] = label;

  int neighbor[26];
  Stack_Neighbor_Offset(n_nbr, stack->width, stack->height, neighbor);
  
  int x, y, z;
  int is_in_bound[26];
  int n_in_bound = 0;
  int cwidth = stack->width - 1;
  int cheight = stack->height - 1;
  int cdepth = stack->depth - 1;

  do {
    Stack_Util_Coord(c, stack->width, stack->height, &x, &y, &z);
    n_in_bound = Stack_Neighbor_Bound_Test(n_nbr, cwidth, cheight, cdepth, 
					   x, y, z, is_in_bound);
					       
    /* add all unlabeled neighbors to the queue*/    
    if (n_in_bound == n_nbr) { /* no boundary check required */
      for (i = 0; i < n_nbr; i++) {
	STACK_LABEL_OBJECT_CONSTRAINT_N_UPDATE_QUEUE(stack->array);
      }
    } else {
      for (i = 0; i < n_nbr; i++) {
	if (is_in_bound[i]) {
	  STACK_LABEL_OBJECT_CONSTRAINT_N_UPDATE_QUEUE(stack->array);
	}
      }
    }

    c = chord->array[c]; /* move to next voxel */
    obj_size++;

    if (code == NULL) {
      if (obj_size >= max) {
	break;
      }
    }
  } while (c >= 0);

  if (is_owner == TRUE) {
    Kill_IMatrix(chord);
  }

  return obj_size;
}
Exemple #11
0
int Stack_Label_Object_W(Stack *stack, int seed, int flag, int label, 
			 Objlabel_Workspace *ow)
{
  TZ_ASSERT(stack->kind == GREY || stack->kind == GREY16, "Unsupported kind.");

  STACK_OBJLABEL_OPEN_WORKSPACE(stack, ow);
  ow->seed = seed;

  uint16_t* array16 = (uint16_t*) stack->array;
  uint8_t* array8 = (uint8_t*) stack->array;

  if (stack->kind == GREY) {
    if (stack->array[seed] != flag) {
      TZ_WARN(ERROR_OTHER);
      fprintf(stderr, "The seed does not have the right flag.\n");
      return 0;
    }
  } else {
    if (array16[seed] != flag) {
      TZ_WARN(ERROR_OTHER);
      fprintf(stderr, "The seed does not have the right flag.\n");
      return 0;
    }
  }

  int npixel = Get_Stack_Size(stack);
  
  int i;
  int c = seed; /* center pixel */
  int nb;       /* neighobr pixel */
  
  if (ow->init_chord == TRUE) {
    for (i = 0; i < npixel; i++) {
      ow->chord->array[i] = -1;
    }
  }

  int obj_size = 0;
  int next = c;

  if (stack->kind == GREY) {
    stack->array[seed] = label;
  } else {
    array16[seed] = label;
  }
  
  int x, y, z;
  int is_in_bound[26];
  int n_in_bound = 0;
  int cwidth = stack->width - 1;
  int cheight = stack->height - 1;
  int cdepth = stack->depth - 1;

  int neighbor[26];
  Stack_Neighbor_Offset(ow->conn, stack->width, stack->height, neighbor);

#define STACK_LABEL_OBJECT_N_UPDATE_QUEUE(stack_array)			\
    {									\
      nb = c + neighbor[i];						\
      /*process unlabeled white neighbors*/				\
      if ((stack_array[nb] == flag) && (ow->chord->array[nb] == -1)) {	\
	ow->chord->array[next] = nb;					\
        TZ_ASSERT(ow->chord->array[next] != next, "loop"); \
	next = nb;							\
	stack_array[nb] = label;					\
      }									\
    }	

  int area = stack->width * stack->height;

  do {
    z = c / area;
    if (z > stack->depth) {
      n_in_bound = 0;
    } else {
      y = c % area;
      x = y % stack->width;
      y = y / stack->width;

      if ((x > stack->width) || (y > stack->height)) {
	n_in_bound = 0;
      } else {
	//Stack_Util_Coord(c, stack->width, stack->height, &x, &y, &z);
	if ((x > 0) && (x < cwidth) && (y > 0) && (y < cheight) && 
	    (z > 0) && (z < cdepth)) { 
	  n_in_bound = ow->conn;
	} else {
	  n_in_bound = Stack_Neighbor_Bound_Test_S(ow->conn, 
						 cwidth, cheight, cdepth, 
						 x, y, z, is_in_bound);
	}
      }
    }
					       
    /* add all unlabeled neighbors to the queue*/    
    if (n_in_bound == ow->conn) { /* no boundary check required */
      if (stack->kind == GREY) {
        for (i = 0; i < ow->conn; i++) {
          STACK_LABEL_OBJECT_N_UPDATE_QUEUE(array8);
        }
      } else {
        for (i = 0; i < ow->conn; i++) {
          STACK_LABEL_OBJECT_N_UPDATE_QUEUE(array16);
        }
      }
    } else {
      for (i = 0; i < ow->conn; i++) {
	if (is_in_bound[i]) {
          if (stack->kind == GREY) {
            STACK_LABEL_OBJECT_N_UPDATE_QUEUE(array8);
          } else {
            STACK_LABEL_OBJECT_N_UPDATE_QUEUE(array16);
          }
	}
      }
    }

    c = ow->chord->array[c]; /* move to next voxel */
    obj_size++;
  } while (c >= 0);

  STACK_OBJLABEL_CLOSE_WORKSPACE(ow);

  return obj_size;
}
Exemple #12
0
/**
 * Stack_Build_Seed_Graph_Gg() allows users to build a seed graph using 
 * approximate geodesdic distances. The workspace should be created by
 * Make_Objlabel_Workspace_Gg() and initialized by Init_Objlabel_Workspace_Gg()
 * if necessary.
 */
Graph* Stack_Build_Seed_Graph_Gg(Stack *stack, int *seed, int nseed,
				BOOL weighted, Objlabel_Workspace *ow)
{
  if (stack->kind != GREY16) {
    PRINT_EXCEPTION("Unsupported stack kind", "The stack must be GREY16");
    return NULL;
  }
  
  int i, j, k;

  uint16 *level = (uint16 *) ow->u;
  uint16 *mask = (uint16 *) stack->array;

  const int conn = 26;

  /* each seed has a queue */
  int *queue_head = iarray_malloc(nseed); /* queue_head malloced */
  int *queue_tail = iarray_malloc(nseed); /* queue_head malloced */
  int *queue_length = iarray_malloc(nseed);  /* queue_length malloced */

  /* At the beginning, each queue has one element, the corresponding seed */
  iarraycpy(queue_head, seed, 0, nseed);
  iarraycpy(queue_tail, seed, 0, nseed);

  for (i = 0; i < nseed; i++) {
    queue_length[i] = 1;
  }

  int neighbor[26];
  int bound[26];
  int nbound;
  int cwidth = stack->width - 1;
  int cheight = stack->height - 1;
  int cdepth = stack->depth - 1;

  BOOL stop = FALSE;
  int x, y, z;

  Stack_Neighbor_Offset(conn, stack->width, stack->height, neighbor);
  
#define STACK_SEED_GRAPH_UPDATE_QUEUE_GG(test)				\
  for (k = 0; k < conn; k++) {						\
    if (test) {								\
      int checking_voxel = queue_head[i] + neighbor[k];			\
      if ((mask[checking_voxel] > 0) && (mask[checking_voxel] != label)) { \
	if (mask[checking_voxel] == 1) {				\
	  ow->chord->array[queue_tail[i]] = checking_voxel;		\
	  queue_tail[i] = checking_voxel;				\
	  mask[checking_voxel] = label;					\
	  level[checking_voxel] = level[queue_head[i]] + 1;		\
	  queue_length[i]++;						\
	} else {							\
	  int v1, v2, tmp;						\
	  v1 = i;							\
	  v2 = mask[checking_voxel] - 2;				\
	  ASSERT(v1 != v2, "Bug in Stack_Build_Seed_Graph_G()");	\
	  if (v1 > v2) {						\
	    SWAP2(v1, v2, tmp);						\
	  }								\
	  if (Graph_Edge_Index(v1, v2, gw) < 0) {			\
	    if (weighted == TRUE) {					\
	      /*double dist = Stack_Util_Voxel_Distance(seed[v1], seed[v2], stack->width, stack->height);*/ \
	      double dist = level[checking_voxel] + level[queue_head[i]]; \
	      Graph_Add_Weighted_Edge(graph, v1, v2, dist);		\
	    } else {							\
	      Graph_Add_Edge(graph, v1, v2);				\
	    }								\
	    Graph_Expand_Edge_Table(v1, v2, graph->nedge -1, gw);	\
	  }								\
	}								\
      }									\
    }									\
  }

  Graph *graph = Make_Graph(nseed, nseed, weighted);
  Graph_Workspace *gw = New_Graph_Workspace();

  while (stop == FALSE) {
    stop = TRUE;
    for (i = 0; i < nseed; i++) {
      if (queue_length[i] > 0) {
	int label = i + 2;
	for (j = 0; j < queue_length[i]; j++) {
	  Stack_Util_Coord(queue_head[i], stack->width, stack->height, 
			   &x, &y, &z);
	  nbound = Stack_Neighbor_Bound_Test(conn, cwidth, cheight, cdepth,
					     x, y, z, bound);
	  if (nbound == conn) {
	    STACK_SEED_GRAPH_UPDATE_QUEUE_GG(1);
	  } else {
	    STACK_SEED_GRAPH_UPDATE_QUEUE_GG(bound[k]);
	  }
	}
	queue_head[i] = ow->chord->array[queue_head[i]];
	queue_length[i]--;
	stop = FALSE;
      }
    }
  }

  free(queue_head); /* queue_head freed */
  free(queue_tail); /* queue_head freed */
  free(queue_length);  /* queue_length freed */

  return graph;
}
Exemple #13
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;  
}
Exemple #14
0
Graph* Stack_Graph_W(const Stack *stack, Stack_Graph_Workspace *sgw)
{
  int x, y, z;
  int offset = 0;
  int is_in_bound[26];
  int nbound;
  int i;
  int stack_range[6];

  int *range = sgw->range;

  if (range == NULL) {
    stack_range[0] = 0;
    stack_range[1] = stack->width - 1;
    stack_range[2] = 0;
    stack_range[3] = stack->height - 1;
    stack_range[4] = 0;
    stack_range[5] = stack->depth - 1;
  } else {
    stack_range[0] = imax2(0, range[0]);
    stack_range[1] = imin2(stack->width - 1, range[1]);
    stack_range[2] = imax2(0, range[2]);
    stack_range[3] = imin2(stack->height - 1, range[3]);
    stack_range[4] = imax2(0, range[4]);
    stack_range[5] = imin2(stack->depth - 1, range[5]);
  }
  
  int cdepth = stack_range[5] - stack_range[4];
  int cheight = stack_range[3] - stack_range[2];
  int cwidth = stack_range[1] - stack_range[0];
  
  int nvertex = (cwidth + 1) * (cheight + 1) * (cdepth + 1);
  sgw->virtualVertex = nvertex;

  BOOL weighted = TRUE;
  if (sgw->sp_option == 1) {
    weighted = FALSE;
    sgw->intensity = darray_malloc(nvertex + 1);
    sgw->intensity[nvertex] = Infinity;
  }
  Graph *graph = Make_Graph(nvertex, nvertex, weighted);

  int neighbor[26];
  int scan_mask[26];
  Stack_Neighbor_Offset(sgw->conn, cwidth + 1, cheight + 1, neighbor);

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

  double dist[26];
  Stack_Neighbor_Dist_R(sgw->conn, sgw->resolution, dist);
  //const double *dist = Stack_Neighbor_Dist(sgw->conn);
  const int *x_offset = Stack_Neighbor_X_Offset(sgw->conn);
  const int *y_offset = Stack_Neighbor_Y_Offset(sgw->conn);
  const int *z_offset = Stack_Neighbor_Z_Offset(sgw->conn);

  /* go forward */
  for (i = 0; i < sgw->conn; i++) {
    scan_mask[i] = (neighbor[i] > 0);
  }

#define STACK_GRAPH_ADD_EDGE(cond) \
  for (i = 0; i < sgw->conn; i++) { \
    if (cond) { \
      int nx = x + stack_range[0]; \
      int ny = y + stack_range[2]; \
      int nz = z + stack_range[4]; \
      if (Graph_Is_Weighted(graph)) { \
	double weight = dist[i]; \
	if (sgw->wf != NULL) { \
	  sgw->argv[0] = dist[i]; \
	  \
	  sgw->argv[1] = Get_Stack_Pixel((Stack *)stack, nx, ny, nz, 0); \
	  sgw->argv[2] = \
	  Get_Stack_Pixel((Stack *)stack, nx + x_offset[i], \
	      ny + y_offset[i], nz + z_offset[i], 0); \
	  weight = sgw->wf(sgw->argv); \
	} \
	Graph_Add_Weighted_Edge(graph, offset, offset + neighbor[i], \
	    weight); \
      } else { \
	Graph_Add_Edge(graph, offset, offset + neighbor[i]); \
	sgw->intensity[offset] = Get_Stack_Pixel((Stack*) stack, \
	      nx, ny, nz, 0); \
      } \
    } \
  }

  int groupVertexMap[256];
  for (i = 0; i < 256; ++i) {
    groupVertexMap[i] = 0;
  }

  int swidth = cwidth + 1;
  int sarea =  (cwidth + 1) * (cheight + 1);
  int area = stack->width * stack->height;
  for (z = 0; z <= cdepth; z++) {
    for (y = 0; y <= cheight; y++) {
      for (x = 0; x <= cwidth; x++) {
	nbound = Stack_Neighbor_Bound_Test_S(sgw->conn, cwidth, cheight, 
					     cdepth, 
					     x, y, z, is_in_bound);
	size_t offset2 = Stack_Subindex((size_t) offset, stack_range[0],
	    stack_range[2], stack_range[4],
	    swidth, sarea, stack->width, area);

#ifdef _DEBUG_2
        if (offset == 36629) {
          printf("debug here\n");
        }
#endif

	if (nbound == sgw->conn) {
	  STACK_GRAPH_ADD_EDGE((scan_mask[i] == 1) && 
              (sgw->signal_mask == NULL ? 1 : 
               ((sgw->signal_mask->array[offset2] > 0) &&
                (sgw->signal_mask->array[offset2+org_neighbor[i]] > 0))))
	} else {
	  STACK_GRAPH_ADD_EDGE((scan_mask[i] == 1) && is_in_bound[i] && 
	      (sgw->signal_mask == NULL ? 1 : 
	       ((sgw->signal_mask->array[offset2] > 0) &&
		(sgw->signal_mask->array[offset2+org_neighbor[i]]) >
		0)))
	}
	if (sgw->group_mask != NULL) {
          int groupId = sgw->group_mask->array[offset2];
	  if (groupId > 0) {
#ifdef _DEBUG_2
	    sgw->group_mask->array[offset2] = 2;
#endif
            int groupVertex = groupVertexMap[groupId];
            if (groupVertex <= 0) {
              groupVertex = nvertex++;
              groupVertexMap[groupId] = groupVertex;
            }

            Graph_Add_Weighted_Edge(graph, groupVertex, offset, 0.0);
	  }
	}

	offset++;
      }
    }
  }

  return graph;
}
Exemple #15
0
Graph* Stack_Graph(const Stack *stack, int conn, const int *range, 
		   Weight_Func_t *wf)
{
  int x, y, z;
  int offset = 0;
  int is_in_bound[26];
  int nbound;
  int i;
  int stack_range[6];

  if (range == NULL) {
    stack_range[0] = 0;
    stack_range[1] = stack->width - 1;
    stack_range[2] = 0;
    stack_range[3] = stack->height - 1;
    stack_range[4] = 0;
    stack_range[5] = stack->depth - 1;
  } else {
    stack_range[0] = imax2(0, range[0]);
    stack_range[1] = imin2(stack->width - 1, range[1]);
    stack_range[2] = imax2(0, range[2]);
    stack_range[3] = imin2(stack->height - 1, range[3]);
    stack_range[4] = imax2(0, range[4]);
    stack_range[5] = imin2(stack->depth - 1, range[5]);
  }
  
  int cdepth = stack_range[5] - stack_range[4];
  int cheight = stack_range[3] - stack_range[2];
  int cwidth = stack_range[1] - stack_range[0];
  
  int nvertex = (cwidth + 1) * (cheight + 1) * (cdepth + 1);

  Graph *graph = Make_Graph(nvertex, nvertex, TRUE);

  int neighbor[26];
  int scan_mask[26];
  Stack_Neighbor_Offset(conn, cwidth + 1, cheight + 1, neighbor);

  const double *dist = Stack_Neighbor_Dist(conn);
  const int *x_offset = Stack_Neighbor_X_Offset(conn);
  const int *y_offset = Stack_Neighbor_Y_Offset(conn);
  const int *z_offset = Stack_Neighbor_Z_Offset(conn);

  double args[3];

  for (i = 0; i < conn; i++) {
    scan_mask[i] = (neighbor[i] > 0);
  }

  for (z = 0; z <= cdepth; z++) {
    for (y = 0; y <= cheight; y++) {
      for (x = 0; x <= cwidth; x++) {
	nbound = Stack_Neighbor_Bound_Test(conn, cwidth, cheight, cdepth, 
					   x, y, z, is_in_bound);
	if (nbound == conn) {
	  for (i = 0; i < conn; i++) {
	    if (scan_mask[i] == 1) {
	      double weight = dist[i];
	      if (wf != NULL) {
		args[0] = dist[i];
		args[1] = Get_Stack_Pixel((Stack *)stack, x + stack_range[0], 
					  y + stack_range[2], 
					  z + stack_range[4], 0);
		args[2] = Get_Stack_Pixel((Stack *)stack, 
					  x + stack_range[0] + x_offset[i],
					  y + stack_range[2] + y_offset[i],
					  z + stack_range[4] + z_offset[i], 0);
		weight = wf(args);
	      }
	      Graph_Add_Weighted_Edge(graph, offset, offset + neighbor[i], 
				      weight);
	    }
	  }
	} else {
	  for (i = 0; i < conn; i++) {
	    if ((scan_mask[i] == 1) && is_in_bound[i]){
	      double weight = dist[i];
	      if (wf != NULL) {
		args[0] = dist[i];
		args[1] = Get_Stack_Pixel((Stack *)stack, x + stack_range[0], 
					  y + stack_range[2], 
					  z + stack_range[4], 0);
		args[2] = Get_Stack_Pixel((Stack *)stack, 
					  x + stack_range[0] + x_offset[i],
					  y + stack_range[2] + y_offset[i],
					  z + stack_range[4] + z_offset[i], 0);
		weight = wf(args);
	      }
	      Graph_Add_Weighted_Edge(graph, offset, offset + neighbor[i], 
				      weight);
	    }
	  }
	}
	offset++;
      }
    }
  }

  return graph;
}