void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { MATLAB_ASSERT( nrhs == 2, "graphCutMex: Wrong number of input parameters: expected 2"); MATLAB_ASSERT( nlhs <= 2, "graphCutMex: Too many output arguments: expected 2 or less"); //Fix input parameter order: const mxArray *uInPtr = (nrhs >= 1) ? prhs[0] : NULL; //unary const mxArray *pInPtr = (nrhs >= 2) ? prhs[1] : NULL; //pairwise //Fix output parameter order: mxArray **cOutPtr = (nlhs >= 1) ? &plhs[0] : NULL; //cut mxArray **lOutPtr = (nlhs >= 2) ? &plhs[1] : NULL; //labels //node number int numNodes; // get unary potentials MATLAB_ASSERT(mxGetNumberOfDimensions(uInPtr) == 2, "graphCutMex: The first paramater is not 2-dimensional"); MATLAB_ASSERT(mxGetClassID(uInPtr) == MATLAB_ENERGYTERM_TYPE, "graphCutMex: Unary potentials are of wrong type"); MATLAB_ASSERT(mxGetPi(uInPtr) == NULL, "graphCutMex: Unary potentials should not be complex"); numNodes = mxGetM(uInPtr); MATLAB_ASSERT(numNodes >= 1, "graphCutMex: The number of nodes is not positive"); MATLAB_ASSERT(mxGetN(uInPtr) == 2, "graphCutMex: The first paramater is not of size #nodes x 2"); EnergyTermType* termW = (EnergyTermType*)mxGetData(uInPtr); //get pairwise potentials MATLAB_ASSERT(mxGetNumberOfDimensions(pInPtr) == 2, "graphCutMex: The second paramater is not 2-dimensional"); mwSize numEdges = mxGetM(pInPtr); MATLAB_ASSERT( mxGetN(pInPtr) == 4, "graphCutMex: The second paramater is not of size #edges x 4"); MATLAB_ASSERT(mxGetClassID(pInPtr) == MATLAB_ENERGYTERM_TYPE, "graphCutMex: Pairwise potentials are of wrong type"); EnergyTermType* edges = (EnergyTermType*)mxGetData(pInPtr); for(int i = 0; i < numEdges; i++) { MATLAB_ASSERT(1 <= round(edges[i]) && round(edges[i]) <= numNodes, "graphCutMex: error in pairwise terms array: wrong vertex index"); MATLAB_ASSERT(isInteger(edges[i]), "graphCutMex: error in pairwise terms array: wrong vertex index"); MATLAB_ASSERT(1 <= round(edges[i + numEdges]) && round(edges[i + numEdges]) <= numNodes, "graphCutMex: error in pairwise terms array: wrong vertex index"); MATLAB_ASSERT(isInteger(edges[i + numEdges]), "graphCutMex: error in pairwise terms array: wrong vertex index"); MATLAB_ASSERT(edges[i + 2 * numEdges] + edges[i + 3 * numEdges] >= 0, "graphCutMex: error in pairwise terms array: nonsubmodular edge"); } // start computing if (nlhs == 0){ return; } //prepare graph GraphType *g = new GraphType( numNodes, numEdges); for(int i = 0; i < numNodes; i++) { g -> add_node(); g -> add_tweights( i, termW[i], termW[numNodes + i]); } for(int i = 0; i < numEdges; i++) if(edges[i] < 1 || edges[i] > numNodes || edges[numEdges + i] < 1 || edges[numEdges + i] > numNodes || edges[i] == edges[numEdges + i] || !isInteger(edges[i]) || !isInteger(edges[numEdges + i])){ mexWarnMsgIdAndTxt("graphCutMex:pairwisePotentials", "Some edge has invalid vertex numbers and therefore it is ignored"); } else if(edges[2 * numEdges + i] + edges[3 * numEdges + i] < 0){ mexWarnMsgIdAndTxt("graphCutMex:pairwisePotentials", "Some edge is non-submodular and therefore it is ignored"); } else { if (edges[2 * numEdges + i] >= 0 && edges[3 * numEdges + i] >= 0) g -> add_edge((GraphType::node_id)round(edges[i] - 1), (GraphType::node_id)round(edges[numEdges + i] - 1), edges[2 * numEdges + i], edges[3 * numEdges + i]); else if (edges[2 * numEdges + i] <= 0 && edges[3 * numEdges + i] >= 0) { g -> add_edge((GraphType::node_id)round(edges[i] - 1), (GraphType::node_id)round(edges[numEdges + i] - 1), 0, edges[3 * numEdges + i] + edges[2 * numEdges + i]); g -> add_tweights((GraphType::node_id)round(edges[i] - 1), 0, edges[2 * numEdges + i]); g -> add_tweights((GraphType::node_id)round(edges[numEdges + i] - 1),0 , -edges[2 * numEdges + i]); } else if (edges[2 * numEdges + i] >= 0 && edges[3 * numEdges + i] <= 0) { g -> add_edge((GraphType::node_id)round(edges[i] - 1), (GraphType::node_id)round(edges[numEdges + i] - 1), edges[3 * numEdges + i] + edges[2 * numEdges + i], 0); g -> add_tweights((GraphType::node_id)round(edges[i] - 1),0 , -edges[3 * numEdges + i]); g -> add_tweights((GraphType::node_id)round(edges[numEdges + i] - 1), 0, edges[3 * numEdges + i]); } else mexWarnMsgIdAndTxt("graphCutMex:pairwisePotentials", "Something strange with an edge and therefore it is ignored"); } //compute flow EnergyType flow = g -> maxflow(); //output minimum value if (cOutPtr != NULL){ *cOutPtr = mxCreateNumericMatrix(1, 1, MATLAB_ENERGY_TYPE, mxREAL); *(EnergyType*)mxGetData(*cOutPtr) = (EnergyType)flow; } //output minimum cut if (lOutPtr != NULL){ *lOutPtr = mxCreateNumericMatrix(numNodes, 1, MATLAB_LABEL_TYPE, mxREAL); LabelType* segment = (LabelType*)mxGetData(*lOutPtr); for(int i = 0; i < numNodes; i++) segment[i] = g -> what_segment(i); } delete g; }
BKInstanceMap::mapped_type& sGetBKInstance(int id) { BKInstanceMap::iterator it = gInstanceMap.find(id); MATLAB_ASSERT(it != gInstanceMap.end(), "Invalid handle; no such bkptimization object"); return it->second; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { MATLAB_ASSERT( nrhs == 2, "computeMinMarginalsBinaryMex: Wrong number of input parameters: expected 2"); MATLAB_ASSERT( nlhs <= 2, "computeMinMarginalsBinaryMex: Too many output arguments: expected 2 or less"); //Fix input parameter order: const mxArray *uInPtr = (nrhs >= 1) ? prhs[0] : NULL; //unary const mxArray *pInPtr = (nrhs >= 2) ? prhs[1] : NULL; //pairwise //Fix output parameter order: mxArray **valuesOutPtr = (nlhs >= 1) ? &plhs[0] : NULL; // min-marginal values mxArray **argsOutPtr = (nlhs >= 2) ? &plhs[1] : NULL; // min-marginal args //node number mwSize numNodes; // get unary potentials MATLAB_ASSERT(mxGetNumberOfDimensions(uInPtr) == 2, "computeMinMarginalsBinaryMex: The unary paramater is not 2-dimensional"); MATLAB_ASSERT(mxGetClassID(uInPtr) == mxDOUBLE_CLASS, "computeMinMarginalsBinaryMex: Unary potentials are of wrong type"); MATLAB_ASSERT(mxGetPi(uInPtr) == NULL, "computeMinMarginalsBinaryMex: Unary potentials should not be complex"); numNodes = mxGetM(uInPtr); MATLAB_ASSERT(numNodes >= 1, "computeMinMarginalsBinaryMex: The number of nodes is not positive"); MATLAB_ASSERT(mxGetN(uInPtr) == NUM_LABELS, "computeMinMarginalsBinaryMex: The edge paramater is not of size #nodes x 2"); double* termW = (double*)mxGetData(uInPtr); //get pairwise potentials MATLAB_ASSERT(mxGetNumberOfDimensions(pInPtr) == 2, "computeMinMarginalsBinaryMex: The edge paramater is not 2-dimensional"); mwSize numEdges = mxGetM(pInPtr); MATLAB_ASSERT( mxGetN(pInPtr) == 6, "computeMinMarginalsBinaryMex: The edge paramater is not of size #edges x 6"); MATLAB_ASSERT(mxGetClassID(pInPtr) == mxDOUBLE_CLASS, "computeMinMarginalsBinaryMex: Pairwise potentials are of wrong type"); double* edges = (double*)mxGetData(pInPtr); for(mwSize iEdge = 0; iEdge < numEdges; ++iEdge) { MATLAB_ASSERT(1 <= round(edges[iEdge]) && round(edges[iEdge]) <= numNodes, "computeMinMarginalsBinaryMex: node index out of bounds, should be in 1,...,numNodes"); MATLAB_ASSERT(isInteger(edges[iEdge]), "computeMinMarginalsBinaryMex: non-integer node index"); MATLAB_ASSERT(1 <= round(edges[iEdge + numEdges]) && round(edges[iEdge + numEdges]) <= numNodes, "computeMinMarginalsBinaryMex: node index out of bounds, should be in 1,...,numNodes"); MATLAB_ASSERT(isInteger(edges[iEdge + numEdges]), "computeMinMarginalsBinaryMex: non-integer node index"); } // start computing if (nlhs == 0){ return; } const int numLabels = NUM_LABELS; std::vector< std::vector<double> > minMarginalValues(numNodes, std::vector<double> ( numLabels, DBL_MAX )); std::vector< std::vector< std::vector<int> > > minMarginalArgs(numNodes, std::vector< std::vector<int> > ( numLabels, std::vector<int>(numNodes, 0) ) ); computeMinMarginalsBinaryPairwiseBruteForce(numNodes, numEdges, termW, edges, minMarginalValues, minMarginalArgs ); // output the values of the min-marginals if (valuesOutPtr != NULL){ *valuesOutPtr = mxCreateNumericMatrix(numNodes, numLabels, mxDOUBLE_CLASS, mxREAL); double* values = (double*)mxGetData(*valuesOutPtr); for(mwSize iNode = 0; iNode < numNodes; ++iNode) for(mwSize iLabel = 0; iLabel < numLabels; ++iLabel) { values[iNode + iLabel * numNodes] = minMarginalValues[iNode][iLabel]; } } // output the arguments of the min-marginals if (argsOutPtr != NULL){ mwSize numDims = 3; mwSize dims[3] = { numNodes, numLabels, numNodes }; *argsOutPtr = mxCreateNumericArray(numDims, dims, mxDOUBLE_CLASS, mxREAL); double* args = (double*)mxGetData(*argsOutPtr); for(mwSize iNode = 0; iNode < numNodes; ++iNode) for(mwSize iLabel = 0; iLabel < numLabels; ++iLabel) for(mwSize jNode = 0; jNode < numNodes; ++jNode) { args[ iNode + iLabel * numNodes + jNode * numLabels * numNodes ] = minMarginalArgs[iNode][iLabel][jNode]; } } }