3 #include "GCoptimization.h"
\r
4 #include "GraphCut.h"
\r
9 // define A64BITS for compiling on a 64 bits machine...
\r
12 * Matlab wrapper for Weksler graph cut implementation
\r
15 * [gch] = GraphCut3dConstr(R, C, Z, num_labels, DataCost, SmoothnessCost, [Contrast])
\r
17 * Note that data types are crucials!
\r
20 * R, C, Z - size of 3D grid.
\r
21 * num_labels - number of labels.
\r
22 * DataCost - of type float, array size [width*height*depth*#labels], the data term for pixel
\r
23 * x,y,z recieving label l is stroed at [(x+y*width+z*width*depth)*#labels + l]
\r
24 * SmoothnessCost - of type float, array size [#labels.^2] the cost between l1 and l2 is
\r
25 * stored at [l1+l2*#labels] = Vpq(lp,lq)
\r
26 * Contrast - of type float, array size[width*height*depth], the weight Wpq will be determined by the contrast:
\r
27 * Wpq = exp(-|C(p)-C(q)|)
\r
30 * gch - of type int32, graph cut handle - do NOT mess with it!
\r
33 int nlhs, /* number of expected outputs */
\r
34 mxArray *plhs[], /* mxArray output pointer array */
\r
35 int nrhs, /* number of inputs */
\r
36 const mxArray *prhs[] /* mxArray input pointer array */
\r
41 Graph::captype *DataCost;
\r
42 Graph::captype *SmoothnessCost;
\r
43 Graph::captype *Contrast = NULL;
\r
44 GCoptimization::LabelType *Labels;
\r
45 GCoptimization::PixelType R, C, Z;
\r
47 GCoptimization *MyGraph = NULL;
\r
49 /* check number of inout arguments - must be 6 */
\r
50 if ((nrhs != 6)&&(nrhs!=7)) {
\r
51 mexErrMsgIdAndTxt("GraphCut:NarginError","Wrong number of input argumnets");
\r
53 GetScalar(prhs[0], R);
\r
54 GetScalar(prhs[1], C);
\r
55 GetScalar(prhs[2], Z);
\r
56 GetScalar(prhs[3], num_labels);
\r
59 /* check second input DataCost: must have #labels*height*width elements of type float */
\r
60 if ( mxGetNumberOfElements(prhs[4]) != num_labels*R*C*Z ) {
\r
61 mexErrMsgIdAndTxt("GraphCut:DataCost",
\r
62 "DataCost argument does not contains the right number of elements");
\r
64 if (mxGetClassID(prhs[4]) != mxSINGLE_CLASS ) {
\r
65 mexErrMsgIdAndTxt("GraphCut:DataCost",
\r
66 "DataCost argument is not of type float");
\r
68 DataCost = (Graph::captype*)mxGetData(prhs[4]);
\r
70 /* check fifth input SmoothnessCost: must have #labels.^2 elements of type float */
\r
71 if ( mxGetNumberOfElements(prhs[5]) != num_labels*num_labels ) {
\r
72 mexErrMsgIdAndTxt("GraphCut:SmoothnessCost",
\r
73 "SmoothnessCost argument does not contains the right number of elements");
\r
75 if (mxGetClassID(prhs[5]) != mxSINGLE_CLASS ) {
\r
76 mexErrMsgIdAndTxt("GraphCut:SmoothnessCost",
\r
77 "SmoothnessCost argument is not of type float");
\r
79 SmoothnessCost = (Graph::captype*)mxGetData(prhs[5]);
\r
82 /* add Contrast cue */
\r
83 if ( mxGetNumberOfElements(prhs[6]) != R*C*Z ) {
\r
84 mexErrMsgIdAndTxt("GraphCut:SmoothnessCost",
\r
85 "Contrast argument does not contains the right number of elements");
\r
87 if (mxGetClassID(prhs[6]) != mxSINGLE_CLASS ) {
\r
88 mexErrMsgIdAndTxt("GraphCut:SmoothnessCost",
\r
89 "Contrast argument is not of type float");
\r
91 Contrast = (Graph::captype*)mxGetData(prhs[6]);
\r
94 /* prepare the output argument */
\r
96 mexErrMsgIdAndTxt("GraphCut:OutputArg","Wrong number of output arguments");
\r
99 MyGraph = new GCoptimization(R*C*Z, num_labels, SET_ALL_AT_ONCE, SET_ALL_AT_ONCE);
\r
100 /* neighborhod setup */
\r
101 GCoptimization::PixelType c(0), r(0), z(0), p(0), q(0);
\r
103 for ( r = 0 ; r <= R - 2; r++ ) {
\r
104 for ( c = 0 ; c <= C - 2; c++ ) {
\r
105 for ( z = 0 ; z <= Z - 2; z++ ) {
\r
106 /* all nodes with 3 nieghbors */
\r
109 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
110 q = r+(c+1)*R+z*R*C;
\r
111 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
112 q = r+c*R+(z+1)*R*C;
\r
113 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
115 /* top of Z has 2 n in c and r */
\r
118 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
119 q = r+(c+1)*R+z*R*C;
\r
120 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
122 /* end of c has 2 n in z and r */
\r
123 for ( z = 0 ; z <= Z -2 ; z++ ) {
\r
126 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
127 q = r+c*R+(z+1)*R*C;
\r
128 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
130 /* end of c abd z has n in r */
\r
133 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
135 /* end of r has n in z and c */
\r
136 for ( c = 0 ; c <= C - 2; c++ ) {
\r
137 for ( z = 0 ; z <= Z - 2; z++ ) {
\r
139 q = r+c*R+(z+1)*R*C;
\r
140 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
141 q = r+(c+1)*R+z*R*C;
\r
142 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
145 q = r+(c+1)*R+z*R*C;
\r
146 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
148 for ( z = 0 ; z <= Z - 2; z++ ) {
\r
150 q = r+c*R+(z+1)*R*C;
\r
151 MyGraph->setNeighbors(p, q, exp(-fabs(Contrast[p]-Contrast[q])));
\r
153 /* end of graph construction with contrast */
\r
155 for ( r = 0 ; r <= R - 2; r++ ) {
\r
156 for ( c = 0 ; c <= C - 2; c++ ) {
\r
157 for ( z = 0 ; z <= Z - 2; z++ ) {
\r
158 /* all nodes with 3 nieghbors */
\r
159 MyGraph->setNeighbors(r+c*R+z*R*C,r+1+c*R+z*R*C);
\r
160 MyGraph->setNeighbors(r+c*R+z*R*C,r+(c+1)*R+z*R*C);
\r
161 MyGraph->setNeighbors(r+c*R+z*R*C,r+c*R+(z+1)*R*C);
\r
163 /* top of Z has 2 n in c and r */
\r
164 MyGraph->setNeighbors(r+c*R+z*R*C,r+1+c*R+z*R*C);
\r
165 MyGraph->setNeighbors(r+c*R+z*R*C,r+(c+1)*R+z*R*C);
\r
167 /* end of c has 2 n in z and r */
\r
168 for ( z = 0 ; z <= Z -2 ; z++ ) {
\r
169 MyGraph->setNeighbors(r+c*R+z*R*C,r+1+c*R+z*R*C);
\r
170 MyGraph->setNeighbors(r+c*R+z*R*C,r+c*R+(z+1)*R*C);
\r
172 /* end of c abd z has n in r */
\r
173 MyGraph->setNeighbors(r+c*R+z*R*C,r+1+c*R+z*R*C);
\r
175 /* end of r has n in z and c */
\r
176 for ( c = 0 ; c <= C - 2; c++ ) {
\r
177 for ( z = 0 ; z <= Z - 2; z++ ) {
\r
178 MyGraph->setNeighbors(r+c*R+z*R*C,r+c*R+(z+1)*R*C);
\r
179 MyGraph->setNeighbors(r+c*R+z*R*C,r+(c+1)*R+z*R*C);
\r
181 MyGraph->setNeighbors(r+c*R+z*R*C,r+(c+1)*R+z*R*C);
\r
183 for ( z = 0 ; z <= Z - 2; z++ ) {
\r
184 MyGraph->setNeighbors(r+c*R+z*R*C,r+c*R+(z+1)*R*C);
\r
187 MyGraph->setData(DataCost);
\r
188 /* if ( vCue != NULL && vCue != NULL )
\r
189 MyGraph->setSmoothness(SmoothnessCost, hCue, vCue);
\r
191 MyGraph->setSmoothness(SmoothnessCost);
\r
194 /* create a container for the pointer */
\r
195 plhs[0] = mxCreateNumericMatrix(1, 1, MATLAB_POINTER_TYPE, mxREAL);
\r
198 gh = (GraphHandle*) mxGetData(plhs[0]);
\r
199 *gh = (GraphHandle)(MyGraph);
\r