/* Construct GCGraph */ void constructGCGraph( const Mat& img, const Mat& mask, const GMM& bgdGMM, const GMM& fgdGMM, double lambda, const Mat& leftW, const Mat& upleftW, const Mat& upW, const Mat& uprightW, GCGraph<double>& graph ) { int vtxCount = img.cols*img.rows, edgeCount = 2*(4*img.cols*img.rows - 3*(img.cols + img.rows) + 2); graph.create(vtxCount, edgeCount); Point p; for( p.y = 0; p.y < img.rows; p.y++ ) { for( p.x = 0; p.x < img.cols; p.x++) { // add node int vtxIdx = graph.addVtx(); Vec3b color = img.at<Vec3b>(p); // set t-weights double fromSource, toSink; if( mask.at<uchar>(p) == GC_PR_BGD || mask.at<uchar>(p) == GC_PR_FGD ) { fromSource = -log( bgdGMM(color) ); toSink = -log( fgdGMM(color) ); } else if( mask.at<uchar>(p) == GC_BGD ) { fromSource = 0; toSink = lambda; } else // GC_FGD { fromSource = lambda; toSink = 0; } graph.addTermWeights( vtxIdx, fromSource, toSink ); // set n-weights if( p.x>0 ) { double w = leftW.at<double>(p); graph.addEdges( vtxIdx, vtxIdx-1, w, w ); } if( p.x>0 && p.y>0 ) { double w = upleftW.at<double>(p); graph.addEdges( vtxIdx, vtxIdx-img.cols-1, w, w ); } if( p.y>0 ) { double w = upW.at<double>(p); graph.addEdges( vtxIdx, vtxIdx-img.cols, w, w ); } if( p.x<img.cols-1 && p.y>0 ) { double w = uprightW.at<double>(p); graph.addEdges( vtxIdx, vtxIdx-img.cols+1, w, w ); } } } }
/* Construct GCGraph */ static void constructGCGraph( const Mat& img, double lambda, const Mat& leftW, const Mat& upleftW, const Mat& upW, const Mat& uprightW, GCGraph<double>& graph ) { int vtxCount = img.cols*img.rows, edgeCount = 2*(4*img.cols*img.rows - 3*(img.cols + img.rows) + 2); graph.create(vtxCount, edgeCount); Point p; Mat gray; cvtColor(img, gray, CV_BGR2GRAY); Mat bw; threshold(gray, bw, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); for( p.y = 0; p.y < img.rows; p.y++ ) { for( p.x = 0; p.x < img.cols; p.x++) { // add node int vtxIdx = graph.addVtx(); Vec3b color = img.at<Vec3b>(p); // set t-weights double fromSource, toSink; if(bw.at<uchar>(p) == 0) { fromSource = lambda; toSink = 0; } else { fromSource = 0; toSink = lambda; } graph.addTermWeights( vtxIdx, fromSource, toSink ); // set n-weights if( p.x>0 ) { double w = leftW.at<double>(p); graph.addEdges( vtxIdx, vtxIdx-1, w, w ); } if( p.x>0 && p.y>0 ) { double w = upleftW.at<double>(p); graph.addEdges( vtxIdx, vtxIdx-img.cols-1, w, w ); } if( p.y>0 ) { double w = upW.at<double>(p); graph.addEdges( vtxIdx, vtxIdx-img.cols, w, w ); } if( p.x<img.cols-1 && p.y>0 ) { double w = uprightW.at<double>(p); graph.addEdges( vtxIdx, vtxIdx-img.cols+1, w, w ); } } } }
/** * Add each pixel as * a node in a graph * * @param graph The graph pointer * @param img The Source image * * * @return Updates the graph */ void GRAPHCUT::addVertices(GCGraph<float>& graph, Mat& img) { for (int r = 0; r < img.rows; r++) for (int c = 0; c < img.cols; c++) { graph.addVtx(); graph.addTermWeights(c + img.cols * r, img.at<float>(r, c), 1 - img.at<float>(r, c)); } }