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; }
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; }
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; }