Example #1
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;
}
Example #2
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;
}
Example #3
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;
}