Graph* Swc_Arraylist_Graph(const Swc_Arraylist *sc, int *q) { BOOL is_owner = TRUE; if (q != NULL) { is_owner = FALSE; } q = Swc_Arraylist_Queue(sc, q); Graph *graph = Make_Graph(sc->length, sc->length - 1, FALSE); Graph_Set_Directed(graph, TRUE); int i; for (i = 0; i < sc->length; i++) { if (q[i] >= 0) { Graph_Add_Edge(graph, q[i], i); } } if (is_owner == TRUE) { free(q); } return graph; }
void solve() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%lf%lf", &p[i].x, &p[i].y), p[i].index = i, p[i].in = NULL; Alloc_memory(); sort(p, p + n); for (int i = 0; i < n; i++) Q[i] = p + i; edge *L, *R; Divide(0, n - 1, &L, &R); M = 0; Make_Graph(); Kruskal(); }
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; }
/** * 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; }
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; }
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; }
int main() { #if 0 char *filepath = "../data/fly_neuron_n2/graph_d.swc"; Neuron_Structure *ns = Neuron_Structure_From_Swc_File(filepath); Neuron_Component_Arraylist *comp_array = Neuron_Structure_Branch_Point(ns); filepath = "../data/fly_neuron_n2.tif"; Stack *stack = Read_Stack(filepath); Translate_Stack(stack, COLOR, 1); int i; Stack_Draw_Workspace *ws = New_Stack_Draw_Workspace(); for (i = 0; i < comp_array->length; i++) { Neuron_Component_Draw_Stack(comp_array->array + i, stack, ws); } Kill_Stack_Draw_Workspace(ws); Write_Stack("../data/test.tif", stack); #endif #if 0 Stack *stack = NULL; Locseg_Chain *chain1 = Read_Locseg_Chain("../data/fly_neuron_n3/chain0.tb"); Locseg_Chain *chain2 = Read_Locseg_Chain("../data/fly_neuron_n3/chain10.tb"); Connection_Test_Workspace *ws = New_Connection_Test_Workspace(); Connection_Test_Workspace_Read_Resolution(ws, "../data/fly_neuron_n1.res"); Neurocomp_Conn conn; conn.mode = NEUROCOMP_CONN_HL; Locseg_Chain_Connection_Test(chain1, chain2, stack, 1.0, &conn, ws); Print_Neurocomp_Conn(&conn); #endif #if 0 Locseg_Chain **chain = (Locseg_Chain**) malloc(sizeof(Locseg_Chain*) * 3); chain[0] = Read_Locseg_Chain("../data/mouse_single_org/chain4.tb"); chain[1] = Read_Locseg_Chain("../data/mouse_single_org/chain19.tb"); chain[2] = Read_Locseg_Chain("../data/mouse_single_org/chain64.tb"); Stack *signal = Read_Stack("../data/mouse_single_org.tif"); Connection_Test_Workspace *ctw = New_Connection_Test_Workspace(); FILE *fp = fopen("../data/mouse_single_org.res", "r"); darray_fscanf(fp, ctw->resolution, 3); Neuron_Component *chain_array = Make_Neuron_Component_Array(3); int i; for (i = 0; i < 3; i++) { Set_Neuron_Component(chain_array + i, NEUROCOMP_TYPE_LOCSEG_CHAIN, chain[i]); } Neuron_Structure *ns = Locseg_Chain_Comp_Neurostruct(chain_array, 3, signal, 1.0, ctw); Graph *graph = ns->graph; Process_Neuron_Structure(ns); Print_Neuron_Structure(ns); Neuron_Structure_Crossover_Test(ns, 0.5375); printf("\ncross over changed: \n"); Print_Neuron_Structure(ns); #endif #if 0 Neuron_Structure *ns = Make_Neuron_Structure(5); Set_Neuron_Component(ns->comp, NEUROCOMP_TYPE_GEO3D_CIRCLE, New_Geo3d_Circle()); Set_Neuron_Component(ns->comp + 1, NEUROCOMP_TYPE_GEO3D_CIRCLE, New_Geo3d_Circle()); Set_Neuron_Component(ns->comp + 2, NEUROCOMP_TYPE_GEO3D_CIRCLE, New_Geo3d_Circle()); Set_Neuron_Component(ns->comp + 3, NEUROCOMP_TYPE_GEO3D_CIRCLE, New_Geo3d_Circle()); Set_Neuron_Component(ns->comp + 4, NEUROCOMP_TYPE_GEO3D_CIRCLE, New_Geo3d_Circle()); NEUROCOMP_GEO3D_CIRCLE(ns->comp)->radius = 1.5; NEUROCOMP_GEO3D_CIRCLE(ns->comp + 1)->radius = 2.5; NEUROCOMP_GEO3D_CIRCLE(ns->comp + 2)->radius = 3.5; NEUROCOMP_GEO3D_CIRCLE(ns->comp + 3)->radius = 4.5; NEUROCOMP_GEO3D_CIRCLE(ns->comp + 4)->radius = 5.5; ns->graph = Make_Graph(5, 4, 0); //Graph_Add_Edge(ns->graph, 0, 1); Graph_Add_Edge(ns->graph, 1, 3); Graph_Add_Edge(ns->graph, 1, 4); Graph_Add_Edge(ns->graph, 0, 2); Graph_Set_Directed(ns->graph, TRUE); Print_Graph(ns->graph); Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns, 1.0, NULL); Print_Swc_Tree(tree); Swc_Tree_To_Dot_File(tree, "../data/test2.dot"); #endif #if 0 int n; Neuron_Component *chain_array = Dir_Locseg_Chain_Nc("../data/fly_neuron_n22", "^chain.*\\.tb", &n, NULL); Neuron_Structure *ns = Locseg_Chain_Comp_Neurostruct(chain_array, n, NULL, 1.0, NULL); Process_Neuron_Structure(ns); Neuron_Structure* ns2= Neuron_Structure_Locseg_Chain_To_Circle(ns); Neuron_Structure_To_Tree(ns2); Graph_To_Dot_File(ns2->graph, "../data/test.dot"); Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, NULL); Swc_Tree_Remove_Zigzag(tree); //Swc_Tree_Tune_Fork(tree); //Print_Swc_Tree(tree); Write_Swc_Tree("../data/test.swc", tree); #endif #if 0 Graph *graph = Neuron_Structure_Import_Xml_Graph("../data/mouse_single_org/trueconn2.xml"); Graph_Normalize_Edge(graph); Graph_Remove_Duplicated_Edge(graph); Graph *graph2 = Neuron_Structure_Import_Xml_Graph("../data/mouse_single_org/conn.xml"); Graph_Normalize_Edge(graph2); Graph_Remove_Duplicated_Edge(graph2); Graph_Workspace *gw = New_Graph_Workspace(); int n = Graph_Edge_Count(graph, graph2->edges, graph2->nedge, gw); printf("fp: %d\n", graph2->nedge - n); printf("tp: %d\n", n); printf("fn: %d\n", graph->nedge - n); double p = (double) n / graph2->nedge; double r = (double) n / graph->nedge; printf("precision: %g\n", p); printf("recall: %g\n", r); printf("F-measure: %g\n", 2.0 * (p * r) / (p + r)); #endif #if 0 Neuron_Structure *ns = Make_Neuron_Structure(2); Local_Neuroseg *locseg = New_Local_Neuroseg(); Locseg_Chain *chain1 = New_Locseg_Chain(); Locseg_Chain_Add(chain1, locseg, NULL, DL_TAIL); Set_Neuron_Component(ns->comp, NEUROCOMP_TYPE_LOCSEG_CHAIN, chain1); Locseg_Chain *chain2 = New_Locseg_Chain(); locseg = New_Local_Neuroseg(); double bottom[3] = {10, 10, 5}; double top[3] = {5, 5, 5}; Local_Neuroseg_Set_Bottom_Top(locseg, bottom, top); Locseg_Chain_Add(chain2, locseg, NULL, DL_TAIL); Set_Neuron_Component(ns->comp + 1, NEUROCOMP_TYPE_LOCSEG_CHAIN, chain2); Neurocomp_Conn *conn = New_Neurocomp_Conn(); Connection_Test_Workspace *ctw = New_Connection_Test_Workspace(); Locseg_Chain_Connection_Test(chain2, chain1, NULL, 1.0, conn, ctw); Neuron_Structure_Add_Conn(ns, 1, 0, conn); Print_Neuron_Structure(ns); Neuron_Structure *ns2 = Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0); Neuron_Structure_To_Swc_File(ns2, "../data/test.swc"); #endif #if 0 int n; Locseg_Chain **chain_array = Dir_Locseg_Chain_Nd("../data/diadem_a1_part3", "^chain.*\\.tb", &n, NULL); /* Locseg_Chain **chain_array = Locseg_Chain_Import_List("../data/diadem_a1_part2/good_tube.txt", &n); */ //n = 100; /* Locseg_Chain **chain_array = (Locseg_Chain**) malloc(sizeof(Locseg_Chain*) * 2); n = 2; chain_array[0] = Read_Locseg_Chain("../data/diadem_a1_part2/chain58.tb"); chain_array[1] = Read_Locseg_Chain("../data/diadem_a1_part2/chain154.tb"); */ Stack *stack = Read_Stack("../data/diadem_a1_part3.tif"); Stack *mask = Make_Stack(GREY, stack->width, stack->height, stack->depth); Zero_Stack(mask); Sp_Grow_Workspace *sgw = New_Sp_Grow_Workspace(); sgw->size = Stack_Voxel_Number(stack); sgw->resolution[0] = 0.0375 * 2.0; sgw->resolution[1] = 0.0375 * 2.0; sgw->resolution[2] = 0.33; Sp_Grow_Workspace_Set_Mask(sgw, mask->array); sgw->wf = Stack_Voxel_Weight_S; Stack_Sp_Grow_Infer_Parameter(sgw, stack); Neuron_Structure *ns = Locseg_Chain_Sp_Grow_Reconstruct(chain_array, n, stack, 1.0, sgw); Print_Neuron_Structure(ns); Graph_To_Dot_File(ns->graph, "../data/test.dot"); //Neuron_Structure_To_Swc_File(ns, "../data/test.swc"); Neuron_Structure *ns2 = Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0); //double root[3] = {31, 430, 0}; double root[3] = {1221, 449, 8.5}; Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, root); Swc_Tree_Clean_Root(tree); Swc_Tree_Resort_Id(tree); Write_Swc_Tree("../data/test.swc", tree); #endif #if 0 int n; Locseg_Chain **chain_array = Dir_Locseg_Chain_Nd("../data/diadem_e1", "^chain.*\\.tb", &n, NULL); //n = 100; /* Locseg_Chain **chain_array = (Locseg_Chain**) malloc(sizeof(Locseg_Chain*) * 2); n = 2; chain_array[0] = Read_Locseg_Chain("../data/diadem_a1_part2/chain58.tb"); chain_array[1] = Read_Locseg_Chain("../data/diadem_a1_part2/chain154.tb"); */ Stack *stack = Read_Stack("../data/diadem_e1.tif"); Stack *mask = Make_Stack(GREY, stack->width, stack->height, stack->depth); Zero_Stack(mask); Sp_Grow_Workspace *sgw = New_Sp_Grow_Workspace(); sgw->size = Stack_Voxel_Number(stack); sgw->resolution[0] = 0.3296485; sgw->resolution[1] = 0.3296485; sgw->resolution[2] = 1.0; Sp_Grow_Workspace_Set_Mask(sgw, mask->array); sgw->wf = Stack_Voxel_Weight_S; Stack_Sp_Grow_Infer_Parameter(sgw, stack); Neuron_Structure *ns = Locseg_Chain_Sp_Grow_Reconstruct(chain_array, n, stack, 1.0, sgw); Print_Neuron_Structure(ns); //Neuron_Structure_To_Swc_File(ns, "../data/test.swc"); Neuron_Structure *ns2 = Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0); Graph_To_Dot_File(ns2->graph, "../data/test.dot"); double root[3] = {31, 430, 0}; //double root[3] = {4882, 1797, 19}; Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, root); //Swc_Tree_Clean_Root(tree); Swc_Tree_Resort_Id(tree); Write_Swc_Tree("../data/test2.swc", tree); #endif #if 0 int n; Locseg_Chain **chain_array = Dir_Locseg_Chain_Nd("../data/benchmark/stack_graph/fork", "^chain.*\\.tb", &n, NULL); Stack *stack = Read_Stack("../data/benchmark/stack_graph/fork/fork.tif"); Stack *mask = Make_Stack(GREY, stack->width, stack->height, stack->depth); Zero_Stack(mask); Sp_Grow_Workspace *sgw = New_Sp_Grow_Workspace(); sgw->size = Stack_Voxel_Number(stack); Sp_Grow_Workspace_Set_Mask(sgw, mask->array); sgw->wf = Stack_Voxel_Weight_S; Stack_Sp_Grow_Infer_Parameter(sgw, stack); Neuron_Structure *ns = Locseg_Chain_Sp_Grow_Reconstruct(chain_array, n, stack, 1.0, sgw); Neuron_Structure *ns2 = Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0); Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, NULL); //Swc_Tree_Clean_Root(tree); Swc_Tree_Resort_Id(tree); Write_Swc_Tree("../data/test.swc", tree); #endif #if 0 int n = 3; Locseg_Chain **chain_array = (Locseg_Chain**) malloc(sizeof(Locseg_Chain) * n); chain_array[0] = Read_Locseg_Chain("/Users/zhaot/Work/neurolabi/data/benchmark/stack_graph/fork/chain0.tb"); chain_array[1] = Read_Locseg_Chain("/Users/zhaot/Work/neurolabi/data/benchmark/stack_graph/fork/chain1.tb"); chain_array[2] = New_Locseg_Chain(); printf("%d\n", Locseg_Chain_Is_Empty(chain_array[2])); Stack *stack = Read_Stack("../data/benchmark/stack_graph/fork/fork.tif"); Stack *mask = Make_Stack(GREY, stack->width, stack->height, stack->depth); Zero_Stack(mask); Sp_Grow_Workspace *sgw = New_Sp_Grow_Workspace(); sgw->size = Stack_Voxel_Number(stack); Sp_Grow_Workspace_Set_Mask(sgw, mask->array); sgw->wf = Stack_Voxel_Weight_S; Stack_Sp_Grow_Infer_Parameter(sgw, stack); Neuron_Structure *ns = Locseg_Chain_Sp_Grow_Reconstruct(chain_array, n, stack, 1.0, sgw); Neuron_Structure *ns2 = Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0); Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, NULL); //Swc_Tree_Clean_Root(tree); Swc_Tree_Remove_Zigzag(tree); Swc_Tree_Resort_Id(tree); Write_Swc_Tree("../data/test2.swc", tree); #endif #if 0 Neuron_Structure *ns = New_Neuron_Structure(); ns->graph = New_Graph(); Graph_Add_Edge(ns->graph, 0, 1); Graph_Add_Edge(ns->graph, 0, 2); Graph_Add_Edge(ns->graph, 2, 3); Graph_Add_Edge(ns->graph, 2, 4); Graph_Add_Edge(ns->graph, 4, 5); Graph_Add_Edge(ns->graph, 5, 6); ns->conn = (Neurocomp_Conn*) malloc(sizeof(Neurocomp_Conn) * ns->graph->nedge); ns->conn[0].info[0] = 0; ns->conn[0].info[1] = 0; ns->conn[0].cost = 0.0; ns->conn[0].mode = NEUROCOMP_CONN_LINK; ns->conn[1].info[0] = 1; ns->conn[1].info[1] = 1; ns->conn[1].cost = 0.0; ns->conn[1].mode = NEUROCOMP_CONN_LINK; ns->conn[2].info[0] = 0; ns->conn[2].info[1] = 0; ns->conn[2].cost = 0.0; ns->conn[2].mode = NEUROCOMP_CONN_LINK; ns->conn[3].info[0] = 1; ns->conn[3].info[1] = 0; ns->conn[3].cost = 1.0; ns->conn[3].mode = NEUROCOMP_CONN_HL; ns->conn[4].info[0] = 0; ns->conn[4].info[1] = 1; ns->conn[4].cost = 0.0; ns->conn[4].mode = NEUROCOMP_CONN_LINK; ns->conn[5].info[0] = 1; ns->conn[5].info[1] = 1; ns->conn[5].cost = 1.0; ns->conn[5].mode = NEUROCOMP_CONN_LINK; Neuron_Structure_Merge_Locseg_Chain(ns); #endif #if 0 Neuron_Structure *ns = New_Neuron_Structure(); ns->graph = New_Graph(); ns->comp = Dir_Locseg_Chain_Nc("../data/diadem_e3", "^chain.*\\.tb", &(ns->graph->nvertex), NULL); Graph_Add_Edge(ns->graph, 0, 1); Graph_Add_Edge(ns->graph, 0, 2); Graph_Add_Edge(ns->graph, 2, 3); Graph_Add_Edge(ns->graph, 3, 4); Graph_Add_Edge(ns->graph, 4, 5); ns->conn = (Neurocomp_Conn*) malloc(sizeof(Neurocomp_Conn) * ns->graph->nedge); ns->conn[0].info[0] = 0; ns->conn[0].info[1] = 0; ns->conn[0].cost = 0.0; ns->conn[0].mode = NEUROCOMP_CONN_LINK; ns->conn[1].info[0] = 0; ns->conn[1].info[1] = 0; ns->conn[1].cost = 0.0; ns->conn[1].mode = NEUROCOMP_CONN_LINK; ns->conn[2].info[0] = 0; ns->conn[2].info[1] = 0; ns->conn[2].cost = 1.0; ns->conn[2].mode = NEUROCOMP_CONN_LINK; ns->conn[3].info[0] = 0; ns->conn[3].info[1] = 0; ns->conn[3].cost = 2.0; ns->conn[3].mode = NEUROCOMP_CONN_LINK; ns->conn[4].info[0] = 0; ns->conn[4].info[1] = 0; ns->conn[4].cost = 0.0; ns->conn[4].mode = NEUROCOMP_CONN_LINK; int i; for (i = 0; i < ns->graph->nvertex; i++) { printf("%d ", Locseg_Chain_Length(NEUROCOMP_LOCSEG_CHAIN(ns->comp+i))); } printf("\n"); Neuron_Structure_Merge_Locseg_Chain(ns); for (i = 0; i < ns->graph->nvertex; i++) { printf("%d ", Locseg_Chain_Length(NEUROCOMP_LOCSEG_CHAIN(ns->comp+i))); } printf("\n"); #endif #if 0 int n; Locseg_Chain **chain_array = Dir_Locseg_Chain_Nd("../data/diadem_e1", "^chain.*\\.tb", &n, NULL); Stack *stack = Read_Stack("../data/diadem_e1.tif"); Stack *mask = Make_Stack(GREY, stack->width, stack->height, stack->depth); Zero_Stack(mask); Sp_Grow_Workspace *sgw = New_Sp_Grow_Workspace(); sgw->size = Stack_Voxel_Number(stack); sgw->resolution[0] = 0.3296485; sgw->resolution[1] = 0.3296485; sgw->resolution[2] = 1.0; Sp_Grow_Workspace_Set_Mask(sgw, mask->array); sgw->wf = Stack_Voxel_Weight_S; Stack_Sp_Grow_Infer_Parameter(sgw, stack); Neuron_Structure *ns = Locseg_Chain_Sp_Grow_Reconstruct(chain_array, n, stack, 1.0, sgw); Neuron_Structure_Merge_Locseg_Chain(ns); int i; char filepath[100]; for (i = 0; i < ns->graph->nvertex; i++) { Locseg_Chain_Regularize(NEUROCOMP_LOCSEG_CHAIN(ns->comp+i)); if (Locseg_Chain_Is_Empty(NEUROCOMP_LOCSEG_CHAIN(ns->comp+i)) == FALSE) { sprintf(filepath, "../data/tmp/chain%d.tb", i); Write_Locseg_Chain(filepath, NEUROCOMP_LOCSEG_CHAIN(ns->comp+i)); } } #endif #if 0 Stack *stack = Read_Stack("../data/benchmark/fork2/fork2.tif"); Neuron_Structure *ns = New_Neuron_Structure(); ns->graph = New_Graph(); ns->comp = Dir_Locseg_Chain_Nc("../data/benchmark/fork2/tubes", "^chain.*\\.tb", &(ns->graph->nvertex), NULL); coordinate_3d_t roots[3]; roots[0][0] = 51; roots[0][1] = 23; roots[0][2] = 60; roots[1][0] = 51; roots[1][1] = 23; roots[1][2] = 40; roots[2][0] = 25; roots[2][1] = 76; roots[2][2] = 60; Neuron_Structure_Break_Root(ns, roots, 3); Neuron_Structure_Load_Root(ns, roots, 3); Connection_Test_Workspace *ctw = New_Connection_Test_Workspace(); ctw->dist_thre = 100.0; ctw->sp_test = FALSE; Locseg_Chain_Comp_Neurostruct_W(ns, stack, 1.0, ctw); Process_Neuron_Structure(ns); Neuron_Structure_To_Tree(ns); /* Neuron_Structure_Remove_Conn(ns, 0, 2); Neuron_Structure_Remove_Conn(ns, 2, 0); */ Neuron_Structure_Remove_Negative_Conn(ns); Neuron_Structure* ns2= NULL; ns2 = Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0); Neuron_Structure_To_Tree(ns2); Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, NULL); Swc_Tree_Resort_Id(tree); Write_Swc_Tree("../data/test3.swc", tree); #endif #if 1 Stack *stack = NULL; Locseg_Chain *chain1 = Read_Locseg_Chain("../data/benchmark/diadem/diadem_e1/chain22.tb"); Locseg_Chain *chain2 = Read_Locseg_Chain("../data/benchmark/diadem/diadem_e1/chain0.tb"); Connection_Test_Workspace *ws = New_Connection_Test_Workspace(); Connection_Test_Workspace_Read_Resolution(ws, "../data/diadem_e3.res"); Neurocomp_Conn conn; conn.mode = NEUROCOMP_CONN_HL; Locseg_Chain_Connection_Test(chain1, chain2, stack, 1.0, &conn, ws); Print_Neurocomp_Conn(&conn); #endif return 0; }
int main(int argc, char *argv[]) { static char *Spec[] = {"[-root_id <int>] [<input:string>]", "[-a <string>] [-b <string>]", "[-stitch_script] [-exclude <string>] [-tile_number <int>]", NULL}; Process_Arguments(argc, argv, Spec, 1); int *excluded = NULL; int nexc = 0; int *excluded_pair = NULL; int nexcpair = 0; if (Is_Arg_Matched("-exclude")) { String_Workspace *sw = New_String_Workspace(); FILE *fp = fopen(Get_String_Arg("-exclude"), "r"); char *line = Read_Line(fp, sw); excluded = String_To_Integer_Array(line, NULL, &nexc); line = Read_Line(fp, sw); if (line != NULL) { excluded_pair = String_To_Integer_Array(line, NULL, &nexcpair); nexcpair /= 2; } Kill_String_Workspace(sw); fclose(fp); } int n = 0; Graph *graph = Make_Graph(n + 1, n, TRUE); char filepath1[100]; char filepath2[100]; int i, j; Stack *stack1 = NULL; FILE *fp = NULL; if (Is_Arg_Matched("-stitch_script")) { Cuboid_I *boxes = read_tile_array(Get_String_Arg("-a"), &n); for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { BOOL is_excluded = FALSE; int k; for (k = 0; k < nexc; k++) { if ((i == excluded[k] - 1) || (j == excluded[k] - 1)) { is_excluded = TRUE; break; } } for (k = 0; k < nexcpair; k++) { if (((i == excluded_pair[k*2]) && (j == excluded_pair[k*2+1])) || ((j == excluded_pair[k*2]) && (i == excluded_pair[k*2+1]))) { is_excluded = TRUE; break; } } /* if ((i != 103) && (j != 103) && (i != 115) && (j != 115) && (i != 59) && (j != 59) && !(i == 116 && j == 116)) { */ if (is_excluded == FALSE) { Cuboid_I_Overlap_Volume(boxes + i, boxes + j); Cuboid_I ibox; Cuboid_I_Intersect(boxes + i, boxes + j, &ibox); int width, height, depth; Cuboid_I_Size(&ibox, &width, &height, &depth); if ((imax2(width, height) > 1024 / 3) && (imin2(width, height) > 0)) { sprintf(filepath1, "%s/stack/%03d.xml", Get_String_Arg("input"), i + 1); sprintf(filepath2, "%s/stack/%03d.xml", Get_String_Arg("input"), j + 1); if (stack1 == NULL) { stack1 = Read_Stack_U(filepath1); } Stack *stack2 = Read_Stack_U(filepath2); Stack *substack1= Crop_Stack(stack1, ibox.cb[0] - boxes[i].cb[0], ibox.cb[1] - boxes[i].cb[1], 0, width, height, stack1->depth, NULL); Stack *substack2 = Crop_Stack(stack2, ibox.cb[0] - boxes[j].cb[0], ibox.cb[1] - boxes[j].cb[1], 0, width, height, stack2->depth, NULL); Image *img1 = Proj_Stack_Zmax(substack1); Image *img2 = Proj_Stack_Zmax(substack2); double w = u16array_corrcoef((uint16_t*) img1->array, (uint16_t*) img2->array, img1->width * img1->height); Kill_Stack(stack2); Kill_Stack(substack1); Kill_Stack(substack2); Kill_Image(img1); Kill_Image(img2); printf("%d, %d : %g\n", i + 1, j + 1, w); Graph_Add_Weighted_Edge(graph, i + 1, j + 1, 1000.0 / (w + 1.0)); } } if (stack1 != NULL) { Kill_Stack(stack1); stack1 = NULL; } } } Graph_Workspace *gw = New_Graph_Workspace(); Graph_To_Mst2(graph, gw); Arrayqueue q = Graph_Traverse_B(graph, Get_Int_Arg("-root_id"), gw); Print_Arrayqueue(&q); int *grown = iarray_malloc(graph->nvertex); for (i = 0; i < graph->nvertex; i++) { grown[i] = 0; } int index = Arrayqueue_Dequeue(&q); grown[index] = 1; char stitch_p_file[5][500]; FILE *pfp[5]; for (i = 0; i < 5; i++) { sprintf(stitch_p_file[i], "%s/stitch/stitch_%d.sh", Get_String_Arg("input"), i); pfp[i] = fopen(stitch_p_file[i], "w"); } sprintf(filepath1, "%s/stitch/stitch_all.sh", Get_String_Arg("input")); fp = GUARDED_FOPEN(filepath1, "w"); fprintf(fp, "#!/bin/bash\n"); int count = 0; while ((index = Arrayqueue_Dequeue(&q)) > 0) { for (i = 0; i < graph->nedge; i++) { int index2 = -1; if (index == graph->edges[i][0]) { index2 = graph->edges[i][1]; } else if (index == graph->edges[i][1]) { index2 = graph->edges[i][0]; } if (index2 > 0) { if (grown[index2] == 1) { char cmd[500]; sprintf(filepath2, "%s/stitch/%03d_%03d_pos.txt", Get_String_Arg("input"), index2, index); sprintf(cmd, "%s/stitchstack %s/stack/%03d.xml %s/stack/%03d.xml -o %s", Get_String_Arg("-b"), Get_String_Arg("input"), index2, Get_String_Arg("input"), index, filepath2); fprintf(fp, "%s\n", cmd); count++; fprintf(pfp[count%5], "%s\n", cmd); /* if (!fexist(filepath2)) { system(cmd); } */ grown[index] = 1; break; } } } } fclose(fp); for (i = 0; i < 5; i++) { fprintf(pfp[i], "touch %s/stitch/stitch_%d_done\n", Get_String_Arg("input"), i); fclose(pfp[i]); } return 0; } sprintf(filepath1, "%s/stitch/stitch_all.sh", Get_String_Arg("input")); fp = GUARDED_FOPEN(filepath1, "r"); //#define MAX_TILE_INDEX 153 int tile_number = Get_Int_Arg("-tile_number"); int max_tile_index = tile_number + 1; char *line = NULL; String_Workspace *sw = New_String_Workspace(); int id[2]; char filepath[100]; int offset[max_tile_index][3]; int relative_offset[max_tile_index][3]; int array[max_tile_index]; for (i = 0; i < max_tile_index; i++) { array[i] = -1; offset[i][0] = 0; offset[i][1] = 0; offset[i][2] = 0; relative_offset[i][0] = 0; relative_offset[i][1] = 0; relative_offset[i][2] = 0; } while ((line = Read_Line(fp, sw)) != NULL) { char *remain = strsplit(line, ' ', 1); if (String_Ends_With(line, "stitchstack")) { String_To_Integer_Array(remain, id, &n); id[0] = id[1]; id[1] = id[3]; array[id[1]] = id[0]; sprintf(filepath, "%s/stitch/%03d_%03d_pos.txt", Get_String_Arg("input"), id[0], id[1]); if (!fexist(filepath)) { fprintf(stderr, "file %s does not exist\n", filepath); return 1; } FILE *fp2 = GUARDED_FOPEN(filepath, "r"); line = Read_Line(fp2, sw); line = Read_Line(fp2, sw); int tmpoffset[8]; String_To_Integer_Array(line, tmpoffset, &n); relative_offset[id[1]][0] = tmpoffset[2]; relative_offset[id[1]][1] = tmpoffset[3]; relative_offset[id[1]][2] = tmpoffset[4]; fclose(fp2); } } for (i = 1; i < max_tile_index; i++) { BOOL is_excluded = FALSE; int k; for (k = 0; k < nexc; k++) { if (i == excluded[k]) { is_excluded = TRUE; break; } } /*if ((i == 104) || (i == 116) || (i == 60) || (i == 152)) {*/ if (is_excluded) { printf("%d: (0, 0, 10000)\n", i); } else { int index = i; while (index >= 0) { offset[i][0] += relative_offset[index][0]; offset[i][1] += relative_offset[index][1]; offset[i][2] += relative_offset[index][2]; index = array[index]; } printf("%d: (%d, %d, %d)\n", i, offset[i][0], offset[i][1], offset[i][2]); } } fclose(fp); return 0; }