int Stack_Label_Largest_Object_W(Stack *stack, int flag, int label, Objlabel_Workspace *ow) { TZ_ASSERT(ow->chord != NULL, "NULL chord is not allowed. Wait for fix."); TZ_ASSERT(ow->conn <= 26, "Invalid neighborhood system."); STACK_OBJLABEL_OPEN_WORKSPACE(stack, ow); int small_label = label; int large_label = small_label + 1; int nvoxel = Stack_Voxel_Number(stack); int i; if (ow->init_chord == TRUE) { for (i = 0; i < nvoxel; i++) { ow->chord->array[i] = -1; } ow->init_chord = FALSE; } int obj_size = 0; int max_size = 0; ow->seed = -1; int large_seed = -1; PROGRESS_BEGIN("Labeling object"); for (i = 0; i < nvoxel; i++) { if (stack->array[i] == flag) { PROGRESS_STATUS(i / (nvoxel / 100 + 1)); obj_size = Stack_Label_Object_W(stack, i, flag, small_label, ow); if (obj_size > max_size) { /* update the largest object */ if (large_seed >= 0) { /* relabel the previous largest object */ stack_label_object_by_chord(stack, ow->chord, small_label, large_seed); } #ifdef _DEBUG_ printf("%d\n", obj_size); if (obj_size > 10000) { printf("debug here\n"); } #endif stack_label_object_by_chord(stack, ow->chord, large_label, i); large_seed = i; max_size = obj_size; } PROGRESS_REFRESH; } } PROGRESS_END("done"); ow->seed = large_seed; STACK_OBJLABEL_CLOSE_WORKSPACE(ow); return max_size; }
std::vector<const Swc_Tree_Node*> ZSwcDeepAngleMetric::extractLeafSegment( const Swc_Tree_Node *tn) { TZ_ASSERT(SwcTreeNode::isRegular(tn), "Invalid node"); std::vector<const Swc_Tree_Node*> nodeArray; nodeArray.push_back(tn); if (SwcTreeNode::isRoot(tn)) { for (int i = 0; i < m_level; ++i) { tn = SwcTreeNode::firstChild(tn); if (tn == NULL) { break; } nodeArray.push_back(tn); } } else { for (int i = 0; i < m_level; ++i) { tn = SwcTreeNode::parent(tn); if (!SwcTreeNode::isRegular(tn)) { break; } nodeArray.push_back(tn); } } return nodeArray; }
int Stack_Label_Objects_Ns(Stack *stack, IMatrix *chord, int flag, int label, int slabel, int n_nbr) { TZ_ASSERT(stack->kind == GREY, "Unsupported kind."); TZ_ASSERT(slabel <= 255, "Invalid lable"); BOOL is_owner = FALSE; STACK_OBJLABEL_CHECK_CHORD(stack, chord, is_owner); int nvoxel = Stack_Voxel_Number(stack); int nobj = 0; int i; Objlabel_Workspace ow; Default_Objlabel_Workspace(&ow); ow.conn = n_nbr; ow.chord = chord; ow.init_chord = FALSE; for (i = 0; i < nvoxel; i++) { ow.chord->array[i] = -1; } PROGRESS_BEGIN("Labeling object"); for (i = 0; i < nvoxel; i++) { if (stack->array[i] == flag) { PROGRESS_STATUS(i / (nvoxel / 100 + 1)); Stack_Label_Object_W(stack, i, flag, label, &ow); nobj++; stack->array[i] = slabel; PROGRESS_REFRESH; } } PROGRESS_END("done"); if (is_owner == TRUE) { Kill_IMatrix(chord); } return nobj; }
int ZSwcSubtreeAnalyzer::decompose(ZSwcTree *tree) const { tree->forceVirtualRoot(); tree->setLabel(0); tree->computeBackTraceLength(); ZSwcTreeNodeArray nodeArray = tree->getSwcTreeNodeArray(ZSwcTree::DEPTH_FIRST_ITERATOR); //Sort the node by weight nodeArray.sortByWeight(); int subtreeId = 0; for (size_t i = 0; i < nodeArray.size(); ++i) { Swc_Tree_Node *tn = nodeArray[i]; #ifdef _DEBUG_2 std::cout << "Weight of node " << SwcTreeNode::id(tn) << ": " << SwcTreeNode::weight(tn) << std::endl; #endif if (SwcTreeNode::weight(tn) >= m_minLength && SwcTreeNode::isRegular(tn)) { TZ_ASSERT(SwcTreeNode::label(tn) == 0, "Invalid label"); //tree->addLabelSubtree(tn, 1); ++subtreeId; #ifdef _DEBUG_2 std::cout << "Subtree root: " << SwcTreeNode::id(tn) << std::endl; #endif tree->updateIterator(SWC_TREE_ITERATOR_DEPTH_FIRST, tn, 0); for (Swc_Tree_Node *iter = tree->begin(); iter != NULL; iter = tree->next()) { if (SwcTreeNode::label(iter) == 0) { SwcTreeNode::setLabel(iter, subtreeId); #ifdef _DEBUG_2 std::cout << "Label node " << SwcTreeNode::id(iter) << " by " << subtreeId << std::endl; #endif } } //Subtract weight from upstream nodes Swc_Tree_Node *parent = SwcTreeNode::parent(tn); while (parent != NULL) { SwcTreeNode::addWeight( parent, -SwcTreeNode::weight(tn) - SwcTreeNode::length(tn)); parent = SwcTreeNode::parent(parent); } //Detach SwcTreeNode::setParent(tn, tree->root()); } } return subtreeId; }
int Stack_Label_Large_Objects_N(Stack *stack, IMatrix *chord, int flag, int label, int minsize, int n_nbr) { TZ_ASSERT(stack->kind == GREY, "GREY stack required."); Objlabel_Workspace ow; Default_Objlabel_Workspace(&ow); ow.conn = n_nbr; ow.chord = chord; ow.init_chord = TRUE; return Stack_Label_Large_Objects_W(stack, flag, label, minsize, &ow); }
const int& ZIntPoint::operator [](int index) const { TZ_ASSERT(index >= 0 && index < 3, "Invalid index"); switch (index) { case 0: return m_x; case 1: return m_y; case 2: return m_z; default: break; } std::cerr << "Index out of bound" << std::endl; return m_x; }
int Swc_Fp_Max_Id(FILE *fp) { int n = -1; int max_pid = -1; Swc_Node record; while (!feof(fp)) { if (Swc_Node_Fscan(fp, &record) == 1) { if (n < record.id) { n = record.id; } if (max_pid < record.parent_id) { max_pid = record.parent_id; } } } TZ_ASSERT(n >= max_pid, "Invalid parent id."); return n; }
Stack* Stack_Blend_Label_Field(const Stack *stack, const Stack *label, double alpha, const uint8_t *color_map, int color_number, Stack *out) { TZ_ASSERT(stack->kind == GREY, "Unsupported kind"); TZ_ASSERT(label->kind == GREY || label->kind == GREY16, "Unsupported kind"); TZ_ASSERT(Stack_Same_Size(stack, label), "Unmatched size"); if (alpha < 0.0) { TZ_WARN(ERROR_DATA_VALUE); alpha = 0.0; } if (alpha > 1.0) { TZ_WARN(ERROR_DATA_VALUE); alpha = 1.0; } if (out == NULL) { out = Make_Stack(COLOR, stack->width, stack->height, stack->depth); } TZ_ASSERT(out->kind == COLOR, "Unsupported kind"); color_t *out_array = (color_t*) out->array; if (color_map == NULL) { color_map = Jet_Colormap; color_number = Jet_Color_Number; } size_t voxel_number = Stack_Voxel_Number(stack); size_t offset; Image_Array ima; ima.array = label->array; for (offset = 0; offset < voxel_number; ++offset) { int label_value; if (label->kind == GREY) { label_value = ima.array8[offset]; } else { label_value = ima.array16[offset]; } int gray_value = stack->array[offset]; if (label_value > 0) { label_value = (label_value - 1) % color_number; int k; for (k = 0; k < 3; ++k) { int value = iround((1.0 - alpha) * gray_value + alpha * color_map[label_value * 3 + k]); if (value < 0) { value = 0; } else if (value > 255) { value = 255; } out_array[offset][k] = value; } } else { int k; for (k = 0; k < 3; ++k) { out_array[offset][k] = gray_value; } } #ifdef _DEBUG_2 if (out_array[offset][0] == 0 && out_array[offset][1] == 0 && out_array[offset][2] == 0) { printf("debug here\n"); } #endif } return out; }
Tiff_IFD *Make_IFD_For_Lsm_Image(Tiff_Image *image, int compression, Tiff_IFD *templat, int depth) { TZ_ASSERT((image->number_channels >= 1) && (image->number_channels <= MAX_CHANNEL_NUMBER), "Invalid channel number"); unsigned char *encode; encode = get_code_vector(1.1*image->width*image->height*sizeof(int) + 4096, "Make_IFD_For_Lsm_Image"); Tiff_IFD *ifd = NULL; if (compression == 1) { ifd = Create_Tiff_IFD(12); } else { ifd = Create_Tiff_IFD(11); } uint32_t newsubfile_type = 0; /* not a thumbnail*/ Set_Tiff_Tag(ifd, TIFF_NEW_SUB_FILE_TYPE, TIFF_LONG, 1, &(newsubfile_type)); uint32_t image_width = image->width; Set_Tiff_Tag(ifd, TIFF_IMAGE_WIDTH, TIFF_LONG, 1, &(image_width)); uint32_t image_length = image->height; Set_Tiff_Tag(ifd, TIFF_IMAGE_LENGTH, TIFF_LONG, 1, &(image_length)); uint16_t bits_per_sample[MAX_CHANNEL_NUMBER]; int bits_per_sample_count = image->number_channels; int i; //for (i = 0; i < 3; i++) { for (i = 0; i < image->number_channels; i++) { bits_per_sample[i] = image->channels[0]->bytes_per_pixel * 8; } Set_Tiff_Tag(ifd, TIFF_BITS_PER_SAMPLE, TIFF_SHORT, bits_per_sample_count, bits_per_sample); uint16_t tif_compression; if (compression == 0) { tif_compression = TIFF_VALUE_UNCOMPRESSED; /* no compression */ } else { tif_compression = TIFF_VALUE_LZW; /* LZW */ } Set_Tiff_Tag(ifd, TIFF_COMPRESSION, TIFF_SHORT, 1, &tif_compression); uint16_t photometric_interpretion; if (image->number_channels > 1) { photometric_interpretion = TIFF_VALUE_RGB; /* TIF_RGB24 */ } else { if (image->channels[0]->interpretation == CHAN_MAPPED) { photometric_interpretion = TIFF_VALUE_RGB_PALETTE; /* one channel with color map */ } else { photometric_interpretion = TIFF_VALUE_BLACK_IS_ZERO; /* one channel without color map*/ } } Set_Tiff_Tag(ifd, TIFF_PHOTOMETRIC_INTERPRETATION, TIFF_SHORT, 1, &photometric_interpretion); uint32_t strip_offsets[MAX_CHANNEL_NUMBER]; /* determine later */ uint32_t strip_byte_counts[MAX_CHANNEL_NUMBER]; /* determine later */ int data_size = 0; int remain; for (i = 0; i < image->number_channels; i++) { data_size += tiff_channel_psize(image->channels[i]); } Allocate_Tiff_IFD_Data(ifd,data_size); unsigned char *data, *stream; redo: data = stream = Tiff_IFD_Data(ifd); remain = data_size; //printf("compression = %d\n",compression); for (i = 0; i < image->number_channels; i++) { int scale = image->channels[i]->scale; int bytes = image->channels[i]->bytes_per_pixel; int a = image->width*image->height; int x, y; int byte_count; unsigned char *source; source = (unsigned char *) (image->channels[i]->plane); if (compression) // Difference data if required { if (bytes == 1) { unsigned char last, next; unsigned char *base = source; signed char *diff = (signed char *) encode; for (y = 0; y < image->height; y++) { last = *base; *((unsigned char *) diff) = last; base += 1; diff += 1; for (x = 1; x < image->width; x++) { next = *base++; *diff++ = next - last; last = next; } } } else if (bytes == 2) { unsigned short last, next; unsigned short *base = (unsigned short *) source; signed short *diff = (signed short *) encode; for (y = 0; y < image->height; y++) { last = *base; *((unsigned short *) diff) = last; base += 1; diff += 1; for (x = 1; x < image->width; x++) { next = *base++; *diff++ = next - last; last = next; } } } else // bytes == 4 { unsigned int last, next; unsigned int *base = (unsigned int *) source; signed int *diff = (signed int *) encode; for (y = 0; y < image->height; y++) { last = *base; *((unsigned int *) diff) = last; base += 1; diff += 1; for (x = 1; x < image->width; x++) { next = *base++; *diff++ = next - last; last = next; } } } source = encode; #ifdef DEBUG_ENCODE printf("\nDifference predicted:\n"); Print_Plane(image->width,image->height,bytes,source,0,1); #endif } // Endian flip multi-byte data if required if (bytes == 2) { if (scale < 16 && ! Native_Endian()) { unsigned char *w; if (compression || scale%8 != 0) w = encode; else w = stream; if (w == source) { unsigned char t; for (x = 0; x < a; x++) { t = w[0]; w[0] = w[1]; w[1] = t; w += 2; } } else { unsigned char *v = source; for (x = 0; x < a; x++) { w[0] = v[1]; w[1] = v[0]; w += 2; v += 2; } } source = w - bytes*a; #ifdef DEBUG_ENCODE printf("\nEndian flipped:\n"); Print_Plane(image->width,image->height,bytes,source,1,0); #endif } } else if (bytes == 4) { if (scale < 32 && ! Native_Endian()) { unsigned char *w; if (compression || scale%8 != 0) w = encode; else w = stream; if (w == source) { unsigned char t; for (x = 0; x < a; x++) { t = w[0]; w[0] = w[3]; w[3] = t; t = w[1]; w[1] = w[2]; w[2] = t; w += 4; } } else { unsigned char *v = source; for (x = 0; x < a; x++) { w[0] = v[3]; w[1] = v[2]; w[2] = v[1]; w[3] = v[0]; w += 4; v += 4; } } source = w - bytes*a; #ifdef DEBUG_ENCODE printf("\nEndian flipped:\n"); Print_Plane(image->width,image->height,bytes,source,1,0); #endif } } // In-place bit-packing if non-byte boundary sample size if (scale % 8 != 0 || scale == 24) { int bp8 = (scale & 0x7); int bp3 = (scale >> 3); int pos; unsigned char *src; unsigned char *trg; unsigned char *org; src = source; if (compression) trg = org = encode; else trg = org = stream; pos = 0; if (16 < scale && scale <= 24) for (x = 0; x < a; x++) { src += 1; PACK_BITS(src,bp8,bp3,trg,pos) } else for (x = 0; x < a; x++) PACK_BITS(src,bp8,bp3,trg,pos) if (pos != 0) trg++; byte_count = trg - org; source = org; #ifdef DEBUG_ENCODE printf("\nBit packed:\n"); Print_Plane(byte_count,1,1,source,1,0); #endif }
int Stack_Label_Objects_N(Stack *stack, IMatrix *chord, int flag, int label, int n_nbr) { TZ_ASSERT(label > flag, "Invalid label"); int start_label = label; BOOL is_owner = FALSE; STACK_OBJLABEL_CHECK_CHORD(stack, chord, is_owner); int nvoxel = Stack_Voxel_Number(stack); int nobj = 0; int i; Objlabel_Workspace ow; Default_Objlabel_Workspace(&ow); ow.conn = n_nbr; ow.chord = chord; ow.init_chord = FALSE; for (i = 0; i < nvoxel; i++) { ow.chord->array[i] = -1; } PROGRESS_BEGIN("Labeling object"); uint16_t *array16 = (uint16_t*) stack->array; uint8_t *array8 = (uint8_t*) stack->array; for (i = 0; i < nvoxel; i++) { BOOL is_flag = FALSE; if (stack->kind == GREY) { is_flag = (array8[i] == flag); } else { is_flag = (array16[i] == flag); } if (is_flag == TRUE) { if (label > 255) { if (stack->kind == GREY) { Translate_Stack(stack, GREY16, 1); array16 = (uint16_t*) stack->array; } } PROGRESS_STATUS(i / (nvoxel / 100 + 1)); Stack_Label_Object_W(stack, i, flag, label, &ow); label++; if (label > 65535) { TZ_WARN(ERROR_DATA_VALUE); label = start_label; } nobj++; PROGRESS_REFRESH; } } PROGRESS_END("done"); if (is_owner == TRUE) { Kill_IMatrix(chord); } return nobj; }
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; }
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; }