int main(int argc, char **argv) {
  if(argc!= 5){
    printf("Usage: diademAddScaleFromImage cloud.cl image cube_to_translate out.cl\n");
    exit(0);
  }

  Cloud<Point3D>*  orig = new Cloud<Point3D>(argv[1]);
  Image<float>*  scales = new Image<float>  (argv[2]);
  CubeF*             cb = new CubeF        (argv[3]);
  Cloud<Point3Dw>* dest = new Cloud<Point3Dw>();

  int x, y, z, nP;
  for(nP = 0; nP < orig->points.size(); nP++){
    cb->micrometersToIndexes3
      (orig->points[nP]->coords[0], orig->points[nP]->coords[1],  orig->points[nP]->coords[2],
       x, y, z);
    dest->points.push_back
      (new Point3Dw(orig->points[nP]->coords[0],
                    orig->points[nP]->coords[1],
                    orig->points[nP]->coords[2],
                    scales->at(x,y)));

  }
  dest->saveToFile(argv[4]);

}
示例#2
0
int main(int argc, char **argv) {

  if(argc!=3){
    printf("graphFindLeaves graph.gr leaves.cl\n");
    exit(0);
  }

  Graph<Point3D, EdgeW<Point3D> >* gr =
    new Graph<Point3D, EdgeW<Point3D> >(argv[1]);

  Cloud<Point3D>* cl = new Cloud<Point3D>();

  vector<int> pointsToAdd = gr->findLeaves();

  for(int i = 0; i < pointsToAdd.size(); i++){
      cl->addPoint(gr->cloud->points[pointsToAdd[i]]->coords[0],
                   gr->cloud->points[pointsToAdd[i]]->coords[1],
                   gr->cloud->points[pointsToAdd[i]]->coords[2]);
  }

  //Leaves are green
  cl->v_r = 0;
  cl->v_g = 1;
  cl->v_b = 0;
  cl->v_radius = 0.8;

  cl->saveToFile(argv[2]);

}
int main(int argc, char **argv) {

  struct arguments arguments;
  /* Default values. */
  arguments.verbose = 0;
  arguments.outputFile = "out.cl";
  arguments.cloudName = "";
  arguments.volumeX = "";
  arguments.volumeY = "";
  arguments.volumeZ = "";

  argp_parse (&argp, argc, argv, 0, 0, &arguments);

  printf ("Cloud = %s\n OutputFile = %s\n",
          arguments.cloudName.c_str(), arguments.outputFile.c_str());

  //Code starts here
  Cloud<Point3D>* cl = new Cloud<Point3D>(arguments.cloudName);
  Cloud<Point3Do>* out = new Cloud<Point3Do>(arguments.outputFile);
  Cube< float, double>* vx = new Cube<float, double>(arguments.volumeX);
  Cube< float, double>* vy = new Cube<float, double>(arguments.volumeY);
  Cube< float, double>* vz = new Cube<float, double>(arguments.volumeZ);


  vector< int > idx(3);
  vector< float > micr(3);
  float theta, phi, r;

  for(int i = 0; i < cl->points.size(); i++){
    micr[0] = cl->points[i]->coords[0];
    micr[1] = cl->points[i]->coords[1];
    micr[2] = cl->points[i]->coords[2];
    vx->micrometersToIndexes(micr, idx);

    r = sqrt( vx->at(idx[0],idx[1],idx[2])*vx->at(idx[0],idx[1],idx[2]) +
              vy->at(idx[0],idx[1],idx[2])*vy->at(idx[0],idx[1],idx[2]) +
              vz->at(idx[0],idx[1],idx[2])*vz->at(idx[0],idx[1],idx[2]) );

    theta = atan2(vy->at(idx[0],idx[1],idx[2]), vx->at(idx[0],idx[1],idx[2]));
    phi   = acos(vz->at(idx[0],idx[1],idx[2])/r);

    Point3Do* pt = new Point3Do(micr[0], micr[1], micr[2],
                                theta, phi);

    out->points.push_back(pt);
  }
  out->saveToFile(arguments.outputFile);
}
示例#4
0
int main(int argc, char **argv) {

  Cloud<Point3D>* cd = new Cloud<Point3D>();
  cd->v_saveVisibleAttributes = true;
  cd->loadFromFile("data/cloud.cl");
  printf("Cloud loaded\n");
  cd->saveToFile("data/cloud_copy.cl");
  printf("Check manually that the files data/cloud.cl and data/cloud_copy.cl represent the same cloud\n");

  Cloud<Point2D>* cd2 = new Cloud<Point2D>();
  cd2->v_saveVisibleAttributes = true;
  cd2->loadFromFile("data/cloud2D.cl");
  printf("Cloud2D loaded\n");
  cd2->saveToFile("data/cloud2D_copy.cl");
  printf("Check manually that the files data/cloud2D.cl and data/cloud2D_copy.cl represent the same cloud\n");

}
示例#5
0
int main(int argc, char **argv) {

  struct arguments arguments;
  /* Default values. */
  arguments.flag_min = 0;
  arguments.verbose = 0;
  arguments.threshold = 0;
  arguments.windowxy = 8;
  arguments.windowz = 10;
  arguments.flag_layer = 0;
  arguments.flag_log = 0;
  arguments.saveAsCloud = true;
  arguments.somaDefined = false;

  argp_parse (&argp, argc, argv, 0, 0, &arguments);

  printf ("Volume = %s\nFile = %s\n"
          "bool_min = %s\n"
          "threshold = %f \n"
          "saveAsCloud = %i \n",
          arguments.args[0], arguments.args[1],
          arguments.flag_min ? "yes" : "no",
          arguments.threshold,
          arguments.saveAsCloud
          );

  if(arguments.flag_log && arguments.flag_layer){
    printf("Not yet implemented logarithmic decimation layer by layer\n");
  }

  Cube_P* cube = CubeFactory::load(arguments.args[0]);

  if(arguments.flag_log){
    cube->decimate_log(arguments.threshold, arguments.windowxy, arguments.windowz,
                       arguments.args[1], false);
  }

  if(!(arguments.flag_log || arguments.flag_layer)){
    cube->decimate(arguments.threshold, arguments.windowxy, arguments.windowz,
                       arguments.args[1], false);
  }

  if(arguments.flag_layer){
    // for(int z = 0; z < 
    // cube->decimate
    printf("Lazy enough for not doing this and I do not see the point now\n");
  }


  if(arguments.saveAsCloud){
    Cloud<Point3D >* cd = new Cloud<Point3D>();
    vector< vector< double > > idxs = loadMatrix(arguments.args[1]);
    // vector< int > indexes(3);
    // vector< float > micrometers(3);
    //The first point will be the soma
    if(arguments.somaDefined){
      cd->points.push_back
        (new Point3D(arguments.somaX, arguments.somaY, arguments.somaZ));
    }
    for(int i = 0; i < idxs.size(); i++){

      Point3D* pt = new Point3D( idxs[i][0],
                                 idxs[i][1],
                                 idxs[i][2]);

      cd->points.push_back( pt );
    }
    // cd->v_radius = cube->voxelWidth;
    cd->v_radius = 0.5;
    cd->saveToFile(arguments.args[1]);
  }

}
int main(int argc, char **argv) {


  struct arguments arguments;
  /* Default values. */
  arguments.flag_min = 0;
  arguments.verbose = 0;
  arguments.threshold = 0.02;
  arguments.windowxy = 8;
  arguments.windowz = 10;
  arguments.flag_layer = 0;
  arguments.flag_log = 0;
  arguments.saveAsCloud = true;
  arguments.somaDefined = false;

  argp_parse (&argp, argc, argv, 0, 0, &arguments);

  string directory(arguments.args[0]);
  float threshold =   arguments.threshold;

  printf ("Volume = %s\nFile = %s\n"
          "bool_min = %s\n"
          "threshold = %f \n"
          "saveAsCloud = %i \n",
          arguments.args[0], arguments.args[0],
          arguments.flag_min ? "yes" : "no",
          arguments.threshold,
          arguments.saveAsCloud
          );

  // Cube<float, double>* c1 = new Cube<float, double>
    // (directory + "/1/bf_2_3162.nfo");
  // Cube<float, double>* c2 = new Cube<float, double>
    // (directory + "/2/bf_2_3162.nfo");
  // Cube<float, double>* c4 = new Cube<float, double>
    // (directory + "/4/bf_2_3162.nfo");
  // Cube<float, double>* c8 = new Cube<float, double>
    // (directory + "/8/bf_2_3162.nfo");

  // vector<Cube<float, double>*> thetas;
  // vector<Cube<float, double>*> phis;
  // thetas.push_back(new Cube<float, double>
                   // (directory + "/1/aguet_2.00_2.00_theta.nfo"));
  // thetas.push_back(new Cube<float, double>
                   // (directory + "/2/aguet_2.00_2.00_theta.nfo"));
  // thetas.push_back(new Cube<float, double>
                   // (directory + "/4/aguet_2.00_2.00_theta.nfo"));
  // thetas.push_back(new Cube<float, double>
                   // (directory + "/8/aguet_2.00_2.00_theta.nfo"));
  // phis.push_back(new Cube<float, double>
                   // (directory + "/1/aguet_2.00_2.00_phi.nfo"));
  // phis.push_back(new Cube<float, double>
                   // (directory + "/2/aguet_2.00_2.00_phi.nfo"));
  // phis.push_back(new Cube<float, double>
                   // (directory + "/4/aguet_2.00_2.00_phi.nfo"));
  // phis.push_back(new Cube<float, double>
                   // (directory + "/8/aguet_2.00_2.00_phi.nfo"));



  Cube<float, double>* c1 = new Cube<float, double>
    (directory + "/C14_4_1-d.nfo");
  Cube<float, double>* c2 = new Cube<float, double>
    (directory + "/C14_4_2-d.nfo");
    // (directory + "/2/bf_2_3162.nfo");
  Cube<float, double>* c4 = new Cube<float, double>
    (directory + "/C14_4_4-d.nfo");
    // (directory + "/4/bf_2_3162.nfo");
  Cube<float, double>* c8 = new Cube<float, double>
    (directory + "/C14_4_4-d.nfo");
    // (directory + "/8/bf_2_3162.nfo");

  vector<Cube<float, double>*> thetas;
  vector<Cube<float, double>*> phis;
  thetas.push_back(new Cube<float, double>
                   (directory + "/C14_4_1-d_theta.nfo"));
                   // (directory + "/1/aguet_2.00_2.00_theta.nfo"));
  thetas.push_back(new Cube<float, double>
                   (directory + "/C14_4_2-d_theta.nfo"));
                   // (directory + "/2/aguet_2.00_2.00_theta.nfo"));
  thetas.push_back(new Cube<float, double>
                   (directory + "/C14_4_4-d_theta.nfo"));
                   // (directory + "/4/aguet_2.00_2.00_theta.nfo"));
  thetas.push_back(new Cube<float, double>
                   (directory + "/C14_4_4-d_theta.nfo"));
                   // (directory + "/8/aguet_2.00_2.00_theta.nfo"));
  phis.push_back(new Cube<float, double>
                   (directory + "/C14_4_1-d_phi.nfo"));
                   // (directory + "/1/aguet_2.00_2.00_phi.nfo"));
  phis.push_back(new Cube<float, double>
                   (directory + "/C14_4_2-d_phi.nfo"));
                   // (directory + "/2/aguet_2.00_2.00_phi.nfo"));
  phis.push_back(new Cube<float, double>
                   (directory + "/C14_4_4-d_phi.nfo"));
                   // (directory + "/4/aguet_2.00_2.00_phi.nfo"));
  phis.push_back(new Cube<float, double>
                   (directory + "/C14_4_4-d_phi.nfo"));
                   // (directory + "/8/aguet_2.00_2.00_phi.nfo"));



  vector< vector < float > > toReturn;
  vector< int > toReturnScales;
  vector< float > toReturnThetas;
  vector< float > toReturnPhis;
  int cubeCardinality = c1->cubeWidth*c1->cubeHeight*c1->cubeDepth;
  bool* visitedPoints = (bool*)malloc(cubeCardinality*sizeof(bool));
  for(int i = 0; i < cubeCardinality; i++)
    visitedPoints[i] = false;

  multimap< float, int > valueToCoordsC1;
  multimap< float, int > valueToCoordsC2;
  multimap< float, int > valueToCoordsC4;
  multimap< float, int > valueToCoordsC8;

  //Computes the min and the max
  float min_c1, max_c1, min_c2, max_c2,min_c4, max_c4,min_c8, max_c8, min_c, max_c;
  c1->min_max(&min_c1, &max_c1);
  c2->min_max(&min_c2, &max_c2);
  c4->min_max(&min_c4, &max_c4);
  c8->min_max(&min_c8, &max_c8);
  min_c = min(min_c1, min_c2);
  min_c = min(min_c , min_c4);
  min_c = min(min_c , min_c8);
  max_c = max(max_c1, max_c2);
  max_c = max(max_c , max_c4);
  max_c = max(max_c , max_c8);

  double step_size = (max_c - min_c) / 5;
  double current_threshold = max_c - step_size;

  int position = 0;
  int positionInC1 = 0;
  int ix, iy, iz;
  float mx,my,mz;

  printf("Cube<T,U>::decimate Creating the map[\n");
  // Loop for the decimation
  while(
        (current_threshold > min_c) &&
        (current_threshold > threshold - step_size)
        ){

    if( fabs(threshold - current_threshold) < step_size)
      current_threshold = threshold;

    valueToCoordsC1.erase(valueToCoordsC1.begin(), valueToCoordsC1.end() );
    valueToCoordsC2.erase(valueToCoordsC2.begin(), valueToCoordsC2.end() );
    valueToCoordsC4.erase(valueToCoordsC4.begin(), valueToCoordsC4.end() );
    valueToCoordsC8.erase(valueToCoordsC8.begin(), valueToCoordsC8.end() );

    // Find the non-visited points above the threshold for C1
    for(int z = 0; z < c1->cubeDepth; z++){
      for(int y = 0; y < c1->cubeHeight; y++){
        for(int x = 0; x < c1->cubeWidth; x++)
          {
            position = x + y*c1->cubeWidth + z*c1->cubeWidth*c1->cubeHeight;
            if( (c1->at(x,y,z) > current_threshold) &&
                (visitedPoints[position] == false))
              {
                valueToCoordsC1.insert(pair<float, int >(c1->at(x,y,z), position));
              }
          }
      }
      printf("Threshold: %f, Layer %02i and %07i points\r",
             current_threshold, z, (int)valueToCoordsC1.size()); fflush(stdout);
    }//z of c1
    printf("\n");
    // Find the non-visited points above the threshold for C2
    for(int z = 0; z < c2->cubeDepth; z++){
      for(int y = 0; y < c2->cubeHeight; y++){
        for(int x = 0; x < c2->cubeWidth; x++)
          {
            if(c2->at(x,y,z) > current_threshold){
                c2->indexesToMicrometers3(x,y,z,mx, my,mz);
                c1->micrometersToIndexes3(mx,my,mz,ix,iy,iz);
                position = ix + iy*c1->cubeWidth + iz*c1->cubeWidth*c1->cubeHeight;
                if(visitedPoints[position] == false)
                  {
                    valueToCoordsC2.insert(pair<float, int >(c2->at(x,y,z), position));
                  }
              }
          }
      }
      printf("Threshold: %f, Layer %02i and %07i points\r",
             current_threshold, z, (int)valueToCoordsC2.size()); fflush(stdout);
    }//z of c2
    printf("\n");
    // Find the non-visited points above the threshold for C2
    for(int z = 0; z < c4->cubeDepth; z++){
      for(int y = 0; y < c4->cubeHeight; y++){
        for(int x = 0; x < c4->cubeWidth; x++)
          {
            if(c4->at(x,y,z) > current_threshold){
                c4->indexesToMicrometers3(x,y,z,mx, my,mz);
                c1->micrometersToIndexes3(mx,my,mz,ix,iy,iz);
                position = ix + iy*c1->cubeWidth + iz*c1->cubeWidth*c1->cubeHeight;
                if(visitedPoints[position] == false)
                  {
                    valueToCoordsC4.insert(pair<float, int >(c4->at(x,y,z), position));
                  }
              }
          }
      }
      printf("Threshold: %f, Layer %02i and %07i points\r",
             current_threshold, z, (int)valueToCoordsC4.size()); fflush(stdout);
    }//z of c4
    printf("\n");
    // Find the non-visited points above the threshold for C2
    for(int z = 0; z < c8->cubeDepth; z++){
      for(int y = 0; y < c8->cubeHeight; y++){
        for(int x = 0; x < c8->cubeWidth; x++)
          {
            if(c8->at(x,y,z) > current_threshold){
                c8->indexesToMicrometers3(x,y,z,mx, my,mz);
                c1->micrometersToIndexes3(mx,my,mz,ix,iy,iz);
                position = ix + iy*c1->cubeWidth + iz*c1->cubeWidth*c1->cubeHeight;
                if(visitedPoints[position] == false)
                  {
                    valueToCoordsC8.insert(pair<float, int >(c8->at(x,y,z), position));
                  }
              }
          }
      }
      printf("Threshold: %f, Layer %02i and %07i points\r",
             current_threshold, z, (int)valueToCoordsC8.size()); fflush(stdout);
    }//z of c8
    printf("\n");

    printf("The maps have been creared, now it is time to see what happens\n");
    int nPointsToEvaluate =
      valueToCoordsC1.size() + valueToCoordsC2.size() +
      valueToCoordsC4.size() + valueToCoordsC8.size();
    int nPointsEvaluated = 0;
    int nPointsAdded     = 0;
    multimap< float, int >::reverse_iterator riterC1 = valueToCoordsC1.rbegin();
    multimap< float, int >::reverse_iterator riterC2 = valueToCoordsC2.rbegin();
    multimap< float, int >::reverse_iterator riterC4 = valueToCoordsC4.rbegin();
    multimap< float, int >::reverse_iterator riterC8 = valueToCoordsC8.rbegin();


    vector< float > values(4);
    float maxVal;
    int maxIdx, position, windowErase, z_p, x_p, y_p;
    while(nPointsEvaluated < nPointsToEvaluate){
      nPointsEvaluated++;
      for(int i = 0; i < 4; i++)
        values[i] = -1e8;
      //Puts the values in the vector
      if(riterC1!=valueToCoordsC1.rend()) values[0] = (*riterC1).first;
      if(riterC2!=valueToCoordsC2.rend()) values[1] = (*riterC2).first;
      if(riterC4!=valueToCoordsC4.rend()) values[2] = (*riterC4).first;
      if(riterC8!=valueToCoordsC8.rend()) values[3] = (*riterC8).first;
      maxIdx = 0; maxVal = values[0];
      for(int i = 1; i < 4; i++){
        if(values[i] > maxVal){
          maxVal = values[i];
          maxIdx = i;
        }
      }
      if(maxIdx==0){ position = (*riterC1).second; riterC1++; windowErase = 30; }
      if(maxIdx==1){ position = (*riterC2).second; riterC2++; windowErase = 35; }
      if(maxIdx==2){ position = (*riterC4).second; riterC4++; windowErase = 40; }
      if(maxIdx==3){ position = (*riterC8).second; riterC8++; windowErase = 40; }

      if(visitedPoints[position] == true)
        continue;

      z_p = position / (c1->cubeWidth*c1->cubeHeight);
      y_p = (position - z_p*c1->cubeWidth*c1->cubeHeight)/c1->cubeWidth;
      x_p =  position - z_p*c1->cubeWidth*c1->cubeHeight - y_p*c1->cubeWidth;

      //To prevent the bug in the images
      if(x_p<=5) continue;
      int counter = 0;
      for(int z = max(z_p-windowErase*2/3,0);
          z < min(z_p+windowErase*2/3, (int)c1->cubeDepth); z++)
        for(int y = max(y_p-windowErase,0); y < min(y_p+windowErase, (int)c1->cubeHeight); y++)
          for(int x = max(x_p-windowErase,0); x < min(x_p+windowErase, (int)c1->cubeWidth); x++){
            if(visitedPoints[x + y*c1->cubeWidth + z*c1->cubeWidth*c1->cubeHeight] == true)
              counter++;
            visitedPoints[x + y*c1->cubeWidth + z*c1->cubeWidth*c1->cubeHeight] = true;
          }
      //Only add the point if half of the points arround it have not been visited. Prevents small points to be added

      if(counter > windowErase*windowErase*windowErase*2*2*2/2)
        continue;
      vector< float > coords(3);
      c1->indexesToMicrometers3(x_p, y_p, z_p, coords[0], coords[1], coords[2]);
      toReturn.push_back(coords);
      toReturnScales.push_back(maxIdx);
      thetas[maxIdx]->micrometersToIndexes3(coords[0], coords[1], coords[2],
                                            x_p, y_p, z_p);
      toReturnThetas.push_back(thetas[maxIdx]->at(x_p,y_p,z_p));
      toReturnPhis.push_back(phis[maxIdx]->at(x_p,y_p,z_p));
      nPointsAdded++;
//       printf("nEval = %i of %i\n", nPointsEvaluated, nPointsToEvaluate);
    } // while goinf throught the nms
    printf("%i points have been added\n", nPointsAdded);
    current_threshold = current_threshold - step_size;
  }// While threshold


  vector<float> radius(4);
  radius[0] = 0.4;
  radius[1] = 0.8;
  radius[2] = 1.2;
  radius[3] = 1.6;

  Cloud<Point3D >* cd1 = new Cloud<Point3D>();
  Cloud<Point3D >* cd2 = new Cloud<Point3D>();
  Cloud<Point3D >* cd4 = new Cloud<Point3D>();
  Cloud<Point3D >* cd8 = new Cloud<Point3D>();
  Cloud<Point3D >* ct  = new Cloud<Point3D>();
  Cloud<Point3Dotw>* ctw = new Cloud<Point3Dotw>();

  if(arguments.somaDefined){
    ct->points.push_back
      (new Point3D(arguments.somaX, arguments.somaY, arguments.somaZ));
    ctw->points.push_back
      (new Point3Dotw(arguments.somaX, arguments.somaY, arguments.somaZ,
                      Point3Dot::TrainingPositive, 5.0));
  }

  vector< Cloud< Point3D>*> clouds;
  clouds.push_back(cd1);   clouds.push_back(cd2);
  clouds.push_back(cd4);   clouds.push_back(cd8);

  for(int i = 0; i < toReturn.size(); i++){
    Point3D* pt = new Point3D( toReturn[i][0],
                               toReturn[i][1],
                               toReturn[i][2]);
    clouds[toReturnScales[i]]->points.push_back( pt );


    ct->points.push_back( pt );
    ctw->points.push_back
      (new Point3Dotw(toReturn[i][0], toReturn[i][1], toReturn[i][2],
                      toReturnThetas[i], toReturnPhis[i],
                      Point3Dot::TrainingPositive,
                      radius[toReturnScales[i]]));
  }
  cd1->v_r = 1;   cd1->v_g = 0;   cd1->v_b = 0;   cd1->v_radius = radius[0];
  cd2->v_r = 0;   cd2->v_g = 1;   cd2->v_b = 0;   cd2->v_radius = radius[1];
  cd4->v_r = 0;   cd4->v_g = 0;   cd4->v_b = 1;   cd4->v_radius = radius[2];
  cd8->v_r = 1;   cd8->v_g = 1;   cd8->v_b = 0;   cd8->v_radius = radius[3];

  cd1->saveToFile(directory + "/decimation_1.cl");
  cd2->saveToFile(directory + "/decimation_2.cl");
  cd4->saveToFile(directory + "/decimation_4.cl");
  cd8->saveToFile(directory + "/decimation_8.cl");
  ct->saveToFile (directory + "/decimated.cl");
  ctw->saveToFile(directory + "/decimatedW.cl");

}
示例#7
0
int main(int argc, char **argv) {

  vector<int>   idxs(3);
  vector<float> microm(3);
  char buff[1024];
  // For the color
  const gsl_rng_type * T2;
  gsl_rng * r;
  gsl_rng_env_setup();
  T2 = gsl_rng_default;
  r = gsl_rng_alloc (T2);


  // Cube<uchar, ulong>* cube = new Cube<uchar, ulong>("/media/neurons/cut2/cut2.nfo");
  // Cloud_P* decimatedCloud = CloudFactory::load("/media/neurons/cut2/decimated.cl");

  Cube<float, double>* cube = new Cube<float, double>
    ("/media/neurons/steerableFilters3D/tmp/cut/cut.nfo");
  Cloud_P* decimatedCloud = CloudFactory::load
    ("/media/neurons/steerableFilters3D/tmp/cut/dense.cl");
  Cloud<Point3D>* seedPointsSelected = new Cloud<Point3D>();

  DistanceDijkstraColorNegatedEuclidean* djkc
    = new DistanceDijkstraColorNegatedEuclidean(cube);
  CubeLiveWire* cubeLiveWire = new CubeLiveWire(cube, djkc);;


  vector<int> origIdxs(3);
  origIdxs[0] = 151;
  origIdxs[1] = 152;
  origIdxs[2] = 9;
  if(fileExists("/media/neurons/steerableFilters3D/tmp/cut/parents.nfo") &&
     fileExists("/media/neurons/steerableFilters3D/tmp/cut/distances.nfo")){
    printf("Loading the distances .... ");fflush(stdout);
    cubeLiveWire->loadParents("/media/neurons/steerableFilters3D/tmp/cut/parents.nfo");
    cubeLiveWire->loadDistances("/media/neurons/steerableFilters3D/tmp/cut/distances.nfo");
  } else{
    printf("Computing the distances .... ");fflush(stdout);
    cubeLiveWire->computeDistances(origIdxs[0],origIdxs[1],origIdxs[2]);
    cubeLiveWire->saveParents("parents");
    cubeLiveWire->saveDistances("distances");
  }
  printf(" distances done \n");


  multimap<float, Graph<Point3D, EdgeW<Point3D> >*> paths;

  Cloud< Point3D>* cloud = new Cloud<Point3D>();
  cube->indexesToMicrometers(origIdxs,microm);
  cloud->addPoint(microm[0],microm[1],microm[2]);
  cloud->v_g = 1.0;
  cloud->v_radius = 2.0;
  cloud->saveToFile("/media/neurons/steerableFilters3D/tmp/cut/original.cl");

  float cost;

  printf("Finding the shortest paths from all points to the soma[");fflush(stdout);
  for(int i = 0; i < decimatedCloud->points.size(); i++){
    cube->micrometersToIndexes3(decimatedCloud->points[i]->coords[0],
                                decimatedCloud->points[i]->coords[1],
                                decimatedCloud->points[i]->coords[2],
                                idxs[0],idxs[1],idxs[2]);

    Graph<Point3D, EdgeW<Point3D> >* shortestPath =
      cubeLiveWire->findShortestPathG(origIdxs[0],origIdxs[1],origIdxs[2],
                                      idxs[0],idxs[1],idxs[2]
                                      );
    cost = shortestPath->cloud->points.size() -
      cube->integralOverCloud(shortestPath->cloud);
    paths.insert(pair<float, Graph<Point3D, EdgeW<Point3D> >*>
                 ( exp(cost/(shortestPath->cloud->points.size())), shortestPath));
    if(i%100 == 0) printf("%02f]\r",
                          float(i*100)/decimatedCloud->points.size());fflush(stdout);
  }
  printf("\n");


  // Saves the paths according to the minimum mean distance
  if(1){
    int nGraphSaved = 0;
    for(multimap< float, Graph<Point3D, EdgeW<Point3D> >*>::iterator
          iter = paths.begin();
        iter != paths.end();
        iter++){
      Graph<Point3D, EdgeW<Point3D> >* gr = (*iter).second;
      sprintf(buff, "/media/neurons/steerableFilters3D/tmp/cut/opath%04i.gr",
              nGraphSaved++);
      gr->v_r = gsl_rng_uniform(r);
      gr->v_g = gsl_rng_uniform(r);
      gr->v_b = gsl_rng_uniform(r);
      gr->v_radius = 0.3;
      gr->cloud->v_r = gsl_rng_uniform(r);
      gr->cloud->v_g = gsl_rng_uniform(r);
      gr->cloud->v_b = gsl_rng_uniform(r);
      gr->cloud->v_radius = 0.3;
      gr->saveToFile(buff);
      if(nGraphSaved%100 == 0)
        printf("Saving the %i path with size %i\n", nGraphSaved, gr->cloud->points.size());
    }
  }


  // Getting the first 100 paths
  multimap< float, Graph<Point3D, EdgeW<Point3D> >*>::iterator
    iter = paths.begin();

  int cubeLength = cube->cubeDepth*cube->cubeHeight*cube->cubeWidth;
  int* visited_orig   = (int*) malloc(cubeLength*sizeof(int));
  int*** visited;
  visited = (int***) malloc(cube->cubeDepth*sizeof(int**));
  for(int z = 0; z < cube->cubeDepth; z++){
    visited  [z] = (int**) malloc(cube->cubeHeight*sizeof(int*));
    for(int j = 0; j < cube->cubeHeight; j++){
      visited[z][j] =(int*) &visited_orig [(z*cube->cubeHeight + j)*cube->cubeWidth];
    }
  }
  for(int i = 0; i < cubeLength; i++)
    visited_orig[i] = 0;




  int limitEnd = decimatedCloud->points.size()-1;
  // int limitEnd = 500 ;
  int nGraphsAdded = 0;
  int nGraphsRejected = 0;
  while(nGraphsAdded < limitEnd){
    iter = paths.begin();
    Graph<Point3D, EdgeW<Point3D> >* gr = (*iter).second;
    int nPoint = 0;
    bool alreadyVisited = false;
    //Check if there is a visited part of the path

    for(nPoint = 0; nPoint < gr->cloud->points.size(); nPoint++){
      microm[0] = gr->cloud->points[nPoint]->coords[0];
      microm[1] = gr->cloud->points[nPoint]->coords[1];
      microm[2] = gr->cloud->points[nPoint]->coords[2];
      cube->micrometersToIndexes(microm, idxs);
      if(visited[idxs[2]][idxs[1]][idxs[0]] == true){
        alreadyVisited = true;
        break;  // we reached a visited voxel
      }
    }

    //If the path has been already visited, we better forget of the visited part
    // and add a new graph to the list
    if(alreadyVisited){
      Graph<Point3D, EdgeW<Point3D> >* toAdd = gr->subGraphToPoint(nPoint);
      cost = toAdd->cloud->points.size() -
        cube->integralOverCloud(toAdd->cloud);
      if(nGraphsRejected%100 == 0)
        printf("Rejected %i paths\n", nGraphsRejected++);
      fflush(stdout);
      nGraphsRejected++;
      paths.erase(paths.begin());
      paths.insert(pair<float, Graph<Point3D, EdgeW<Point3D> >*>
                   (exp(cost/(toAdd->cloud->points.size())), toAdd));
    } else {
      for(int i = 0; i < gr->cloud->points.size(); i++){
        microm[0] = gr->cloud->points[i]->coords[0];
        microm[1] = gr->cloud->points[i]->coords[1];
        microm[2] = gr->cloud->points[i]->coords[2];
        if( (i==0) ||
            ((i == gr->cloud->points.size()-1)&&(i>0))
          )
          seedPointsSelected->points.push_back
            (new Point3D(microm[0],microm[1],microm[2]));
        cube->micrometersToIndexes(microm, idxs);
        visited[idxs[2]][idxs[1]][idxs[0]] = true;
        visited[origIdxs[2]][origIdxs[1]][origIdxs[0]] = false;
      }
      gr->v_r = gsl_rng_uniform(r);
      gr->v_g = gsl_rng_uniform(r);
      gr->v_b = gsl_rng_uniform(r);
      gr->v_radius = 0.3;
      gr->cloud->v_r = gsl_rng_uniform(r);
      gr->cloud->v_g = gsl_rng_uniform(r);
      gr->cloud->v_b = gsl_rng_uniform(r);
      gr->cloud->v_radius = 0.3;

      // cost = cube->integralOverCloud(gr->cloud)/gr->cloud->points.size();

      sprintf(buff, "/media/neurons/steerableFilters3D/tmp/cut/path%04i.gr",nGraphsAdded);
      nGraphsAdded++;
      gr->saveToFile(buff);
      if(nGraphsAdded%100 == 0)
        printf("Adding the %i path with size %i\n", nGraphsAdded, gr->cloud->points.size());
      paths.erase(paths.begin());
    }

  }//while
  seedPointsSelected->v_r = 1;
  seedPointsSelected->v_g = 0;
  seedPointsSelected->v_b = 1;
  seedPointsSelected->v_radius = 0.7;
  seedPointsSelected->saveToFile("/media/neurons/steerableFilters3D/tmp/cut/seedPointsSelected.cl");

  // Saves the visited points into a cube

  Cube<int, long>* visitedC =
    new Cube<int, long>(cube->cubeWidth, cube->cubeHeight, cube->cubeDepth,
                        cube->directory + "visited",
                        cube->voxelWidth, cube->voxelHeight, cube->voxelDepth);
  for(int x = 0; x < cube->cubeWidth; x++)
    for(int y = 0; y < cube->cubeHeight; y++)
      for(int z = 0; z < cube->cubeDepth; z++){
        visitedC->put(x,y,z, visited[z][y][x]);
      }


}//main
int main(int argc, char **argv) {

  struct arguments args;
  /* Default values. */
  args.name_image = "";
  args.name_orientation = "";
  args.name_mask = "";
  args.name_cloud = "cloud.cl";
  args.flag_symmetrize = false;
  args.number_negative_points = 0;

  argp_parse (&argp, argc, argv, 0, 0, &args);

  printf("Img: %s\nOrs: %s\nOut: %s\nMsk: %s\nSymmetrize: %i\nNumber_points: %i\n",
         args.name_image.c_str(),
         args.name_orientation.c_str(),
         args.name_cloud.c_str(),
         args.name_mask.c_str(),
         args.flag_symmetrize, args.number_negative_points);

  /** Random number generation.*/
  gsl_rng_env_setup();
  T2 = gsl_rng_default;
  r = gsl_rng_alloc (T2);

  Image< float >* img    = new Image< float >(args.name_image);
  Image< float >* orient = NULL;
  Image< float >* mask   = NULL;
  if(args.name_orientation != "")
    orient = new Image<float>(args.name_orientation);
  if(args.name_mask != "")
    mask = new Image<float>(args.name_mask);

  vector< int > indexes(3);
  vector< float > micrometers(3);
  indexes[2] = 0;

  vector< double > cumPDF = getCumulativePdf(img, mask);

  // saveVectorDouble(cumPDF, "cumPDF.txt");

  Cloud< Point2Dot >* cloud;
  if(fileExists(args.name_cloud))
    cloud = new Cloud< Point2Dot >(args.name_cloud);
  else
    cloud = new Cloud< Point2Dot >();

  double ort = 0;

  int nPoints = 0;
  while(nPoints < args.number_negative_points){

    int idx = sampleCumulativePdf(cumPDF, img);
    indexes[1] = (int)idx/img->width;
    indexes[0] = idx - img->width*indexes[1];

    //If the mask is 0, then loop again
    // if(mask != NULL)
      // if(mask->at(indexes[0], indexes[1]) < 100)
        // continue;

    img->indexesToMicrometers(indexes, micrometers);
    if(orient == NULL){
      ort = (gsl_rng_uniform(r)-0.5)*2*M_PI;
    } else {
      ort = orient->at(indexes[0], indexes[1]);
    }

    cloud->points.push_back(new Point2Dot(micrometers[0], micrometers[1],
                                          ort, -1));
    nPoints++;

    if(args.flag_symmetrize){
      cloud->points.push_back(new Point2Dot(micrometers[0], micrometers[1],
                                            ort + M_PI, -1));
      nPoints++;
    }
  }
  cloud->saveToFile(args.name_cloud);
}