// 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; }
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(); } }
/*-------------------------------------------------------------*/ 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 ¢er, 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); }