// Creates the best possible patch to match the given target
		Heightmap bestPatch(const Heightmap *output, const Patch &target_patch, const ivec2 &target_offset, const vector<Patch> &candidates) {

			// Create a comparator for PatchCandidate
			auto cmp = [](const PatchCandidate &left, const PatchCandidate &right) { return left.cost > right.cost; };

			// create and populate a priority queue for candidates
			priority_queue<PatchCandidate, vector<PatchCandidate>, decltype(cmp)> target_candidates(cmp);
			for (const Patch &p : candidates) {
				// use patch if the the degree matches
				if (p.degree == target_patch.degree)
					target_candidates.emplace(&p, computeCost(p, target_patch, target_offset, output, 5.0, 2.0, 0.001, 1.0));
			}

			// if no patches were found with matching degree, use all patches
			if (target_candidates.empty()) {
				for (const Patch &p : candidates) {
					target_candidates.emplace(&p, computeCost(p, target_patch, target_offset, output, 5.0, 2.0, 0.001, 1.0));
				}
			} 

			
			// compute cost (and graphcut) for best n (typically 5) candidates
			float best_cost = 0;
			Heightmap best_patch = graphcut(output, &(target_candidates.top().patch->data), target_offset, &best_cost);

			for (int i = 0; i < 5 && !target_candidates.empty(); ++i) {
				target_candidates.pop();

				float cost = 0;
				Heightmap g = graphcut(output, &(target_candidates.top().patch->data), target_offset, &cost);
				if (cost < best_cost) {
					best_patch = g;
					best_cost = cost;
				}
			}
			
			return best_patch;
		}
