Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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);  
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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
        }
Esempio n. 10
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
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;
}