void example1() { typedef Graph<int, int, int> GraphType; GraphType *g = new GraphType(/*estimated # of nodes*/2, /*estimated # of edges*/ 1); g->add_node(); g->add_node(); g->add_tweights(0, /* capacities */3, 9); g->add_tweights(1, /* capacities */8, 1); g->add_edge(0, 1, /* capacities */3, 4); int flow = g->maxflow(); std::cout << "Flow = " << flow << std::endl; std::cout << "Minimum cut:" << std::endl; for (int i = 0; i < g->get_node_num(); ++i) { if (g->what_segment(i) == GraphType::SOURCE) std::cout << "node " << i << " is in the SOURCE set" << std::endl; else std::cout << "node " << i << " is in the SINK set" << std::endl; } delete g; }
GraphType* create_graph(std::vector< EdgeType >& edges, std::vector<int>& curr_edge_cap, std::vector<int>& curr_lambda_cap, const std::vector<int>& fg_nodes, const int INFTY, const int NUM_NODES, const bool fg_cap_inf) { bool is_fg; GraphType *g = new GraphType(NUM_NODES, edges.size()); g->add_node(NUM_NODES); for (unsigned int i = 0; i < NUM_NODES; ++i) { is_fg = false; for (unsigned int j = 0; j < fg_nodes.size(); ++j) { if (i == fg_nodes[j]) { is_fg = true; break; } } if (is_fg) g->add_tweights(i, /* capacities */(fg_cap_inf ? INFTY : curr_lambda_cap[i]), 0); else g->add_tweights(i, /* capacities */0, curr_lambda_cap[i]); } /* capacity edges */ for (unsigned int i = 0; i < edges.size(); ++i) { g->add_edge(edges[i].first, edges[i].second, curr_edge_cap[i], curr_edge_cap[i]); } return g; }
GraphType* construct_graph(const int NUM_NODES, const int NUM_EDGES, const int bg_cap[], const int edges_a[], const int edges_b[], const int edges_cap[], GraphType::FGSeedsType& fg_nodes, const int lambda) { GraphType::SrcSeedNode* it; GraphType *g = new GraphType(NUM_NODES, NUM_EDGES); g->add_node(NUM_NODES); /* add unary edges */ for (unsigned int i = 0; i < g->get_node_num(); ++i) { int fg_node_id = get_node_source_id(i, fg_nodes, it); if (fg_node_id == INVALID_SRC_ID) { g->add_tweights(i, /* capacities */0, bg_cap[i] + lambda); } else { g->add_tweights(i, /* capacities */infty, 0); it->second.first = infty; it->second.second = bg_cap[i] + lambda; } g->set_node_source_idx(i, fg_node_id); } /* add pairwise edges */ for (unsigned int i = 0; i < NUM_EDGES; ++i) g->add_edge(edges_a[i], edges_b[i], edges_cap[i], edges_cap[i]); return g; }
static void yagi_random_graph(GraphType &g, size_t max_vertices, int vertex_time_limit, double edge_to_vertex_ratio) { start_deadman(vertex_time_limit); for (size_t i=0; i<max_vertices && !had_alarm; ++i) g.add_vertex(); for (size_t i=g.num_vertices()*edge_to_vertex_ratio; i>0; --i) g.add_edge(yagi_random_vertex(g), yagi_random_vertex(g)); }
void GCOutputBoykovWorker::run() { const int width = m_SourceImage.width(); const int height = m_SourceImage.height(); const int nLabels = 2; cv::Mat src(height, width, CV_8UC3, m_SourceImage.bits(), m_SourceImage.bytesPerLine()); // Allocate graph int num_nodes = width * height; int num_edges = (width-1)*height + width*(height-1); typedef Graph<int,int,int> GraphType; GraphType* graph = new GraphType(num_nodes, num_edges); graph->add_node(num_nodes); // Initialize Data Term generateDataTerm([graph,width](int x, int y, int dterm1, int dterm2){ GraphType::node_id node = y * width + x; graph->add_tweights(node, dterm1, dterm2); }); // Initialize Smoothness Term generateSmoothTerm([graph,width](int x1, int y1, int x2, int y2, int cap1, int cap2){ GraphType::node_id node1, node2; node1 = y1 * width + x1, node2 = y2 * width + x2; graph->add_edge(node1, node2, cap1, cap2); }); // Compute int flow = graph->maxflow(); qDebug("Flow = %d", flow); // Read Result QImage destImage(width, height, QImage::Format_RGB888); cv::Mat dst(height, width, CV_8UC3, destImage.bits(), destImage.bytesPerLine()); for (int y = 0; y < dst.rows; ++y) { for (int x = 0; x < dst.cols; ++x) { GraphType::node_id node = y * width + x; if (graph->what_segment(node) == GraphType::SOURCE) { dst.at<cv::Vec3b>(y,x)[0] = 255; dst.at<cv::Vec3b>(y,x)[1] = 255; dst.at<cv::Vec3b>(y,x)[2] = 255; } else { dst.at<cv::Vec3b>(y,x)[0] = 0; dst.at<cv::Vec3b>(y,x)[1] = 0; dst.at<cv::Vec3b>(y,x)[2] = 0; } } } delete graph; emit completed(destImage); }
int main(int argc, char** argv) { // Check arguments if (argc < 3) { std::cerr << "Usage: " << argv[0] << " NODES_FILE TETS_FILE\n"; exit(1); } // Construct a Graph typedef Graph<int, int> GraphType; GraphType graph; std::vector<GraphType::node_type> nodes; // Create a nodes_file from the first input argument std::ifstream nodes_file(argv[1]); // Interpret each line of the nodes_file as a 3D Point and add to the Graph Point p; while (CME212::getline_parsed(nodes_file, p)) nodes.push_back(graph.add_node(p)); // Create a tets_file from the second input argument std::ifstream tets_file(argv[2]); // Interpret each line of the tets_file as four ints which refer to nodes std::array<int,4> t; while (CME212::getline_parsed(tets_file, t)) for (unsigned i = 1; i < t.size(); ++i) for (unsigned j = 0; j < i; ++j) graph.add_edge(nodes[t[i]], nodes[t[j]]); // Print out the stats std::cout << graph.num_nodes() << " " << graph.num_edges() << std::endl; // Launch the SDLViewer CME212::SDLViewer viewer; viewer.launch(); auto node_map = viewer.empty_node_map(graph); Point pref = Point(-1, 0, 1); int path = shortest_path_lengths(graph, pref); PathColorFn pcf = PathColorFn(path); viewer.add_nodes(graph.node_begin(), graph.node_end(), pcf, node_map); // Test the PositionColorFn, the color is presented according to the nodes' x coordinats. //PositionColorFn pocf = PositionColorFn(); //viewer.add_nodes(graph.node_begin(), graph.node_end(), pocf, node_map); viewer.add_edges(graph.edge_begin(), graph.edge_end(), node_map); viewer.center_view(); return 0; }
int LasySnapping::runMaxflow() { const float INFINNITE_MAX = 1e10; int indexPt = 0; for(int h = 0; h < image->height; h ++){ unsigned char* p = (unsigned char*)image->imageData + h *image->widthStep; for(int w = 0; w < image->width; w ++){ // calculate energe E1 float e1[2]={0}; if(isPtInVector(cvPoint(w,h),forePts)){ e1[0] =0; e1[1] = INFINNITE_MAX; }else if(isPtInVector(cvPoint(w,h),backPts)){ e1[0] = INFINNITE_MAX; e1[1] = 0; }else { getE1(p,e1); } // add node graph->add_node(); graph->add_tweights(indexPt, e1[0],e1[1]); // add edge, 4-connect if(h > 0 && w > 0){ float e2 = getE2(p,p-3); graph->add_edge(indexPt,indexPt-1,e2,e2); e2 = getE2(p,p-image->widthStep); graph->add_edge(indexPt,indexPt-image->width,e2,e2); } p+= 3; indexPt ++; } } return graph->maxflow(); }
int main(int argc, char* argv[]) { // Check arguments if (argc < 2) { std::cerr << "Usage: " << argv[0] << " NODES_FILE TETS_FILE\n"; exit(1); } // Construct a Graph typedef Graph<int> GraphType; GraphType graph; std::vector<GraphType::node_type> nodes; // Create a nodes_file from the first input argument std::ifstream nodes_file(argv[1]); // Interprit each line of the nodes_file as a 3D Point and add to the Graph Point p; while (CS207::getline_parsed(nodes_file, p)) nodes.push_back(graph.add_node(p)); // Create a tets_file from the second input argument std::ifstream tets_file(argv[2]); // Interprit each line of the tets_file as four ints which refer to nodes std::array<int,4> t; while (CS207::getline_parsed(tets_file, t)) for (unsigned i = 1; i < t.size(); ++i) for (unsigned j = 0; j < i; ++j) graph.add_edge(nodes[t[i]], nodes[t[j]]); // Print out the stats std::cout << graph.num_nodes() << " " << graph.num_edges() << std::endl; // Launch the SDLViewer CS207::SDLViewer viewer; viewer.launch(); // Use shortest_path_lengths to set the node values to the path lengths // Construct a Color functor and view with the SDLViewer auto node_map = viewer.empty_node_map(graph); int distance = shortest_path_lengths(graph, {-1,0,1}); viewer.add_nodes(graph.node_begin(), graph.node_end(), Color(distance), node_map); viewer.add_edges(graph.edge_begin(), graph.edge_end(), node_map); return 0; }
Totals yagi_time_add_edge() { GraphType g; start_deadman(2); while (!had_alarm && g.num_vertices()<MAX_VERTICES) g.add_vertex(); start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && g.num_edges()<MAX_EDGES) { typename GraphType::VertexDescriptor v1 = yagi_random_vertex(g); typename GraphType::VertexDescriptor v2 = yagi_random_vertex(g); g.add_edge(v1, v2); } t.stop(); return report("add edge", yagi_size(g), g.num_edges(), t, "edges/s"); }
void MaxFlowMinCut::draw_edges_image_data(GraphType &G, uchar *image, int w, int h, int x1, int y1, int x2, int y2, double *sigmas, double dist) { if (x2 >= 0 && x2 < w && y2 >= 0 && y2 < h) { double sigma = sigmas[y1*w+x1]; double ene = 1.0; if (fabs(sigma) > 0.0) ene = exp(-diff(image, x1, y1, x2, y2)/(2*sigma*sigma)); double weight = ene/dist; // double ene = 1.0; // if (fabs(sigma) > 0.0) // ene = exp(-diff(image, x1, y1, x2, y2)/(2*sigma*sigma)); // // double pi4 = 3.1415926535/4; // double num = dist*dist*pi4*ene; // // double imgx, imgy; // imgx = imgy = 0; // if (x1 > 0 && x1 < w-1) // imgx = (image[y1*w+(x1+1)]-image[y1*w+(x1-1)]); // if (y1 > 0 && y1 < h-1) // imgy = (image[(y1+1)*w+x1]-image[(y1-1)*w+x1]); // double imgl = sqrt(imgx*imgx+imgy*imgy); // if (fabs(imgl) > 0.0) // { // imgx /= imgl; // imgy /= imgl; // } // double dd = (y2-y1)*imgy + (x2-x1)*imgx; // double den = 2*qPow((ene*dist*dist+(1.0-ene)*dd*dd), 3.0/2.0); // double weight = num/den; G.add_edge(y1*w+x1, y2*w+x2, weight, weight); } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //printf("1\n"); //declare variables mxArray *D, *PairW, *tU, *numPixels, *alpha, *Kin; const mwSize *dimsPairW, *dimsD, *dimsTu; double *alphaPtr, *DPtr, *PairWPtr, *tUPtr, *numPixelsPtr, *KPtr; int dimxPairW, dimyPairW, dimzPairW, dimxD, dimyD, dimxTu, dimyTu; int i,j; //associate inputs //printf("2\n"); D = mxDuplicateArray(prhs[0]); PairW = mxDuplicateArray(prhs[1]); tU = mxDuplicateArray(prhs[2]); numPixels = mxDuplicateArray(prhs[3]); Kin = mxDuplicateArray(prhs[4]); //figure out dimensions //printf("3\n"); dimsPairW = mxGetDimensions(prhs[1]); dimyPairW = (int)dimsPairW[0]; dimxPairW = (int)dimsPairW[1]; dimzPairW = (int)dimsPairW[2]; dimsD = mxGetDimensions(prhs[0]); dimyD = (int)dimsD[0]; dimxD = (int)dimsD[1]; //printf("4\n"); //associate outputs alpha = plhs[0] = mxCreateDoubleMatrix(1,dimxPairW,mxREAL); //printf("5\n"); //associate pointers alphaPtr = mxGetPr(alpha); DPtr = mxGetPr(D); tUPtr = mxGetPr(tU); PairWPtr = mxGetPr(PairW); numPixelsPtr = mxGetPr(numPixels); KPtr = mxGetPr(Kin); double K = (double)KPtr[0]; /* dimsTu = mxGetDimensions(prhs[2]); dimyTu = (int)dimsTu[0]; dimxTu = (int)dimsTu[1]; printf("6 dimxTu=%d, dimyTu=%d\n", dimxTu, dimyTu); */ typedef Graph<double,double,double> GraphType; int numNodes=(int)numPixelsPtr[0]; GraphType *g = new GraphType(/*estimated # of nodes*/ numNodes, /*estimated # of edges*/ 10*numNodes); g->add_node(numNodes); for (i=0;i<dimxPairW;i++) { /* int currTU = (int)tUPtr[i]-1; int currAlpha = (int)alphaInPtr[currTU]; if (currAlpha == 0) g->add_tweights(currTU,DPtr[currTU],0); else if (currAlpha == 1) g->add_tweights(currTU,0,DPtr[currTU]); else { printf("ERROR: currAlpha=%d\n", currAlpha); break; } */ // printf("7: i=%d, p=%d\n", i, (int)tUPtr[i]-1); int curr_tU = (int)tUPtr[i]-1; g->add_tweights(curr_tU,DPtr[2*i+1],DPtr[2*i]); for (j=0;j<dimyPairW;j++) { int xy = j+i*dimyPairW; int matSize = dimxPairW*dimyPairW; if (PairWPtr[xy]==0) continue; else { //printf("8: j=%d, p1=%d p2=%d\n", j, (int)tUPtr[i]-1,(int)PairWPtr[matSize + xy]-1); g->add_edge(curr_tU,(int)PairWPtr[matSize + xy]-1,PairWPtr[xy],PairWPtr[xy]); } } } double flow = g->maxflow(); printf("Flow = %f\n", flow); for (i=0;i<dimxPairW;i++) { //printf("9\n"); if (g->what_segment(i) == GraphType::SOURCE) alphaPtr[i]=0; else if (g->what_segment(i) == GraphType::SINK) alphaPtr[i] = 1; else { printf("ERROR: g->what_segment(i) is neither source nor sink\n"); } } delete g; return; }
void MGraphCut::multipleGraphCutFeatureExtention(MGraph& gph, std::vector<std::vector<unsigned> >& gcFeatures, std::vector<unsigned>& vlb, int& lableId, unsigned int limitCutTimes, double myPolarizedThreshold) { //init subgraph; vlb.clear(); vlb.resize(gph.vNum); //std::vector<int> edgeLable(myMesh->getEdges().size()); std::list<MGraphCut::SubGraph> subgraphs; std::vector<MGraphCut::SGIter> sgIters; lableId = 0; std::vector<bool> visitedVer(gph.vNum, false); std::vector<bool> visitedEdge(gph.eNum, false); for (int i = 0; i < (int)gph.vs.size(); i++){ if (visitedVer[i] == true) continue; MGraphCut::SubGraph tsg; std::vector<unsigned> &tvers = tsg.vers; std::vector<unsigned> &tedges = tsg.edges; //tsg.features.reserve(gcFeatures.size()); std::vector<MGraph::Vertex> frontVer(1, gph.vs[i]); while (!frontVer.empty()){ MGraph::Vertex fv = frontVer.back(); frontVer.pop_back(); vlb[fv.id] = lableId; tvers.push_back(fv.id); std::list<int>::iterator vit = fv.vadjs.begin(); std::list<int>::iterator eit = fv.eadjs.begin(); for (; vit != fv.vadjs.end(); vit++, eit++){ unsigned teid = *eit; if (gph.es[teid].isCut){ //edgeLable[teid]=-1; continue; } if (visitedEdge[teid] == true) continue; visitedEdge[teid] = true; //edgeLable[teid] = lableId; tedges.push_back(teid); int adjv = *vit; if (visitedVer[adjv] == true) continue; visitedVer[adjv] = true; frontVer.push_back(gph.vs[adjv]); } } lableId++; subgraphs.push_back(tsg); } for (MGraphCut::SGIter s_it = subgraphs.begin(); s_it != subgraphs.end(); s_it++) sgIters.push_back(s_it); std::vector<std::vector<unsigned> > sgFeature; for (int i = 0; i < (int)gcFeatures.size(); i++){ std::set<unsigned> tlab; for (int j = 0; j < (int)gcFeatures[i].size(); j++){ if (vlb[gph.es[gcFeatures[i][j]].n1] != vlb[gph.es[gcFeatures[i][j]].n2]){ gcFeatures[i].erase(gcFeatures[i].begin() + j); j--; continue; } tlab.insert(vlb[gph.es[gcFeatures[i][j]].n1]); } if (gcFeatures[i].empty()){ gcFeatures.erase(gcFeatures.begin() + i); i--; } else{ std::vector<unsigned> tfs; for (std::set<unsigned>::iterator sit = tlab.begin(); sit != tlab.end(); ++sit) tfs.push_back(*sit); sgFeature.push_back(tfs); } } for (unsigned i = 0; i < sgFeature.size(); i++){ for (unsigned j = 0; j < sgFeature[i].size(); j++){ sgIters[sgFeature[i][j]]->features.push_back(i); } } //feature cost and reward; std::vector<double> gcFeatureAward(gcFeatures.size(), 0); for (unsigned i = 0; i < gcFeatures.size(); i++){ for (unsigned j = 0; j < gcFeatures[i].size(); j++){ gcFeatureAward[i] += gph.es[gcFeatures[i][j]].award; } } std::cout << "************* graph partition *************" << endl; std::cout << "feature number:" << gcFeatures.size() << endl; std::cout << "feature extension param:" << myPolarizedThreshold << endl; clock_t tstr = clock(); unsigned count = 0; //count how many "graph-cuts". // std::vector<int> vertexMap(vlb.size(), -1); // 0 means a source and 1 means a sink vertex for current round; 2 means a vertex connected with a feature edge std::vector<int> featureFlagMap = vertexMap; // Initialize the eigen solver for linear system Eigen::SparseLU< Eigen::SparseMatrix<double, Eigen::ColMajor>, Eigen::COLAMDOrdering<int> > solver; //iteratively graph cut while (count < limitCutTimes) { //std::cout << "cut " << count << " times" << endl; unsigned fid = std::max_element(gcFeatureAward.begin(), gcFeatureAward.end()) - gcFeatureAward.begin(); if (gcFeatureAward[fid] <= -sm_largeDouble) break; gcFeatureAward[fid] = -sm_largeDouble; std::vector<unsigned> features = gcFeatures[fid]; std::vector<unsigned> sgfs = sgFeature[fid]; sgFeature[fid].clear(); while (!sgfs.empty()) { unsigned sgl = sgfs.back(); sgfs.pop_back(); SGIter s_it = sgIters[sgl]; if (s_it->edges.empty()) continue; //make graph for (int i = 0; i < (int)s_it->vers.size(); i++){ vertexMap[s_it->vers[i]] = i; } GraphType *g = new GraphType(s_it->vers.size(), s_it->edges.size()); g->add_node(s_it->vers.size()); for (int i = 0; i < (int)s_it->edges.size(); i++){ if (gph.es[s_it->edges[i]].isCut) continue; g->add_edge(vertexMap[gph.es[s_it->edges[i]].n1], vertexMap[gph.es[s_it->edges[i]].n2], gph.es[s_it->edges[i]].w, gph.es[s_it->edges[i]].w); } // Do potential feature grouping FeatureEdgeExtention(gph, gcFeatures, features, vertexMap, featureFlagMap, s_it, solver, g, myPolarizedThreshold); double flow = g->maxflow(); count++; //update cut edge; for (int i = 0; i < (int)s_it->edges.size(); i++){ if (g->what_segment(vertexMap[gph.es[s_it->edges[i]].n1]) != g->what_segment(vertexMap[gph.es[s_it->edges[i]].n2])) gph.es[s_it->edges[i]].isCut = true; } for (int i = 0; i < (int)s_it->vers.size(); i++) { vertexMap[s_it->vers[i]] = -1; featureFlagMap[s_it->vers[i]] = -1; } //update subgraph; std::vector<unsigned> newLabel(1, sgl); std::vector<MGraphCut::SubGraph> newSG(1); for (unsigned i = 0; i < s_it->vers.size(); i++) visitedVer[s_it->vers[i]] = false; for (unsigned i = 0; i < s_it->edges.size(); i++) visitedEdge[s_it->edges[i]] = false; unsigned nlid = 0; for (unsigned i = 0; i < s_it->vers.size(); i++){ if (visitedVer[s_it->vers[i]] == true) continue; std::vector<unsigned> &tvers = newSG[nlid].vers; std::vector<unsigned> &tedges = newSG[nlid].edges; newSG[nlid].features.reserve(gcFeatures.size()); std::vector<MGraph::Vertex> frontVer(1, gph.vs[s_it->vers[i]]); while (!frontVer.empty()){ MGraph::Vertex fv = frontVer.back(); frontVer.pop_back(); vlb[fv.id] = newLabel[nlid]; tvers.push_back(fv.id); // for(unsigned i=0;i<fv.vadjs.size();i++){ // unsigned teid=fv.eadjs[i]; std::list<int>::iterator vit = fv.vadjs.begin(); std::list<int>::iterator eit = fv.eadjs.begin(); for (; vit != fv.vadjs.end(); vit++, eit++){ unsigned teid = *eit; if (gph.es[teid].isCut){ //edgeLable[teid]=-1; continue; } if (visitedEdge[teid] == true) continue; visitedEdge[teid] = true; //edgeLable[teid] = newLabel[nlid]; tedges.push_back(teid); // int adjv=fv.vadjs[i]; int adjv = *vit; if (visitedVer[adjv] == true) continue; visitedVer[adjv] = true; frontVer.push_back(gph.vs[adjv]); } } nlid++; newLabel.push_back(lableId); lableId++; newSG.push_back(SubGraph()); } newLabel.pop_back(); newSG.pop_back(); lableId--; for (int i = 0; i < (int)s_it->features.size(); i++){ if (s_it->features[i] == fid) continue; if (sgFeature[s_it->features[i]].empty()) continue; unsigned lpos = std::find(sgFeature[s_it->features[i]].begin(), sgFeature[s_it->features[i]].end(), sgl) - sgFeature[s_it->features[i]].begin(); if (lpos < sgFeature[s_it->features[i]].size()) sgFeature[s_it->features[i]].erase(sgFeature[s_it->features[i]].begin() + lpos); std::set<unsigned> tlab; for (int j = 0; j < (int)gcFeatures[s_it->features[i]].size(); j++){ if (vlb[gph.es[gcFeatures[s_it->features[i]][j]].n1] != vlb[gph.es[gcFeatures[s_it->features[i]][j]].n2]){ gcFeatures[s_it->features[i]].erase(gcFeatures[s_it->features[i]].begin() + j); j--; continue; } //if(vlb[ets[gcFeatures[s_it->features[i]][j]]->vertex_iter(0)->id()] == newLabel[0] || vlb[ets[gcFeatures[s_it->features[i]][j]]->vertex_iter(0)->id()] == newLabel[1]) tlab.insert(vlb[gph.es[gcFeatures[s_it->features[i]][j]].n1]); } if (!tlab.empty()){ for (std::set<unsigned>::iterator sit = tlab.begin(); sit != tlab.end(); ++sit){ for (unsigned j = 0; j < newLabel.size(); j++){ if (*sit == newLabel[j]){ newSG[j].features.push_back(s_it->features[i]); sgFeature[s_it->features[i]].push_back(newLabel[j]); break; } } } } else{ } } s_it->vers = newSG[0].vers; s_it->edges = newSG[0].edges; s_it->features = newSG[0].features; for (unsigned i = 1; i < newSG.size(); i++){ subgraphs.push_back(newSG[i]); s_it = subgraphs.end(); s_it--; sgIters.push_back(s_it); } delete g; } } std::cout << endl << "run graph cut " << count << " times"; clock_t totalTime = clock() - tstr; std::cout << " and uses " << totalTime / 1000 << "sec" << totalTime % 1000 << "mm" << endl; }
void MGraphCut::multipleGraphCut(MGraph& gph, std::vector<std::vector<unsigned> >& gcFeatures, std::vector<unsigned>& vlb, int& labelId, unsigned int limitCutTimes) { //init subgraph; vlb.clear();vlb.resize(gph.vNum); //std::vector<int> edgeLabel(myMesh->getEdges().size()); std::list<MGraphCut::SubGraph> subgraphs; std::vector<MGraphCut::SGIter> sgIters; labelId=0; std::vector<bool> visitedVer(gph.vNum,false); std::vector<bool> visitedEdge(gph.eNum,false); for (int i = 0; i<(int)gph.vs.size(); i++){ if(visitedVer[i]==true) continue; MGraphCut::SubGraph tsg; std::vector<unsigned> &tvers = tsg.vers; std::vector<unsigned> &tedges = tsg.edges; //tsg.features.reserve(gcFeatures.size()); std::vector<MGraph::Vertex> frontVer(1,gph.vs[i]); while(!frontVer.empty()){ MGraph::Vertex fv = frontVer.back(); frontVer.pop_back(); vlb[fv.id]=labelId; tvers.push_back(fv.id); std::list<int>::iterator vit = fv.vadjs.begin(); std::list<int>::iterator eit = fv.eadjs.begin(); for(;vit != fv.vadjs.end();vit++,eit++){ unsigned teid=*eit; if(gph.es[teid].isCut){ //edgeLabel[teid]=-1; continue; } if(visitedEdge[teid]==true) continue; visitedEdge[teid]=true; //edgeLabel[teid] = labelId; tedges.push_back(teid); int adjv=*vit; if(visitedVer[adjv]==true) continue; visitedVer[adjv] = true; frontVer.push_back(gph.vs[adjv]); } } labelId++; subgraphs.push_back(tsg); } for(MGraphCut::SGIter s_it=subgraphs.begin();s_it!=subgraphs.end();s_it++) sgIters.push_back(s_it); std::vector<std::vector<unsigned> > sgFeature; for (int i = 0; i<(int)gcFeatures.size(); i++){ std::set<unsigned> tlab; for (int j = 0; j<(int)gcFeatures[i].size(); j++){ if(vlb[gph.es[gcFeatures[i][j]].n1] != vlb[gph.es[gcFeatures[i][j]].n2]){ gcFeatures[i].erase(gcFeatures[i].begin()+j); j--; continue; } tlab.insert(vlb[gph.es[gcFeatures[i][j]].n1]); } if(gcFeatures[i].empty()){ gcFeatures.erase(gcFeatures.begin()+i); i--; } else{ std::vector<unsigned> tfs; for(std::set<unsigned>::iterator sit=tlab.begin(); sit!=tlab.end(); ++sit) tfs.push_back(*sit); sgFeature.push_back(tfs); } } for(unsigned i = 0;i<sgFeature.size();i++){ for(unsigned j=0;j<sgFeature[i].size();j++){ sgIters[sgFeature[i][j]]->features.push_back(i); } } //feature cost and reward; std::vector<double> gcFeatureAward(gcFeatures.size(),0); //assume // if(gcFeaturePriority==0){//min cost // for(unsigned i=0;i<gcFeatures.size();i++){ // for(unsigned j=0;j<gcFeatures[i].size();j++){ // gcFeatureAward[i] -= ets[gcFeatures[i][j]]->cost(); // } // } // } // else if(gcFeaturePriority==1){//max award for(unsigned i=0;i<gcFeatures.size();i++){ for(unsigned j=0;j<gcFeatures[i].size();j++){ gcFeatureAward[i]+= gph.es[gcFeatures[i][j]].award; } } // } // else if(gcFeaturePriority==2){//min cost-award // for(unsigned i=0;i<gcFeatures.size();i++){ // for(unsigned j=0;j<gcFeatures[i].size();j++){ // gcFeatureAward[i] -=edgeWeight[gcFeatures[i][j]]; // } // } // } cout<<"************* graph partition *************"<<endl; cout<<"feature number:"<<gcFeatures.size()<<endl; clock_t tstr = clock(); //run graph cut //important datas: vertexLabel, edgeLabel, subgraphs, labelId, sgFeatures; unsigned count=0; //count how many "graph-cuts". std::vector<int> vertexMap(vlb.size(),-1); // std::vector<bool> visitedVer(gph.vNum,false); // std::vector<bool> visitedEdge(gph.eNum,false); while (count<limitCutTimes){//iteratively graph cut // if(count%10 == 0) cout<<"cut "<<count<<" times"<<endl; unsigned fid = std::max_element(gcFeatureAward.begin(),gcFeatureAward.end()) - gcFeatureAward.begin(); if (gcFeatureAward[fid] <= -sm_largeDouble) break; gcFeatureAward[fid] = -sm_largeDouble; std::vector<unsigned> features = gcFeatures[fid]; std::vector<unsigned> sgfs = sgFeature[fid]; sgFeature[fid].clear(); while(!sgfs.empty()){ unsigned sgl = sgfs.back(); sgfs.pop_back(); SGIter s_it = sgIters[sgl]; if(s_it->edges.empty()) continue; //make graph for (int i = 0; i<(int)s_it->vers.size(); i++){ vertexMap[s_it->vers[i]]=i; } GraphType *g = new GraphType(s_it->vers.size(),s_it->edges.size()); g->add_node(s_it->vers.size()); for (int i = 0; i<(int)s_it->edges.size(); i++){ if(gph.es[s_it->edges[i]].isCut) continue; g->add_edge( vertexMap[ gph.es[s_it->edges[i]].n1], vertexMap[ gph.es[s_it->edges[i]].n2] , gph.es[s_it->edges[i]].w,gph.es[s_it->edges[i]].w ); } for(unsigned i=0;i<features.size();i++){//add source & sink; int vsrc = gph.es[features[i]].n1; int vsin = gph.es[features[i]].n2; if(!gph.es[features[i]].ort){ vsrc = gph.es[features[i]].n2; vsin = gph.es[features[i]].n1; } vsrc = vertexMap[vsrc]; vsin = vertexMap[vsin]; if(vsrc == -1 || vsin == -1) continue; g->add_tweights(vsrc, sm_largeDouble, 0); g->add_tweights(vsin, 0, sm_largeDouble); } double flow = g->maxflow(); count++; //update cut edge; for (int i = 0; i<(int)s_it->edges.size(); i++){ if (g->what_segment(vertexMap[gph.es[s_it->edges[i]].n1]) != g->what_segment(vertexMap[gph.es[s_it->edges[i]].n2])) gph.es[s_it->edges[i]].isCut = true; } for (int i = 0; i<(int)s_it->vers.size(); i++){ vertexMap[s_it->vers[i]]=-1; } //update subgraph; std::vector<unsigned> newLabel(1,sgl); std::vector<MGraphCut::SubGraph> newSG(1); for(unsigned i=0;i<s_it->vers.size();i++) visitedVer[s_it->vers[i]]=false; for(unsigned i=0;i<s_it->edges.size();i++) visitedEdge[s_it->edges[i]]=false; unsigned nlid=0; for(unsigned i=0;i<s_it->vers.size();i++){ if(visitedVer[s_it->vers[i]]==true) continue; std::vector<unsigned> &tvers = newSG[nlid].vers; std::vector<unsigned> &tedges = newSG[nlid].edges; newSG[nlid].features.reserve(gcFeatures.size()); std::vector<MGraph::Vertex> frontVer(1,gph.vs[s_it->vers[i]]); while(!frontVer.empty()){ MGraph::Vertex fv = frontVer.back(); frontVer.pop_back(); vlb[fv.id]=newLabel[nlid]; tvers.push_back(fv.id); // for(unsigned i=0;i<fv.vadjs.size();i++){ // unsigned teid=fv.eadjs[i]; std::list<int>::iterator vit = fv.vadjs.begin(); std::list<int>::iterator eit = fv.eadjs.begin(); for(;vit != fv.vadjs.end();vit++,eit++){ unsigned teid=*eit; if(gph.es[teid].isCut){ //edgeLabel[teid]=-1; continue; } if(visitedEdge[teid]==true) continue; visitedEdge[teid]=true; //edgeLabel[teid] = newLabel[nlid]; tedges.push_back(teid); // int adjv=fv.vadjs[i]; int adjv=*vit; if(visitedVer[adjv]==true) continue; visitedVer[adjv] = true; frontVer.push_back(gph.vs[adjv]); } } nlid++; newLabel.push_back(labelId); labelId++; newSG.push_back(SubGraph()); } newLabel.pop_back(); newSG.pop_back(); labelId--; for (int i = 0; i<(int)s_it->features.size(); i++){ if(s_it->features[i] == fid) continue; if(sgFeature[s_it->features[i]].empty()) continue; unsigned lpos = std::find(sgFeature[s_it->features[i]].begin(),sgFeature[s_it->features[i]].end(),sgl) - sgFeature[s_it->features[i]].begin(); if(lpos < sgFeature[s_it->features[i]].size()) sgFeature[s_it->features[i]].erase(sgFeature[s_it->features[i]].begin()+lpos); std::set<unsigned> tlab; for (int j = 0; j<(int)gcFeatures[s_it->features[i]].size(); j++){ if(vlb[gph.es[gcFeatures[s_it->features[i]][j]].n1] != vlb[gph.es[gcFeatures[s_it->features[i]][j]].n2]){ gcFeatures[s_it->features[i]].erase(gcFeatures[s_it->features[i]].begin()+j); j--; continue; } //if(vlb[ets[gcFeatures[s_it->features[i]][j]]->vertex_iter(0)->id()] == newLabel[0] || vlb[ets[gcFeatures[s_it->features[i]][j]]->vertex_iter(0)->id()] == newLabel[1]) tlab.insert(vlb[gph.es[gcFeatures[s_it->features[i]][j]].n1]); } if(!tlab.empty()){ for(std::set<unsigned>::iterator sit=tlab.begin(); sit!=tlab.end(); ++sit){ for(unsigned j=0;j<newLabel.size();j++){ if(*sit==newLabel[j]){ newSG[j].features.push_back(s_it->features[i]); sgFeature[s_it->features[i]].push_back(newLabel[j]); break; } } } } else{ } } s_it->vers = newSG[0].vers; s_it->edges = newSG[0].edges; s_it->features = newSG[0].features; for(unsigned i=1;i<newSG.size();i++){ subgraphs.push_back(newSG[i]); s_it = subgraphs.end(); s_it--; sgIters.push_back(s_it); } delete g; } } cout<<endl<<"run graph cut "<<count<<" times"; clock_t totalTime=clock()-tstr; cout<<" and uses "<<totalTime/1000<<"sec"<<totalTime%1000<<"mm"<<endl; }
void mexFunction(int nlhs, /* number of expected outputs */ mxArray *plhs[], /* mxArray output pointer array */ int nrhs, /* number of inputs */ const mxArray *prhs[] /* mxArray input pointer array */) { unsigned int nodes; unsigned int pairs; bool *labels; unsigned int *source; unsigned int *destination; float *pairValue; float *unaryValue; float *flow; mxArray *sourceMxArray; mxArray *destinationMxArray; mxArray *pairValueMxArray; /** Input validation */ if( nrhs != 2 ) mexErrMsgTxt( USAGE_NOTIFICATION ); const mxArray *A = prhs[ 0 ]; const mxArray *T = prhs[ 1 ]; if( !mxIsStruct( A ) ) { mexErrMsgTxt( USAGE_NOTIFICATION ); } else { sourceMxArray = mxGetField( A, 0, "source" ); destinationMxArray = mxGetField( A, 0, "destination" ); pairValueMxArray = mxGetField( A, 0, "value" ); if( mxGetClassID( sourceMxArray ) != mxUINT32_CLASS || mxGetClassID( destinationMxArray ) != mxUINT32_CLASS || mxGetClassID( pairValueMxArray ) != mxSINGLE_CLASS ) { mexErrMsgTxt( USAGE_NOTIFICATION ); } if( mxIsComplex( sourceMxArray ) || mxIsComplex( destinationMxArray ) || mxIsComplex( pairValueMxArray ) ) { mexErrMsgTxt( USAGE_NOTIFICATION ); } pairs = mxGetNumberOfElements( sourceMxArray ); if( pairs != mxGetNumberOfElements( destinationMxArray ) || pairs != mxGetNumberOfElements( pairValueMxArray ) ) { mexErrMsgTxt( USAGE_NOTIFICATION ); } } if( mxGetClassID( T ) != mxSINGLE_CLASS ) { mexErrMsgTxt( USAGE_NOTIFICATION ); } else { if( mxIsComplex( T ) ) mexErrMsgTxt( USAGE_NOTIFICATION ); nodes = mxGetM( T ); if( mxGetN( T ) != 2 ) mexErrMsgTxt( USAGE_NOTIFICATION ); } /** End of input validation */ source = ( unsigned int * )mxGetData( sourceMxArray ); destination = ( unsigned int * )mxGetData( destinationMxArray ); pairValue = ( float * )mxGetData( pairValueMxArray ); unaryValue = ( float * )mxGetData( T ); typedef Graph< float, float, float > GraphType; GraphType *graph = new GraphType( nodes, pairs ); graph->add_node( nodes ); /** Add pairwise potentials */ for( int edge = 0; edge < pairs; edge++ ) graph->add_edge( source[ edge ], destination[ edge ], pairValue[ edge ], pairValue[ edge ] ); for( int node = 0; node < nodes; node++ ) graph->add_tweights( node, unaryValue[ node ], unaryValue[ node + nodes ] ); /** Create outputs */ plhs[ 0 ] = mxCreateNumericMatrix( 1, 1, mxSINGLE_CLASS, mxREAL ); plhs[ 1 ] = mxCreateLogicalMatrix( nodes, 1 ); flow = ( float * )mxGetData( plhs[ 0 ] ); labels = ( bool * )mxGetData( plhs[ 1 ] ); *flow = graph->maxflow(); for( int node = 0; node < nodes; node++ ) labels[ node ] = graph->what_segment( node ); delete graph; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //printf("1\n"); //declare variables mxArray *D, *PairW, *tU, *kIn, *alpha; const mwSize *dimsPairW, *dimsD; double *alphaPtr, *DPtr, *PairWPtr, *tUPtr, *kInPtr; int dimxPairW, dimyPairW, dimzPairW, dimxD, dimyD; int i,j; //associate inputs //printf("2\n"); D = mxDuplicateArray(prhs[0]); PairW = mxDuplicateArray(prhs[1]); //tU = mxDuplicateArray(prhs[2]); //kIn = mxDuplicateArray(prhs[3]); //figure out dimensions //printf("3\n"); dimsPairW = mxGetDimensions(prhs[1]); dimyPairW = (int)dimsPairW[0]; dimxPairW = (int)dimsPairW[1]; dimzPairW = (int)dimsPairW[2]; dimsD = mxGetDimensions(prhs[0]); dimyD = (int)dimsD[0]; dimxD = (int)dimsD[1]; //printf("4\n"); //associate outputs alpha = plhs[0] = mxCreateDoubleMatrix(1,dimxPairW,mxREAL); //printf("5\n"); //associate pointers alphaPtr = mxGetPr(alpha); DPtr = mxGetPr(D); PairWPtr = mxGetPr(PairW); //tUPtr = mxGetPr(tU); //kInPtr = mxGetPr(kIn); //printf("6\n"); typedef Graph<double,double,double> GraphType; int numNodes=dimxPairW; GraphType *g = new GraphType(/*estimated # of nodes*/ numNodes, /*estimated # of edges*/ numNodes*6); g->add_node(numNodes); // loop through pixels /* for(i=0;i<dimxPairW;i++) { //mexPrintf("D[0][%d] = %f\n",i,DPtr[i*2]); //mexPrintf("D[1][%d] = %f\n",i,DPtr[i*2+1]); for(j=0;j<dimyPairW;j++) { int xy = j+i*dimyPairW; int matSize = dimxPairW*dimyPairW; //mexPrintf("V[%d][%d][0] = %f\n",j,i,PairWPtr[xy]); mexPrintf("V[%d][%d][1] = %f\n",j,i,PairWPtr[matSize + xy - 1]); } } */ for (i=0;i<dimxPairW;i++) { //if (i % 10000 == 0) //printf("7: %d/%d\n", i, dimxPairW); //if (((int)tUPtr[i])==1) { //printf("7: %d/%d\n", i, dimxPairW); g->add_tweights(i,DPtr[2*i+1],DPtr[2*i]); //} /*else { //printf("7: %d/%d\n", i, dimxPairW); g->add_tweights(i,0,kInPtr[0]); }*/ for (j=0;j<dimyPairW;j++) { int xy = j+i*dimyPairW; int matSize = dimxPairW*dimyPairW; // printf("8: %d/%d\n", j, dimyPairW); if ((int)PairWPtr[matSize + xy]-1<=0) { //printf("8-2\n"); continue; } else { // printf("8-3: i=%d, j=%d, dimyPairW=%d, dimxPairW=%d, dimzPairW=%d, dimxD=%d, dimyD=%d, matSize=%d, xy=%d ---- ", i, j, dimyPairW, dimxPairW, dimzPairW, dimxD, dimyD, matSize, xy); // printf("8-3-2: PairWPtr1=%d, PairWPtr2=%f\n", (int)PairWPtr[matSize + xy]-1, PairWPtr[xy]); g->add_edge(i,(int)PairWPtr[matSize + xy]-1,PairWPtr[xy],PairWPtr[xy]); } } } double flow = g->maxflow(); printf("Flow = %f\n", flow); //printf("9\n"); for (i=0;i<dimxPairW;i++) { //printf("10: %d/%d\n", i, dimxPairW); if (g->what_segment(i) == GraphType::SOURCE) alphaPtr[i]=1; else alphaPtr[i]=0; } delete g; return; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* Check for proper number of arguments */ if (nrhs != 4) { mexErrMsgIdAndTxt("MATLAB:mexmaxflow:nargin", "MEXCPP requires four input arguments."); } else if (nlhs != 1 && nlhs != 2) { mexErrMsgIdAndTxt("MATLAB:mexmaxflow:nargout", "MEXCPP requires one output argument."); } //parse out arguments double *backWeights = (double *) mxGetPr(prhs[0]); double *foreWeights = (double *) mxGetPr(prhs[1]); double *smoothIndices = (double *) mxGetPr(prhs[2]); double *smoothWeights = (double *) mxGetPr(prhs[3]); size_t numNodes = mxGetNumberOfElements(prhs[0]); size_t numDirections = mxGetN(prhs[2]); //Error checking if (numNodes != mxGetNumberOfElements(prhs[1])) mexErrMsgIdAndTxt("MATLAB:mexmaxflow:argin", "Weight arrays must be same length"); if (numNodes != mxGetM(prhs[2])) mexErrMsgIdAndTxt("MATLAB:mexmaxflow:argin", "Number of rows for edge matrix does not match number of nodes"); if (mxGetN(prhs[2]) != mxGetN(prhs[3]) || mxGetM(prhs[2]) != mxGetM(prhs[3])) mexErrMsgIdAndTxt("MATLAB:mexmaxflow:argin", "Edge weights matrix does not match edge indices matrix"); //Create and fill graph typedef Graph<double, double, double> GraphType; GraphType *g = new GraphType(((int)numNodes),((int)(numNodes*numDirections))); g->add_node(((int)numNodes)); //Background is source, foreground is sink for (size_t i=0; i<numNodes; i++) { g->add_tweights(i, backWeights[i], foreWeights[i]); for (size_t j=0; j<numDirections; j++) { //mexPrintf("Value1 = %g\n", smoothIndices[numNodes*j + i]); int edgeIndex = (int)(smoothIndices[numNodes*j + i]-1); double edgeWeight = smoothWeights[numNodes*j + i]; if (edgeIndex < 0) continue; else if (edgeIndex >= numNodes) mexErrMsgIdAndTxt("MATLAB:mexmaxflow:argin", "Illegal edge index"); else if (edgeIndex >= i) continue; g->add_edge(edgeIndex, i, edgeWeight, edgeWeight); } } //Calc flow double energy = g->maxflow(); plhs[0] = mxCreateNumericMatrix(numNodes, 1, mxDOUBLE_CLASS, mxREAL); double* arrPtr = mxGetPr(plhs[0]); //Set alpha for (size_t i=0; i<numNodes; i++) { arrPtr[i] = g->what_segment(i) == GraphType::SINK; } plhs[1] = mxCreateDoubleScalar(energy); delete g; return; }
// ============================================================================= int main(int argc, char** argv) { // Check arguments if (argc < 3) { std::cerr << "Usage: " << argv[0] << " NODES_FILE TETS_FILE\n"; exit(1); } // Construct an empty graph GraphType graph; // Create a nodes_file from the first input argument std::ifstream nodes_file(argv[1]); // Interpret each line of the nodes_file as a 3D Point and add to the Graph Point p; std::vector<typename GraphType::node_type> nodes; while (CME212::getline_parsed(nodes_file, p)) nodes.push_back(graph.add_node(p)); // Create a tets_file from the second input argument std::ifstream tets_file(argv[2]); // Interpret each line of the tets_file as four ints which refer to nodes std::array<int,4> t; while (CME212::getline_parsed(tets_file, t)) { graph.add_edge(nodes[t[0]], nodes[t[1]]); graph.add_edge(nodes[t[0]], nodes[t[2]]); #if 1 // Diagonal edges graph.add_edge(nodes[t[0]], nodes[t[3]]); graph.add_edge(nodes[t[1]], nodes[t[2]]); #endif graph.add_edge(nodes[t[1]], nodes[t[3]]); graph.add_edge(nodes[t[2]], nodes[t[3]]); } // Set initial velocity and mass for (GraphType::NodeIterator it = graph.node_begin(); it != graph.node_end(); ++it) { Node n = *it; n.value().vel = Point(0,0,0); // Initial velocity == 0 n.value().mass = 1.0 / graph.num_nodes(); // graph has total mass == 1, constant density } // Set rest length for all of the Edges to their initial length for (GraphType::EdgeIterator ei = graph.edge_begin(); ei != graph.edge_end(); ++ei ) { (*ei).value().L = (*ei).length(); } // Print out the stats std::cout << graph.num_nodes() << " " << graph.num_edges() << std::endl; // Launch the SDLViewer CME212::SDLViewer viewer; auto node_map = viewer.empty_node_map(graph); viewer.launch(); viewer.add_nodes(graph.node_begin(), graph.node_end(), node_map); viewer.add_edges(graph.edge_begin(), graph.edge_end(), node_map); viewer.center_view(); // Begin the mass-spring simulation double dt = 0.001; double t_start = 0; double t_end = 5.0; for (double t = t_start; t < t_end; t += dt) { // P1 --------------------------------------------------------------------- // symp_euler_step(graph, t, dt, Problem1Force()); // P3 ---------------------------------------------------------------------- //symp_euler_step(graph, t, dt, cf); // Create individual forces GravityForce g(grav); MassSpringForce msf(100); DampingForce d(1.0 / graph.num_nodes()); // Combine the individual forces auto cf = make_combined_force(g, msf, d); // P4 ---------------------------------------------------------------------- // Create individual constraints HPlane hp(-0.75); Sphere sp(0.15, Point(0.5,0.5,-0.5)); SphereRemove sr(0.15, Point(0.5,0.5,-0.5)); // Combined individual constraints // P4.1 // auto c = make_combined_constraint(hp, FixedConstraint()); // P4.2 // auto c = make_combined_constraint(sp, FixedConstraint()); // P4.3 auto c = make_combined_constraint(sr, FixedConstraint()); // Mixed constraints // auto c = make_combined_constraint(hp, sr, FixedConstraint()); // auto c = make_combined_constraint(hp, sp, FixedConstraint()); symp_euler_step(graph, t, dt, cf, c); viewer.clear(); node_map.clear(); viewer.add_nodes(graph.node_begin(), graph.node_end(), node_map); viewer.add_edges(graph.edge_begin(), graph.edge_end(), node_map); // Update viewer with nodes' new positions viewer.add_nodes(graph.node_begin(), graph.node_end(), node_map); viewer.set_label(t); // These lines slow down the animation for small graphs, like grid0_*. // Feel free to remove them or tweak the constants. if (graph.size() < 100) CME212::sleep(0.0001); } return 0; }
void mexFunction(int nOut, mxArray *pOut[], int nIn, const mxArray *pIn[]) { clock_t mexBegin = tic(); const char *usage = "[energy, xmap, misc] = submodularMAPFull_mex(theta, pW, pots).\n" " Solve MAP problem with overcomplete parameterization.\n" " theta is nNodes x 2, first column is 0 potential, second is 1.\n" " W is nNodes x nNodes sparse *indexing* a potential in pots, 1-based.\n" " pots is nPots cell array, each 2x2.\n"; if (nIn != 3) { mexErrMsgIdAndTxt("submodularMAP_mex:args", usage); } ///////////////////////////////////////////////// // Extract arguments and outputs ///////////////////////////////////////////////// Mat<double> theta (pIn[0]); cscMatrix W = extractCSC(pIn[1]); CellMat<Mat<double> > pots(pIn[2]); int nNodes = theta.M; mwSize nEdges = W.nzMax / 2; // symmetric mat int nPots = pots.length; auto misc = StructMat(1, 1, {"maxFlow", "mexTotTime"}); pOut[oMisc] = misc; std::vector<int> x(nNodes); typedef Graph<double,double,double> GraphType; GraphType *g = new GraphType(nNodes, nEdges + 2 * nNodes); g->add_node(nNodes); // Pairwise are normal (bidirectional) edges. mwIndex i, off; // Potential idx int pidx; double w; // Use Kolmogorov's submodular construction, Kolmogorov04 pp. 151 // is there a cache-friendlier way to write this? does it even matter? std::vector<double> sAug(nNodes); std::vector<double> tAug(nNodes); for (mwIndex j = 0; j < nNodes; j++) { for (mwIndex wIdx = W.jc[j]; wIdx < W.jc[j+1]; wIdx++) { // Upper triangular only i = W.ir[wIdx]; // some dirty trickery since we represent an int as a double. if (j > i) { if (pidx >= 0 && pidx < nPots) { pidx = W.pr[wIdx] - 1; // We may have weird numerical issues. if (pidx >= 0 && pidx < nPots) { sAug[i] += pots[pidx](1,0) - pots[pidx](0,0); // C - A tAug[j] += pots[pidx](1,0) - pots[pidx](1,1); // C - D w = pots[pidx](0,1) + pots[pidx](1,0) - pots[pidx](0,0) - pots[pidx](1,1); // B + C - A - D g->add_edge(i, j, w, 0); mexPrintf("%d->%d = %g\n", i, j, w); } } } } } double dTheta; double s; double t; for (int j = 0; j < nNodes; j++) { dTheta = theta(j,1) - theta(j,0); s = MAX(0, dTheta) + sAug[j]; t = MAX(0, -dTheta) + tAug[j]; g->add_tweights(j, s, t); mexPrintf("s->%d = %g\t; %d->t = %g\t; sAug = %g\t; tAug = %g\n", j, s, j, t, sAug[j], tAug[j]); } double maxFlow = g->maxflow(); for (int i = 0; i < nNodes; i++) { x[i] = g->what_segment(i) == GraphType::SINK; //mexPrintf("x[%d] = %d, ws = %d\n", i, x[i], g->what_segment(i)); } misc.set("maxFlow", scalar<double>(maxFlow)); // Compute final energies double energy = 0.0; for (mwIndex j = 0; j < nNodes; j++) { energy += theta(j,x[j]); for (mwIndex wIdx = W.jc[j]; wIdx < W.jc[j+1]; wIdx++) { // Upper triangular only i = W.ir[wIdx]; if (j > i) { if (pidx >= 0 && pidx < nPots) { pidx = W.pr[wIdx] - 1; energy += pots[pidx](x[i],x[j]); } } } } pOut[oX] = Mat<int>(x); pOut[oEnergy] = scalar<double>(energy); delete g; misc.set("mexTotTime", scalar<double>(toc(mexBegin))); }
void mexFunction(int nlhs, /* number of expected outputs */ mxArray *plhs[], /* mxArray output pointer array */ int nrhs, /* number of inputs */ const mxArray *prhs[] /* mxArray input pointer array */) { // input checks if (nrhs != 2 || !mxIsSparse(prhs[0]) || !mxIsSparse(prhs[1])) { mexErrMsgTxt ("USAGE: [flow,labels] = maxflowmex(A,T)"); } const mxArray *A = prhs[0]; const mxArray *T = prhs[1]; if (mxIsComplex(A) || mxIsComplex(T)) { mexErrMsgTxt ("Complex entries are not supported!"); } // fetch its dimensions // actually, we must have m=n mwSize m = mxGetM(A); mwSize n = mxGetN(A); mwSize nzmax = mxGetNzmax(A); if (m != n) { mexErrMsgTxt ("Matrix A should be square!"); } if (n != mxGetM(T) || mxGetN(T) != 2) { mexErrMsgTxt ("T should be of size Nx2"); } // sparse matrices have a different storage convention from that of full matrices in MATLAB. // The parameters pr and pi are still arrays of double-precision numbers, but these arrays // contain only nonzero data elements. There are three additional parameters: nzmax, ir, and jc. // nzmax - is an integer that contains the length of ir, pr, and, if it exists, pi. It is the maximum // possible number of nonzero elements in the sparse matrix. // ir - points to an integer array of length nzmax containing the row indices of the corresponding // elements in pr and pi. // jc - points to an integer array of length n+1, where n is the number of columns in the sparse matrix. // The jc array contains column index information. If the jth column of the sparse matrix has any nonzero // elements, jc[j] is the index in ir and pr (and pi if it exists) of the first nonzero element in the jth // column, and jc[j+1] - 1 is the index of the last nonzero element in that column. For the jth column of // the sparse matrix, jc[j] is the total number of nonzero elements in all preceding columns. The last // element of the jc array, jc[n], is equal to nnz, the number of nonzero elements in the entire sparse matrix. // If nnz is less than nzmax, more nonzero entries can be inserted into the array without allocating additional // storage. double *pr = mxGetPr(A); mwIndex *ir = mxGetIr(A); mwIndex *jc = mxGetJc(A); // create graph typedef Graph<float,float,float> GraphType; // estimations for number of nodes and edges - we know these exactly! GraphType *g = new GraphType(/*estimated # of nodes*/ n, /*estimated # of edges*/ jc[n]); // add the nodes // NOTE: their indices are 0-based g->add_node(n); // traverse the adjacency matrix and add n-links unsigned int i, j, k; float v; for (j = 0; j < n; j++) { // this is a simple check whether there are non zero // entries in the j'th column if (jc[j] == jc[j+1]) { continue; // nothing in this column } for (k = jc[j]; k <= jc[j+1]-1; k++) { i = ir[k]; v = (float)pr[k]; //mexPrintf("non zero entry: (%d,%d) = %.2f\n", i+1, j+1, v); g->add_edge(i, j, v, 0.0f); } } // traverse the terminal matrix and add t-links pr = mxGetPr(T); ir = mxGetIr(T); jc = mxGetJc(T); for (j = 0; j <= 1; j++) { if (jc[j] == jc[j+1]) { continue; } for (k = jc[j]; k <= jc[j+1]-1; k++) { i = ir[k]; v = (float)pr[k]; if (j == 0) // source weight { g->add_tweights(i, v, 0.0f); } else if (j == 1) // sink weight { g->add_tweights(i, 0.0f, v); } } } plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); double* flow = mxGetPr(plhs[0]); *flow = g->maxflow(); // figure out segmentation plhs[1] = mxCreateNumericMatrix(n, 1, mxINT32_CLASS, mxREAL); int* labels = (int*)mxGetData(plhs[1]); for (i = 0; i < n; i++) { labels[i] = g->what_segment(i); } // cleanup delete g; }
//--> finds the most optimal path across the polar Edge map! void findTheCut(double* imgEdge_in, const int width_in, const int height_in, unsigned char* fgMap_out) { // Global static variable get assigned! width = width_in; height = height_in; //Create a Graph with number of nodes typedef Graph<float,float,float> GraphType; GraphType *g = new GraphType(/*estimated # of nodes*/ width*height, /*estimated # of edges*/ 2*width*height); //Create Node Id array GraphType::node_id** node=new GraphType::node_id*[height]; for(int i = 0; i < height; i++){ node[i]=new GraphType::node_id[width]; for(int j = 0; j < width; j++){ node[i][j] = g->add_node(); } } //Set the data costs terms for each pixel and each label for(int i = 0; i < height; i++){ for(int j = 0; j < width; j++){ if ( j==0 ){ g->add_tweights(node[i][j],100.0,0); } else if (j > width-10){ g->add_tweights(node[i][j],0,100.0); } else{ g->add_tweights(node[i][j],0,0); } } } // Set the neighboring pixels! for(int i = 0; i < height; i++){ for(int j = 0; j < width; j++){ int pixelQ; for(int k = 0; k < 2; k=k+1) for(int l = 0; l < 2; l=l+1){ if (k==l) continue; else if (i+k == height && j+l >= 0 && j+l < width){ pixelQ = (j+l); // nodes in the first row double cost; //printf("\n pair (%d,%d )",pixelP,pixelQ); FindB(imgEdge_in, i, j, 0, j+l, &cost); // cost of assigning different labels g->add_edge(node[i][j],node[0][j+l],(float)cost,(float)cost); } else if (i+k >= 0 && i+k < height && j+l >= 0 && j+l < width){ pixelQ = (i+k)*width+(j+l); double cost; //printf("\n pair (%d,%d )",pixelP,pixelQ); FindB(imgEdge_in,i,j,i+k,j+l, &cost); // cost of assigning different labels g->add_edge(node[i][j],node[i+k][j+l],(float)cost,(float)cost); } } } } g->maxflow(); // calculate maxFlow // label "0" is the source, also foreground! for(int i = 0; i < height; i++) for(int j = 0; j < width; j++) *(fgMap_out + width*i + j) = g->what_segment(node[i][j]) == 0 ? 255 : 0; //DONE. Now, release the memory! for(int i=0;i<height;i++) delete []node[i]; delete []node; delete g; }