Пример #2
0
int main()
{ 

	init();
	showHelp();

	int length = ReadCfg::data.size();
	int i = 0;
	while (length--)
	{
		Mat image = imread(ReadCfg::data[i].path);
		graphcut(image);
		++i;
		int order;
		cout << "继续?1/0"<<endl;
		cin >> order;
		if (order != 1)
			break;
		getGlobal()->reset();
	}
}
Пример #3
0
/*-------------------------------------------------------------*/
int main(int argc, char *argv[])
{
  /* check for and handle version tag */
  int nargs = handle_version_option
              (argc, argv,
               "$Id: mri_gcut.cpp,v 1.14 2011/03/02 00:04:16 nicks Exp $",
               "$Name: stable5 $");
  if (nargs && argc - nargs == 1)
  {
    exit (0);
  }
  argc -= nargs;

  Progname = argv[0] ;
  ErrorInit(NULL, NULL, NULL) ;
  DiagInit(NULL, NULL, NULL) ;

  parse_commandline(argc, argv);

  MRI *mri, *mri2, *mri3, *mri_mask=NULL;
  mri3  = MRIread(in_filename);
  if ( mri3 == NULL )
  {
    printf("can't read file %s\nexit!\n", in_filename);
    exit(0);
  }
  mri   = MRISeqchangeType(mri3, MRI_UCHAR, 0.0, 0.999, FALSE);
  mri2  = MRISeqchangeType(mri3, MRI_UCHAR, 0.0, 0.999, FALSE);
  //MRI* mri4 = MRIread("gcutted.mgz");

  if (bNeedMasking == 1)
  {
    printf("reading mask...\n");
    mri_mask = MRIread(mask_filename);
    if ( mri_mask == NULL )
    {
      printf("can't read %s, omit -mult option!\n", mask_filename);
      print_help();
      exit(1);
    }
    else
    {
      if ( mri_mask->width != mri->width ||
           mri_mask->height != mri->height ||
           mri_mask->depth != mri->depth )
      {
        printf("Two masks are of different size, omit -mult option!\n");
        print_help();
        exit(1);
      }
    }
  }

  int w = mri->width;
  int h = mri->height;
  int d = mri->depth;

  // -- copy of mri matrix
  unsigned char ***label;
  label = new unsigned char**[d];
  for (int i = 0; i < d; i++)
  {
    label[i] = new unsigned char*[h];
    for (int j = 0; j < h; j++)
    {
      label[i][j] = new unsigned char[w];
      for (int k = 0; k < w; k++)
      {
        label[i][j][k] = 0;
      }
    }
  }
  // -- gcut image
  int ***im_gcut;
  im_gcut = new int**[d];
  for (int i = 0; i < d; i++)
  {
    im_gcut[i] = new int*[h];
    for (int j = 0; j < h; j++)
    {
      im_gcut[i][j] = new int[w];
      for (int k = 0; k < w; k++)
      {
        im_gcut[i][j][k] = 0;
      }
    }
  }
  // -- diluted
  int ***im_diluteerode;
  im_diluteerode = new int**[d];
  for (int i = 0; i < d; i++)
  {
    im_diluteerode[i] = new int*[h];
    for (int j = 0; j < h; j++)
    {
      im_diluteerode[i][j] = new int[w];
      for (int k = 0; k < w; k++)
      {
        im_diluteerode[i][j][k] = 0;
      }
    }
  }
  //int w, h, d;
  //int x, y, z;
  double whitemean;
  if (bNeedPreprocessing == 0)
  {
    // pre-processed: 110 intensity voxels are the WM
    if (LCC_function(mri ->slices,
                     label,
                     mri->width,
                     mri->height,
                     mri->depth,
                     whitemean) == 1)
    {
      if ( whitemean < 0 )
      {
        printf("whitemean < 0 error!\n");
        exit(0);
      }
    }
    else
    {
      whitemean = 110;
      printf("use voxels with intensity 110 as WM mask\n");
    }
  }
  else
  {
    printf("estimating WM mask\n");
    whitemean = pre_processing(mri ->slices,
                               label,
                               mri->width,
                               mri->height,
                               mri->depth);
    if ( whitemean < 0 )
    {
      printf("whitemean < 0 error!\n");
      exit(0);
    }
  }
  double threshold = whitemean * _t;
  printf("threshold set to: %f*%f=%f\n", whitemean, _t, threshold);

  for (int z = 0 ; z < mri->depth ; z++)
  {
    for (int y = 0 ; y < mri->height ; y++)
    {
      for (int x = 0 ; x < mri->width ; x++)
      {
        if ( mri->slices[z][y][x] < threshold + 1 )
        {
          mri->slices[z][y][x] = 0;
        }
      }
    }//end of for
  }

  //new code
  int ***foregroundseedwt;
  int ***backgroundseedwt;
  matrix_alloc(&foregroundseedwt, d, h, w);
  matrix_alloc(&backgroundseedwt, d, h, w);

  double kval = 2.3;
  graphcut(mri->slices, label, im_gcut,
           foregroundseedwt, backgroundseedwt,
           w, h, d, kval, threshold, whitemean);
  printf("g-cut done!\npost-processing...\n");
  //printf("_test: %f\n", _test);

  post_processing(mri2->slices,
                  mri->slices,
                  threshold,
                  im_gcut,
                  im_diluteerode,
                  w, h, d);
  printf("post-processing done!\n");

  if (bNeedMasking == 1)//masking
  {
    printf("masking...\n");
    for (int z = 0 ; z < mri_mask->depth ; z++)
    {
      for (int y = 0 ; y < mri_mask->height ; y++)
      {
        for (int x = 0 ; x < mri_mask->width ; x++)
        {
          if ( mri_mask->slices[z][y][x] == 0 )
          {
            im_diluteerode[z][y][x] = 0;
          }
        }
      }
    }
  }

  //if the output might have some problem
  int numGcut = 0, numMask = 0;
  double _ratio = 0;
  int error_Hurestic = 0;
  if (bNeedMasking == 1)//-110 and masking are both set
  {
    for (int z = 0 ; z < mri_mask->depth ; z++)
    {
      for (int y = 0 ; y < mri_mask->height ; y++)
      {
        for (int x = 0 ; x < mri_mask->width ; x++)
        {
          if ( im_diluteerode[z][y][x] != 0 )
          {
            numGcut++;
          }
          if ( mri_mask->slices[z][y][x] != 0 )
          {
            numMask++;
          }
        }
      }
    }
    _ratio = (double)numGcut / numMask;
    if (_ratio <= 0.85)
    {
      error_Hurestic = 1;
    }
  }

  if (error_Hurestic == 1)
  {
    printf("** Gcutted brain is much smaller than the mask!\n");
    printf("** Using the mask as the output instead!\n");
    //printf("** Gcutted output is written as: 'error_gcutted_sample'\n");
  }

  for (int z = 0 ; z < mri->depth ; z++)
  {
    for (int y = 0 ; y < mri->height ; y++)
    {
      for (int x = 0 ; x < mri->width ; x++)
      {
        if (error_Hurestic == 0)
        {
          if ( im_diluteerode[z][y][x] == 0 )
          {
            mri2 ->slices[z][y][x] = 0;
          }
        }
        else
        {
          if ( mri_mask->slices[z][y][x] == 0 )
          {
            mri2 ->slices[z][y][x] = 0;
          }
          //if( im_diluteerode[z][y][x] == 0 )
          //mri ->slices[z][y][x] = 0;
        }
      }
    }//end of for 2
  }//end of for 1

  MRIwrite(mri2, out_filename);

  // if user supplied a filename to which to write diffs, then write-out
  // volume file containing where cuts were made (for debug)
  if (diff_filename[0] && (error_Hurestic != 1))
  {
    MRI *mri_diff = MRISeqchangeType(mri3, MRI_UCHAR, 0.0, 0.999, FALSE);
    for (int z = 0 ; z < mri3->depth ; z++)
    {
      for (int y = 0 ; y < mri3->height ; y++)
      {
        for (int x = 0 ; x < mri3->width ; x++)
        {
          if (mri_mask)
          {
            mri_diff->slices[z][y][x] =
              mri2->slices[z][y][x] - mri_mask->slices[z][y][x];
          }
          else
          {
            mri_diff->slices[z][y][x] =
              mri2->slices[z][y][x] - mri3->slices[z][y][x];
          }
        }
      }//end of for 2
    }//end of for 1
    MRIwrite(mri_diff, diff_filename);
    MRIfree(&mri_diff);
  }

  if (mri)
  {
    MRIfree(&mri);
  }
  if (mri2)
  {
    MRIfree(&mri2);
  }
  if (mri3)
  {
    MRIfree(&mri3);
  }
  if (mri_mask)
  {
    MRIfree(&mri_mask);
  }
  for (int i = 0; i < d; i++)
  {
    for (int j = 0; j < h; j++)
    {
      delete[] im_diluteerode[i][j];
      delete[] im_gcut[i][j];
      delete[] label[i][j];
    }
    delete[] im_diluteerode[i];
    delete[] im_gcut[i];
    delete[] label[i];
  }
  delete[] im_diluteerode;
  delete[] im_gcut;
  delete[] label;

  return 0;
}
int main(int argc,char *argv[])
{


    float beta;
    int* tab;
    int xmin;
    int xmax;
    int ymax;
    int ymin;

    // Loading image
    char* imagePath = argv[1];

    cimg_library::CImg<unsigned char> image(imagePath);
    // Patch size
    int w;
    cout << "Please enter size of Patch (must be odd and positive): ";
    cin >> w;
    bool odd = (w-(w/2)*2!=0);
    assert(odd);
    bool positive = (w>=0);
    assert(positive);
    // Minimum offset size
    int tau;
    cout << "Please enter minimum offset value (must be positive): ";
    cin >>tau;
    positive = (tau>=0);
    assert(positive);
    // Random search parameter
    float alpha;
    cout << "Please enter alpha (random search parameter) value (must be between 0 and 1): ";
    cin >> alpha;
    positive = (alpha>=0);
    assert(positive);
    bool inferior_one = (alpha<1);
    assert(inferior_one);
    // Number of vectors to keep
    int nb;
    cout << "Please enter the number of offsets to keep: ";
    cin >> nb;
    positive = (nb>=0);
    assert(positive);

    // Loading offset field

    int** offsetField = patchmatch(image,w,tau,alpha);
    int** tabVect = occurrenceOffsets(offsetField,image,w,nb);


    while(true){
    // Zone to complete
    tab = getXYImage(image);
    xmin = tab[0];
    ymin = tab[1];

if (tab[0]==-1){return 0;}

    tab = getXYImage(image);
    xmax = tab[0];
    ymax = tab[1];

if (tab[0]==-1){return 0;}

    cout << "Please enter Beta value: ";
    cin >> beta;

    int width = image.width();
    int height = image.height();
    cimg_library::CImg<unsigned char> newImage(width,height,1,3);
    newImage = graphcut(image,tabVect,xmin,xmax,ymin,ymax,w,beta,nb);
    displayImage(newImage);
    }

return 0;
}
		// control_points relative to center
		void placeFeature(const std::vector<Patch> &patches, const vec2 &center, vector<vec2> target_control_points, int patch_size, Heightmap *output) {


			const float deformation_weight = 1000.0;
			const float graphcut_weight = 1.0;
			const float feature_weight = 1.0;


			// control points 
			if (target_control_points.size() == 0) return;


			vec2 top_left = center - patch_size / 2;
			int target_degree = target_control_points.size();

			Heightmap best_patch(1,1);
			float best_cost = numeric_limits<float>::max();

			// construct the full set of target points for matching the thin_plate spline
			vector<vec2> target_points;
			target_points.push_back(vec2(patch_size / 2)); // push on the center point
			for (vec2 v : target_control_points) target_points.push_back(v);


			// for every patch
			for (const Patch &p : patches) {
				if (p.degree == target_degree) {

					// ugh TODO
					if (!p.degree > 1) return;


					// Find the best thin plate spline to morph the patch
					// the spline is used to sample the source patch from the perspective of the target
					float best_thin_plate_cost = numeric_limits<float>::max();
					pair<thin_plate_2f, thin_plate_2f> best_thin_plate;


					// create the source points for the thin plate spline
					vector<vec2> source_points = p.controlPoints(); // outpath/control points

					// for every iteration of target control points
					for (int offset = 0; offset < target_degree; offset++) {

						// store the change for a given sample coordinate on the target
						vector<float> d_points_x;
						vector<float> d_points_y;
						
						// no change for center point
						d_points_x.push_back(0);
						d_points_y.push_back(0);

						for (int i = 0; i < target_degree; i++) {
							vec2 d_control = source_points[(i + offset) % target_degree] - target_points[i + 1];
							d_points_x.push_back(d_control.x);
							d_points_y.push_back(d_control.y);
						}

						// create the pair of thin plates for x and y dimensions
						pair<thin_plate_2f, thin_plate_2f> thin_plate {
							thin_plate_2f(target_points, d_points_x),
							thin_plate_2f(target_points, d_points_y)
						};

						float thin_plate_cost = thin_plate.first.energy() + thin_plate.second.energy();

						// find the spline with the minimum energy
						if (thin_plate_cost < best_thin_plate_cost) {
							best_thin_plate_cost = thin_plate_cost;
							best_thin_plate = thin_plate;
						}
					}

					
					// create a new warped patch
					Heightmap p_prime(p.data.size());
					for (size_t y = 0; y < p_prime.height(); ++y) {
						for (size_t x = 0; x < p_prime.width(); ++x) {
							ivec2 target_p(x, y);
							vec2 source_p = target_p + vec2(
								best_thin_plate.first.interpolate(target_p), 
								best_thin_plate.second.interpolate(target_p)
							);

							if (p.data.inBounds(source_p) && p.data.inBounds(source_p + 1)) {
								p_prime.at(target_p) = p.data.sample(source_p.x, source_p.y);
							}
							
							
							p_prime.at(x, y);
						}
					}



					// calculate graphcut
					float graph_cut_cost;
					Heightmap p_prime_prime = graphcut(output, &p_prime, top_left, &graph_cut_cost);

					

					//// green is points transformed
					//image3f img = make_special_heightmap_image(p.data);
					//for (vec2 v : p.controlPoints()) {
					//	img.drawRect(v - vec2(3), vec2(6), vec3::k()); // blue is original course points
					//}
					//img.drawRect(vec2(patch_size/2) - vec2(3), vec2(6), vec3::k()); // blue is original course points
					//for (vec2 v : target_points) {// green is target point transformed
					//	img.drawRect(v + vec2(
					//		best_thin_plate.first.interpolate(v),
					//		best_thin_plate.second.interpolate(v)
					//	) - vec2(3), vec2(6), vec3::j()
					//	);
					//}


					////gui::cache_upload(img, "patch");
					//
					//ostringstream oss;
					//oss << "best_thin_plate_cost = "  << best_thin_plate_cost;
					//img = make_special_heightmap_image(p_prime);

					//// blue is target
					//for (vec2 v : target_control_points) {
					//	img.drawRect(v - vec2(3), vec2(6), vec3::k()); // blue is original
					//}

					//gui::cache_upload(img, oss.str());


					float total_cost = graphcut_weight * graph_cut_cost + deformation_weight * best_thin_plate_cost;
					//float total_cost = best_thin_plate_cost;

					if (total_cost < best_cost) {
						// save as a Candidate patch
						best_cost = total_cost;
						best_patch = p_prime_prime;
					}


				}
			}



			mergePatch(output, &best_patch, top_left);
		}