Example #1
0
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;
}
Example #2
0
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];
				}
			
	}
}