example.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. //////////////////////////////////////////////////////////////////////////////
  2. // Example illustrating the use of GCoptimization.cpp
  3. //
  4. /////////////////////////////////////////////////////////////////////////////
  5. //
  6. // Optimization problem:
  7. // is a set of sites (pixels) of width 10 and hight 5. Thus number of pixels is 50
  8. // grid neighborhood: each pixel has its left, right, up, and bottom pixels as neighbors
  9. // 7 labels
  10. // Data costs: D(pixel,label) = 0 if pixel < 25 and label = 0
  11. // : D(pixel,label) = 10 if pixel < 25 and label is not 0
  12. // : D(pixel,label) = 0 if pixel >= 25 and label = 5
  13. // : D(pixel,label) = 10 if pixel >= 25 and label is not 5
  14. // Smoothness costs: V(p1,p2,l1,l2) = min( (l1-l2)*(l1-l2) , 4 )
  15. // Below in the main program, we illustrate different ways of setting data and smoothness costs
  16. // that our interface allow and solve this optimizaiton problem
  17. // For most of the examples, we use no spatially varying pixel dependent terms.
  18. // For some examples, to demonstrate spatially varying terms we use
  19. // V(p1,p2,l1,l2) = w_{p1,p2}*[min((l1-l2)*(l1-l2),4)], with
  20. // w_{p1,p2} = p1+p2 if |p1-p2| == 1 and w_{p1,p2} = p1*p2 if |p1-p2| is not 1
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <math.h>
  24. #include <string.h>
  25. #include <time.h>
  26. #include "GCoptimization.h"
  27. using namespace OBJREC;
  28. struct ForDataFn {
  29. int numLab;
  30. Graph::captype *data;
  31. };
  32. Graph::captype smoothFn(int p1, int p2, int l1, int l2)
  33. {
  34. if ( (l1 - l2)*(l1 - l2) <= 4 ) return((l1 -l2)*(l1 - l2));
  35. else return(4);
  36. }
  37. Graph::captype dataFn(int p, int l, void *data)
  38. {
  39. ForDataFn *myData = (ForDataFn *) data;
  40. int numLab = myData->numLab;
  41. return( myData->data[p*numLab+l] );
  42. }
  43. ////////////////////////////////////////////////////////////////////////////////
  44. // smoothness and data costs are set up one by one, individually
  45. // grid neighborhood structure is assumed
  46. //
  47. void GridGraph_Individually(int width, int height, int num_pixels, int num_labels)
  48. {
  49. int *result = new int[num_pixels]; // stores result of optimization
  50. try {
  51. GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width, height, num_labels);
  52. // first set up data costs individually
  53. for ( int i = 0; i < num_pixels; i++ )
  54. for (int l = 0; l < num_labels; l++ )
  55. if (i < 25 ) {
  56. if ( l == 0 ) gc->setDataCost(i, l, 0);
  57. else gc->setDataCost(i, l, 10);
  58. }
  59. else {
  60. if ( l == 5 ) gc->setDataCost(i, l, 0);
  61. else gc->setDataCost(i, l, 10);
  62. }
  63. // next set up smoothness costs individually
  64. for ( int l1 = 0; l1 < num_labels; l1++ )
  65. for (int l2 = 0; l2 < num_labels; l2++ ) {
  66. int cost = (l1 - l2) * (l1 - l2) <= 4 ? (l1 - l2) * (l1 - l2) : 4;
  67. gc->setSmoothCost(l1, l2, cost);
  68. }
  69. printf("\nBefore optimization energy is %d", gc->compute_energy());
  70. gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
  71. printf("\nAfter optimization energy is %d", gc->compute_energy());
  72. for ( int i = 0; i < num_pixels; i++ )
  73. result[i] = gc->whatLabel(i);
  74. delete gc;
  75. }
  76. catch (GCException e) {
  77. e.Report();
  78. }
  79. delete [] result;
  80. }
  81. ////////////////////////////////////////////////////////////////////////////////
  82. // in this version, set data and smoothness terms using arrays
  83. // grid neighborhood structure is assumed
  84. //
  85. void GridGraph_DArraySArray(int width, int height, int num_pixels, int num_labels)
  86. {
  87. int *result = new int[num_pixels]; // stores result of optimization
  88. // first set up the array for data costs
  89. Graph::captype *data = new Graph::captype[num_pixels*num_labels];
  90. for ( int i = 0; i < num_pixels; i++ )
  91. for (int l = 0; l < num_labels; l++ )
  92. if (i < 25 ) {
  93. if ( l == 0 ) data[i*num_labels+l] = 0;
  94. else data[i*num_labels+l] = 10;
  95. }
  96. else {
  97. if ( l == 5 ) data[i*num_labels+l] = 0;
  98. else data[i*num_labels+l] = 10;
  99. }
  100. // next set up the array for smooth costs
  101. Graph::captype *smooth = new Graph::captype[num_labels*num_labels];
  102. for ( int l1 = 0; l1 < num_labels; l1++ )
  103. for (int l2 = 0; l2 < num_labels; l2++ )
  104. smooth[l1+l2*num_labels] = (l1 - l2) * (l1 - l2) <= 4 ? (l1 - l2) * (l1 - l2) : 4;
  105. try {
  106. GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width, height, num_labels);
  107. gc->setDataCost(data);
  108. gc->setSmoothCost(smooth);
  109. printf("\nBefore optimization energy is %d", gc->compute_energy());
  110. gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
  111. printf("\nAfter optimization energy is %d", gc->compute_energy());
  112. for ( int i = 0; i < num_pixels; i++ )
  113. result[i] = gc->whatLabel(i);
  114. delete gc;
  115. }
  116. catch (GCException e) {
  117. e.Report();
  118. }
  119. delete [] result;
  120. delete [] smooth;
  121. delete [] data;
  122. }
  123. ////////////////////////////////////////////////////////////////////////////////
  124. // in this version, set data and smoothness terms using arrays
  125. // grid neighborhood structure is assumed
  126. //
  127. void GridGraph_DfnSfn(int width, int height, int num_pixels, int num_labels)
  128. {
  129. int *result = new int[num_pixels]; // stores result of optimization
  130. // first set up the array for data costs
  131. Graph::captype *data = new Graph::captype[num_pixels*num_labels];
  132. for ( int i = 0; i < num_pixels; i++ )
  133. for (int l = 0; l < num_labels; l++ )
  134. if (i < 25 ) {
  135. if ( l == 0 ) data[i*num_labels+l] = 0;
  136. else data[i*num_labels+l] = 10;
  137. }
  138. else {
  139. if ( l == 5 ) data[i*num_labels+l] = 0;
  140. else data[i*num_labels+l] = 10;
  141. }
  142. try {
  143. GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width, height, num_labels);
  144. // set up the needed data to pass to function for the data costs
  145. ForDataFn toFn;
  146. toFn.data = data;
  147. toFn.numLab = num_labels;
  148. gc->setDataCost(&dataFn, &toFn);
  149. // smoothness comes from function pointer
  150. gc->setSmoothCost(&smoothFn);
  151. printf("\nBefore optimization energy is %d", gc->compute_energy());
  152. gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
  153. printf("\nAfter optimization energy is %d", gc->compute_energy());
  154. for ( int i = 0; i < num_pixels; i++ )
  155. result[i] = gc->whatLabel(i);
  156. delete gc;
  157. }
  158. catch (GCException e) {
  159. e.Report();
  160. }
  161. delete [] result;
  162. delete [] data;
  163. }
  164. ////////////////////////////////////////////////////////////////////////////////
  165. // Uses spatially varying smoothness terms. That is
  166. // V(p1,p2,l1,l2) = w_{p1,p2}*[min((l1-l2)*(l1-l2),4)], with
  167. // w_{p1,p2} = p1+p2 if |p1-p2| == 1 and w_{p1,p2} = p1*p2 if |p1-p2| is not 1
  168. void GridGraph_DArraySArraySpatVarying(int width, int height, int num_pixels, int num_labels)
  169. {
  170. int *result = new int[num_pixels]; // stores result of optimization
  171. // first set up the array for data costs
  172. Graph::captype *data = new Graph::captype[num_pixels*num_labels];
  173. for ( int i = 0; i < num_pixels; i++ )
  174. for (int l = 0; l < num_labels; l++ )
  175. if (i < 25 ) {
  176. if ( l == 0 ) data[i*num_labels+l] = 0;
  177. else data[i*num_labels+l] = 10;
  178. }
  179. else {
  180. if ( l == 5 ) data[i*num_labels+l] = 0;
  181. else data[i*num_labels+l] = 10;
  182. }
  183. // next set up the array for smooth costs
  184. Graph::captype *smooth = new Graph::captype[num_labels*num_labels];
  185. for ( int l1 = 0; l1 < num_labels; l1++ )
  186. for (int l2 = 0; l2 < num_labels; l2++ )
  187. smooth[l1+l2*num_labels] = (l1 - l2) * (l1 - l2) <= 4 ? (l1 - l2) * (l1 - l2) : 4;
  188. // next set up spatially varying arrays V and H
  189. Graph::captype *V = new Graph::captype[num_pixels];
  190. Graph::captype *H = new Graph::captype[num_pixels];
  191. for ( int i = 0; i < num_pixels; i++ ) {
  192. H[i] = i + (i + 1) % 3;
  193. V[i] = i * (i + width) % 7;
  194. }
  195. try {
  196. GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width, height, num_labels);
  197. gc->setDataCost(data);
  198. gc->setSmoothCostVH(smooth, V, H);
  199. printf("\nBefore optimization energy is %d", gc->compute_energy());
  200. gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
  201. printf("\nAfter optimization energy is %d", gc->compute_energy());
  202. for ( int i = 0; i < num_pixels; i++ )
  203. result[i] = gc->whatLabel(i);
  204. delete gc;
  205. }
  206. catch (GCException e) {
  207. e.Report();
  208. }
  209. delete [] result;
  210. delete [] smooth;
  211. delete [] data;
  212. }
  213. ////////////////////////////////////////////////////////////////////////////////
  214. // in this version, set data and smoothness terms using arrays
  215. // grid neighborhood is set up "manually"
  216. //
  217. void GeneralGraph_DArraySArray(int width, int height, int num_pixels, int num_labels)
  218. {
  219. int *result = new int[num_pixels]; // stores result of optimization
  220. // first set up the array for data costs
  221. Graph::captype *data = new Graph::captype[num_pixels*num_labels];
  222. for ( int i = 0; i < num_pixels; i++ )
  223. for (int l = 0; l < num_labels; l++ )
  224. if (i < 25 ) {
  225. if ( l == 0 ) data[i*num_labels+l] = 0;
  226. else data[i*num_labels+l] = 10;
  227. }
  228. else {
  229. if ( l == 5 ) data[i*num_labels+l] = 0;
  230. else data[i*num_labels+l] = 10;
  231. }
  232. // next set up the array for smooth costs
  233. Graph::captype *smooth = new Graph::captype[num_labels*num_labels];
  234. for ( int l1 = 0; l1 < num_labels; l1++ )
  235. for (int l2 = 0; l2 < num_labels; l2++ )
  236. smooth[l1+l2*num_labels] = (l1 - l2) * (l1 - l2) <= 4 ? (l1 - l2) * (l1 - l2) : 4;
  237. try {
  238. GCoptimizationGeneralGraph *gc = new GCoptimizationGeneralGraph(num_pixels, num_labels);
  239. gc->setDataCost(data);
  240. gc->setSmoothCost(smooth);
  241. // now set up a grid neighborhood system
  242. // first set up horizontal neighbors
  243. for (int y = 0; y < height; y++ )
  244. for (int x = 1; x < width; x++ )
  245. gc->setNeighbors(x + y*width, x - 1 + y*width);
  246. // next set up vertical neighbors
  247. for (int y = 1; y < height; y++ )
  248. for (int x = 0; x < width; x++ )
  249. gc->setNeighbors(x + y*width, x + (y - 1)*width);
  250. printf("\nBefore optimization energy is %d", gc->compute_energy());
  251. gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
  252. printf("\nAfter optimization energy is %d", gc->compute_energy());
  253. for ( int i = 0; i < num_pixels; i++ )
  254. result[i] = gc->whatLabel(i);
  255. delete gc;
  256. }
  257. catch (GCException e) {
  258. e.Report();
  259. }
  260. delete [] result;
  261. delete [] smooth;
  262. delete [] data;
  263. }
  264. ////////////////////////////////////////////////////////////////////////////////
  265. // in this version, set data and smoothness terms using arrays
  266. // grid neighborhood is set up "manually". Uses spatially varying terms. Namely
  267. // V(p1,p2,l1,l2) = w_{p1,p2}*[min((l1-l2)*(l1-l2),4)], with
  268. // w_{p1,p2} = p1+p2 if |p1-p2| == 1 and w_{p1,p2} = p1*p2 if |p1-p2| is not 1
  269. void GeneralGraph_DArraySArraySpatVarying(int width, int height, int num_pixels, int num_labels)
  270. {
  271. int *result = new int[num_pixels]; // stores result of optimization
  272. // first set up the array for data costs
  273. Graph::captype *data = new Graph::captype[num_pixels*num_labels];
  274. for ( int i = 0; i < num_pixels; i++ )
  275. for (int l = 0; l < num_labels; l++ )
  276. if (i < 25 ) {
  277. if ( l == 0 ) data[i*num_labels+l] = 0;
  278. else data[i*num_labels+l] = 10;
  279. }
  280. else {
  281. if ( l == 5 ) data[i*num_labels+l] = 0;
  282. else data[i*num_labels+l] = 10;
  283. }
  284. // next set up the array for smooth costs
  285. Graph::captype *smooth = new Graph::captype[num_labels*num_labels];
  286. for ( int l1 = 0; l1 < num_labels; l1++ )
  287. for (int l2 = 0; l2 < num_labels; l2++ )
  288. smooth[l1+l2*num_labels] = (l1 - l2) * (l1 - l2) <= 4 ? (l1 - l2) * (l1 - l2) : 4;
  289. try {
  290. GCoptimizationGeneralGraph *gc = new GCoptimizationGeneralGraph(num_pixels, num_labels);
  291. gc->setDataCost(data);
  292. gc->setSmoothCost(smooth);
  293. // now set up a grid neighborhood system
  294. // first set up horizontal neighbors
  295. for (int y = 0; y < height; y++ )
  296. for (int x = 1; x < width; x++ ) {
  297. int p1 = x - 1 + y * width;
  298. int p2 = x + y * width;
  299. gc->setNeighbors(p1, p2, p1 + p2);
  300. }
  301. // next set up vertical neighbors
  302. for (int y = 1; y < height; y++ )
  303. for (int x = 0; x < width; x++ ) {
  304. int p1 = x + (y - 1) * width;
  305. int p2 = x + y * width;
  306. gc->setNeighbors(p1, p2, p1*p2);
  307. }
  308. printf("\nBefore optimization energy is %d", gc->compute_energy());
  309. gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
  310. printf("\nAfter optimization energy is %d", gc->compute_energy());
  311. for ( int i = 0; i < num_pixels; i++ )
  312. result[i] = gc->whatLabel(i);
  313. delete gc;
  314. }
  315. catch (GCException e) {
  316. e.Report();
  317. }
  318. delete [] result;
  319. delete [] smooth;
  320. delete [] data;
  321. }
  322. ////////////////////////////////////////////////////////////////////////////////
  323. int main(int argc, char **argv)
  324. {
  325. int width = 10;
  326. int height = 5;
  327. int num_pixels = width * height;
  328. int num_labels = 7;
  329. // smoothness and data costs are set up one by one, individually
  330. GridGraph_Individually(width, height, num_pixels, num_labels);
  331. // smoothness and data costs are set up using arrays
  332. GridGraph_DArraySArray(width, height, num_pixels, num_labels);
  333. // smoothness and data costs are set up using functions
  334. GridGraph_DfnSfn(width, height, num_pixels, num_labels);
  335. // smoothness and data costs are set up using arrays.
  336. // spatially varying terms are present
  337. GridGraph_DArraySArraySpatVarying(width, height, num_pixels, num_labels);
  338. //Will pretend our graph is
  339. //general, and set up a neighborhood system
  340. // which actually is a grid
  341. GeneralGraph_DArraySArray(width, height, num_pixels, num_labels);
  342. //Will pretend our graph is general, and set up a neighborhood system
  343. // which actually is a grid. Also uses spatially varying terms
  344. GeneralGraph_DArraySArraySpatVarying(width, height, num_pixels, num_labels);
  345. printf("\n Finished %d (%d) clock per sec %d", clock() / CLOCKS_PER_SEC, clock(), CLOCKS_PER_SEC);
  346. return 0;
  347. }
  348. /////////////////////////////////////////////////////////////////////////////////