static void globalMattingHelper(cv::Mat _image, cv::Mat _trimap, cv::Mat &_foreground, cv::Mat &_alpha, cv::Mat &_conf) { const cv::Mat_<cv::Vec3b> &image = (const cv::Mat_<cv::Vec3b>&)_image; const cv::Mat_<uchar> &trimap = (const cv::Mat_<uchar>&)_trimap; std::vector<cv::Point> foregroundBoundary = findBoundaryPixels(trimap, 255, 128); std::vector<cv::Point> backgroundBoundary = findBoundaryPixels(trimap, 0, 128); int n = (int)(foregroundBoundary.size() + backgroundBoundary.size()); for (int i = 0; i < n; ++i) { int x = rand() % trimap.cols; int y = rand() % trimap.rows; if (trimap(y, x) == 0) backgroundBoundary.push_back(cv::Point(x, y)); else if (trimap(y, x) == 255) foregroundBoundary.push_back(cv::Point(x, y)); } std::sort(foregroundBoundary.begin(), foregroundBoundary.end(), IntensityComp(image)); std::sort(backgroundBoundary.begin(), backgroundBoundary.end(), IntensityComp(image)); std::vector<std::vector<Sample> > samples; calculateAlphaPatchMatch(image, trimap, foregroundBoundary, backgroundBoundary, samples); _foreground.create(image.size(), CV_8UC3); _alpha.create(image.size(), CV_8UC1); _conf.create(image.size(), CV_8UC1); cv::Mat_<cv::Vec3b> &foreground = (cv::Mat_<cv::Vec3b>&)_foreground; cv::Mat_<uchar> &alpha = (cv::Mat_<uchar>&)_alpha; cv::Mat_<uchar> &conf = (cv::Mat_<uchar>&)_conf; for (int y = 0; y < alpha.rows; ++y) for (int x = 0; x < alpha.cols; ++x) { switch (trimap(y, x)) { case 0: alpha(y, x) = 0; conf(y, x) = 255; foreground(y, x) = 0; break; case 128: { alpha(y, x) = 255 * samples[y][x].alpha; conf(y, x) = 255 * exp(-samples[y][x].cost / 6); cv::Point p = foregroundBoundary[samples[y][x].fi]; foreground(y, x) = image(p.y, p.x); break; } case 255: alpha(y, x) = 255; conf(y, x) = 255; foreground(y, x) = image(y, x); break; } } }
// erode foreground and background regions to increase the size of unknown region static void erodeFB(cv::Mat &_trimap, int r) { cv::Mat_<uchar> &trimap = (cv::Mat_<uchar>&)_trimap; int w = trimap.cols; int h = trimap.rows; cv::Mat_<uchar> foreground(trimap.size(), (uchar)0); cv::Mat_<uchar> background(trimap.size(), (uchar)0); for (int y = 0; y < h; ++y) for (int x = 0; x < w; ++x) { if (trimap(y, x) == 0) background(y, x) = 1; else if (trimap(y, x) == 255) foreground(y, x) = 1; } cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(r, r)); cv::erode(background, background, kernel); cv::erode(foreground, foreground, kernel); for (int y = 0; y < h; ++y) for (int x = 0; x < w; ++x) { if (background(y, x) == 0 && foreground(y, x) == 0) trimap(y, x) = 128; } }
void SpinBlock::addAdditionalCompOps() { #ifndef SERIAL boost::mpi::communicator world; if (world.size() == 1) return; //there is no need to have additional compops int length = dmrginp.last_site(); int dotopindex = (sites[0] == 0) ? complementary_sites[0] : complementary_sites[complementary_sites.size()-1]; if (!ops[CRE]->is_local()) { for(int i=0; i<get_sites().size(); i++) { if (ops[CRE]->has(sites[i])) { if (processorindex(sites[i]) != mpigetrank()) ops[CRE]->add_local_indices(sites[i]); mpi::broadcast(world, *(ops[CRE]->get_element(sites[i])[0]), processorindex(sites[i])); } } } for (int i=0; i<complementary_sites.size(); i++) { int compsite = complementary_sites[i]; if (compsite == dotopindex) continue; int I = (compsite > dotopindex) ? compsite : dotopindex; int J = (compsite > dotopindex) ? dotopindex : compsite; if (processorindex(compsite) == processorindex(trimap(I, J, length))) continue; if (processorindex(compsite) == mpigetrank()) { bool other_proc_has_ops = true; world.recv(processorindex(trimap(I, J, length)), 0, other_proc_has_ops); //this will potentially receive some ops if (other_proc_has_ops) { ops[CRE_DESCOMP]->add_local_indices(I, J); recvcompOps(*ops[CRE_DESCOMP], I, J, CRE_DESCOMP); ops[DES_DESCOMP]->add_local_indices(I, J); recvcompOps(*ops[DES_DESCOMP], I, J, DES_DESCOMP); } } else { //this will potentially send some ops if (processorindex(trimap(I, J, length)) == mpigetrank()) { bool this_proc_has_ops = ops[CRE_DESCOMP]->has_local_index(I, J); world.send(processorindex(compsite), 0, this_proc_has_ops); if (this_proc_has_ops) { sendcompOps(*ops[CRE_DESCOMP], I, J, CRE_DESCOMP, compsite); sendcompOps(*ops[DES_DESCOMP], I, J, DES_DESCOMP, compsite); } } else continue; } //dmrginp.datatransfer.stop(); //dmrginp.datatransfer -> stop(); //ROA } #endif }
void SpinBlock::recvcompOps(Op_component_base& opcomp, int I, int J, int optype) { #ifndef SERIAL boost::mpi::communicator world; std::vector<boost::shared_ptr<SparseMatrix> > oparray = opcomp.get_element(I,J); for(int i=0; i<oparray.size(); i++) { world.recv(processorindex(trimap(I, J, dmrginp.last_site())), optype+i*10+1000*J+100000*I, *oparray[i]); } #endif }
static void expansionOfKnownRegionsHelper(const cv::Mat &_image, cv::Mat &_trimap, int r, float c) { const cv::Mat_<cv::Vec3b> &image = (const cv::Mat_<cv::Vec3b> &)_image; cv::Mat_<uchar> &trimap = (cv::Mat_<uchar>&)_trimap; int w = image.cols; int h = image.rows; for (int x = 0; x < w; ++x) for (int y = 0; y < h; ++y) { if (trimap(y, x) != 128) continue; const cv::Vec3b &I = image(y, x); for (int j = y-r; j <= y+r; ++j) for (int i = x-r; i <= x+r; ++i) { if (i < 0 || i >= w || j < 0 || j >= h) continue; if (trimap(j, i) != 0 && trimap(j, i) != 255) continue; const cv::Vec3b &I2 = image(j, i); float pd = sqrt((float)(sqr(x - i) + sqr(y - j))); float cd = colorDist(I, I2); if (pd <= r && cd <= c) { if (trimap(j, i) == 0) trimap(y, x) = 1; else if (trimap(j, i) == 255) trimap(y, x) = 254; } } } for (int x = 0; x < trimap.cols; ++x) for (int y = 0; y < trimap.rows; ++y) { if (trimap(y, x) == 1) trimap(y, x) = 0; else if (trimap(y, x) == 254) trimap(y, x) = 255; } }