Beispiel #1
0
ZVoxelArray ZSpGrowParser::extractPath(ssize_t index)
{
  ZVoxelArray path;
  int width = m_workspace->width;
  int height = m_workspace->height;

  if (m_workspace != NULL) {
    while (index >= 0) {
      ZVoxel voxel;
      voxel.setFromIndex(index, width, height);
      path.append(voxel);

      if (m_pathMask != NULL) {
        if (m_pathMask->array[index] == 1) {
          break;
        }
      }

      assert(index != m_workspace->path[index]);
      index = m_workspace->path[index];
    }
  }

  return path;
}
Beispiel #2
0
Swc_Tree* ZNeuronTracer::trace(double x1, double y1, double z1, double r1,
                               double x2, double y2, double z2, double r2)
{
  if (x1 < 0 || y1 < 0 || z1 < 0 || x1 >= C_Stack::width(m_stack) ||
      y1 >= C_Stack::height(m_stack) || z1 >= C_Stack::depth(m_stack)) {
    return NULL;
  }

  if (ZPoint(x1, y1, z1).distanceTo(x2, y2, z2) > MAX_P2P_TRACE_DISTANCE) {
    return NULL;
  }

  /*
  int start[3];
  int end[3];

  start[0] = iround(x1);
  start[1] = iround(y1);
  start[2] = iround(z1);
  end[0] = iround(x2);
  end[1] = iround(y2);
  end[2] = iround(z2);
  */

  ZStackGraph stackGraph;
  stackGraph.setResolution(m_resolution);
  if (m_backgroundType == NeuTube::IMAGE_BACKGROUND_BRIGHT) {
    stackGraph.setWeightFunction(Stack_Voxel_Weight);
  } else {
    stackGraph.setWeightFunction(Stack_Voxel_Weight_S);
  }

  stackGraph.inferWeightParameter(m_stack);

  int startIndex = C_Stack::indexFromCoord(x1, y1, z1, C_Stack::width(m_stack),
                                           C_Stack::height(m_stack),
                                           C_Stack::depth(m_stack));
  int endIndex = C_Stack::indexFromCoord(x2, y2, z2, C_Stack::width(m_stack),
                                         C_Stack::height(m_stack),
                                         C_Stack::depth(m_stack));

  std::vector<int> path =
      stackGraph.computeShortestPath(m_stack, startIndex, endIndex);

  ZVoxelArray voxelArray;
  for (size_t i = path.size(); i > 0; --i) {
    int x, y, z;
    C_Stack::indexToCoord(path[i - 1], C_Stack::width(m_stack),
                          C_Stack::height(m_stack), &x, &y, &z);
    voxelArray.append(ZVoxel(x, y, z));
  }

  double length = voxelArray.getCurveLength();
  double dist = 0.0;

  for (size_t i = 0; i < path.size(); ++i) {
    double ratio = dist / length;
    double r = r1 * ratio + r2 * (1 - ratio);
    voxelArray.setValue(i, r);
    if (i < path.size() - 1) {
      dist += voxelArray[i].distanceTo(voxelArray[i+1]);
    }
  }

  return voxelArray.toSwcTree();
}
Beispiel #3
0
vector<ZVoxelArray> ZSpGrowParser::extractAllPath(double lengthThreshold,
                                                  Stack *ballStack)
{
  bool isPathAvailable = true;

  const double maskExpansionRadius = 2.0;
  const double skeletonRadius = 3.0;

  //Calibrate
  lengthThreshold -= maskExpansionRadius;

  vector<ZVoxelArray> pathArray;

  //While any long path is available
  while (isPathAvailable) {
    //Extract the longest path
    double length = 0.0;
    ZVoxelArray path = extractLongestPath(&length);

    cout << "Path length: " << length << endl;
    cout << "Path size: " << path.size() << endl;
    if (path.size() == 1) {
      cout << "Debug here." << endl;
    }


    if (length < lengthThreshold) {
      isPathAvailable = false;
    } else {
      pathArray.push_back(path);
      //Update checkedMask
      if (m_checkedMask == NULL) {
        m_checkedMask = Make_Stack(GREY, m_workspace->width,
                                   m_workspace->height, m_workspace->depth);
        Zero_Stack(m_checkedMask);
      }
      if (m_pathMask == NULL) {
        m_pathMask = Make_Stack(GREY, m_workspace->width,
                                m_workspace->height, m_workspace->depth);
        Zero_Stack(m_pathMask);
      }

      if (ballStack != NULL) { //Extract distance field values
        path.sample(ballStack, DistanceWeight);
        path.addValue(1.0);
        path.minimizeValue(skeletonRadius);
      } else {
        path.addValue(skeletonRadius);
      }

      path.labelStackWithBall(m_pathMask, 1); //Label skeletons with a certain width

      if (ballStack != NULL) {
        path.sample(ballStack, DistanceWeight);
        path.addValue(maskExpansionRadius);
      }
      path.labelStackWithBall(m_checkedMask, 1); //Label mask
    }
  }

  return pathArray;
}
Beispiel #4
0
Swc_Tree* ZNeuronTracer::trace(double x1, double y1, double z1, double r1,
                               double x2, double y2, double z2, double r2)
{
  setTraceScoreThreshold(TRACING_INTERACTIVE);

  ZIntPoint stackOffset = getStack()->getOffset();

  ZPoint targetPos(x2, y2, z2);

  x1 = iround(x1);
  y1 = iround(y1);
  z1 = iround(z1);
  x2 = iround(x2);
  y2 = iround(y2);
  z2 = iround(z2);

  x1 -= stackOffset.getX();
  y1 -= stackOffset.getY();
  z1 -= stackOffset.getZ();

  x2 -= stackOffset.getX();
  y2 -= stackOffset.getY();
  z2 -= stackOffset.getZ();

  if (x1 < 0 || y1 < 0 || z1 < 0 || x1 >= getStack()->width() ||
      y1 >= getStack()->height() || z1 >= getStack()->depth()) {
    return NULL;
  }

  ZStackGraph stackGraph;
  if (m_resolution[2] / m_resolution[0] > 3.0) {
    stackGraph.setZMargin(2);
  }
  stackGraph.updateRange(
        x1, y1, z1, x2, y2, z2,
        getStack()->width(), getStack()->height(), getStack()->depth());
  if (stackGraph.getRoiVolume() > MAX_P2P_TRACE_VOLUME) {
    return NULL;
  }

  stackGraph.setResolution(m_resolution);

  if (m_vertexOption == ZStackGraph::VO_SURFACE) {
    stackGraph.setWeightFunction(Stack_Voxel_Weight_I);
  } else {
    if (m_usingEdgePath) {
      stackGraph.setWeightFunction(Stack_Voxel_Weight_S);
    } else {
      if (m_backgroundType == NeuTube::IMAGE_BACKGROUND_BRIGHT) {
        stackGraph.setWeightFunction(Stack_Voxel_Weight_Sr);
      } else {
        stackGraph.setWeightFunction(Stack_Voxel_Weight_S);
      }
    }
  }

  ZIntCuboid box = stackGraph.getRange();
//  if (m_usingEdgePath) {
//    box.setFirstCorner(imin2(x1, x2), imin2(y1, y2), imin2(z1, z2));
//    box.setLastCorner(imax2(x1, x2), imax2(y1, y2), imax2(z1, z2));
//  }

  Stack *partial = C_Stack::crop(
        getIntensityData(), box.getFirstCorner().getX(), box.getFirstCorner().getY(),
        box.getFirstCorner().getZ(), box.getWidth(), box.getHeight(),
        box.getDepth(), NULL);

  /*
  if (m_bcAdjust) {
    Stack_Scale(partial, 0, m_greyFactor, m_greyOffset);
  }
  */

  if (m_usingEdgePath) {
    Stack *partialEdge = C_Stack::computeGradient(partial);
    C_Stack::kill(partial);
    partial = partialEdge;

#ifdef _DEBUG_2
    C_Stack::write(GET_TEST_DATA_DIR + "/test.tif", partial);
#endif
  }

  stackGraph.inferWeightParameter(partial);

  ZVoxelArray voxelArray;
  std::vector<int> path;

  if (m_usingEdgePath) {
    int x0 = box.getFirstCorner().getX();
    int y0 = box.getFirstCorner().getY();
    int z0 = box.getFirstCorner().getZ();

    int startIndex = C_Stack::indexFromCoord(
          x1 - x0, y1 - y0 , z1 - z0, C_Stack::width(partial),
          C_Stack::height(partial),
          C_Stack::depth(partial));
    int endIndex = C_Stack::indexFromCoord(
          x2 - x0, y2 - y0, z2 - z0, C_Stack::width(partial),
          C_Stack::height(partial),
          C_Stack::depth(partial));

    stackGraph.setRange(0, 0, 0, C_Stack::width(partial) - 1,
                        C_Stack::height(partial) - 1,
                        C_Stack::depth(partial) - 1);
    path = stackGraph.computeShortestPath(
          partial, startIndex, endIndex, m_vertexOption);


    for (size_t i = path.size(); i > 0; --i) {
      int x, y, z;
      C_Stack::indexToCoord(path[i - 1], C_Stack::width(partial),
          C_Stack::height(partial), &x, &y, &z);
      voxelArray.append(ZVoxel(x + x0, y + y0, z + z0));
    }

  } else {
    int width = getStack()->width();
    int height = getStack()->height();
    int depth = getStack()->depth();

    int startIndex = C_Stack::indexFromCoord(
          x1, y1, z1, width, height, depth);
    int endIndex = C_Stack::indexFromCoord(
          x2, y2, z2, width, height, depth);

    path = stackGraph.computeShortestPath(
          getIntensityData(), startIndex, endIndex, m_vertexOption);
//    C_Stack::kill(stackField);

    for (size_t i = path.size(); i > 0; --i) {
      int x, y, z;
      C_Stack::indexToCoord(path[i - 1], width, height, &x, &y, &z);
      voxelArray.append(ZVoxel(x, y, z));
    }
  }

  C_Stack::kill(partial);

  double length = voxelArray.getCurveLength();
  double dist = 0.0;

  const std::vector<ZVoxel> &voxelData = voxelArray.getInternalData();
  for (size_t i = 0; i < path.size(); ++i) {
    double ratio = dist / length;
    double r = r1 * ratio + r2 * (1 - ratio);
    voxelArray.setValue(i, r);
    if (i < path.size() - 1) {
      dist += voxelData[i].distanceTo(voxelData[i+1]);
    }
  }

  Swc_Tree *tree = voxelArray.toSwcTree();
  if (tree != NULL) {
    Swc_Tree_Translate(
          tree, stackOffset.getX(), stackOffset.getY(), stackOffset.getZ());
    ZSwcSignalFitter fitter;
    fitter.setBackground(m_backgroundType);
    fitter.setFixingTerminal(true);
    fitter.fitSignal(tree, getStack(), getSignalChannel());

    Swc_Tree_Node *leaf = tree->root;
    while (SwcTreeNode::firstChild(leaf) != NULL) {
      leaf = SwcTreeNode::firstChild(leaf);
    }
    SwcTreeNode::setPos(leaf, targetPos);
  }

  return tree;
}