SMIL  1.0.4
GeoCutsAlgo_impl_T.hpp
1 #ifndef GEOCUTSALGO_IMPL_T_HPP
2 #define GEOCUTSALGO_IMPL_T_HPP
3 #include <morphee/selement/include/selementNeighborList.hpp>
4 #include <morphee/selement/include/private/selementNeighborhood_T.hpp>
5 #include <morphee/image/include/private/image_T.hpp>
6 #include <morphee/image/include/imageUtils.hpp>
7 
8 #include <boost/config.hpp>
9 #include <boost/utility.hpp> // for boost::tie
10 #include <boost/graph/graph_traits.hpp> // for boost::graph_traits
11 #include <boost/graph/adjacency_list.hpp>
12 #include <boost/graph/graphviz.hpp>
13 #include <boost/graph/prim_minimum_spanning_tree.hpp>
14 #include <boost/graph/dijkstra_shortest_paths.hpp>
15 #include <boost/graph/johnson_all_pairs_shortest.hpp>
16 
17 #include <boost/version.hpp>
18 #if BOOST_VERSION >= 104700
19 #include <boost/graph/boykov_kolmogorov_max_flow.hpp>
20 #elif BOOST_VERSION >= 103500
21 #include <boost/graph/kolmogorov_max_flow.hpp>
22 #else
23 #include "../boost_ext/kolmogorov_max_flow.hpp"
24 #endif
25 
26 #include "../boost_ext/kolmogorov_max_flow_min_cost.hpp" // FROM STAWIASKI JAN 2012
27 //#include "../boost_ext/maximum_spanning_tree.hpp"
28 //#include "../boost_ext/boost_compare.hpp" //STAWIASKI JAN2012 commented, why?
29 #include <boost/graph/connected_components.hpp>
30 
31 #include <morphee/image/include/private/image_T.hpp>
32 #include <morphee/image/include/private/imageManipulation_T.hpp>
33 #include <morphee/selement/include/selementNeighborList.hpp>
34 #include <morphee/selement/include/private/selementNeighborhood_T.hpp>
35 #include <morphee/morphoBase/include/private/morphoLabel_T.hpp>
36 #include <morphee/morphoBase/include/private/morphoLabel2_T.hpp>
37 #include <morphee/morphoBase/include/private/morphoGraphs_T.hpp>
38 #include <morphee/morphoBase/include/private/morphoHierarch_T.hpp>
39 #include <morphee/graph/include/private/graphProjection_T.hpp>
40 #include <morphee/graph/include/graph.hpp>
41 //#include <graphs/MorphoGraph/include/Morpho_Graph.hpp>// Required for
42 //t_Order_Edges_Weights
43 #include <graphs/MorphoGraph/include/Morpho_Graph_T.hpp> // Required for t_Order_Edges_Weights
44 
45 #include <vector>
46 
47 // ##################################################
48 // BEGIN FROM STAWIASKI JAN 2012
49 // ##################################################
50 
51 #include <math.h>
52 #define M_PI 3.14159265358979323846
53 #define INFINI_POSITIF std::numeric_limits<double>::max)()
54 #define _SECURE_SCL 0
55 #include <stdio.h>
56 
57 typedef struct {
58  float x;
59  float y;
60  float p;
61 } morceau;
62 
63 typedef std::list<morceau> affine_par_morceaux;
64 
65 // ##################################################
66 // END FROM STAWIASKI JAN 2012
67 // ##################################################
68 //#include <morphee/common/include/commonTypesOperator.hpp>
69 
70 namespace morphee
71 {
72  namespace graphalgo
73  {
74  template <class BoostGraph>
75  const BoostGraph t_CopyGraph(const BoostGraph &graphIn);
76  template <class Graph>
77  RES_C t_LabelConnectedComponent(const Graph &GIn, Graph &Gout);
78  template <class Graph>
79  RES_C t_LabelConnectedComponent(const Graph &GIn, Graph &Gout, int *num);
80  // ##################################################
81  // BEGIN FROM STAWIASKI JAN 2012
82  // ##################################################
83 
84  //
85 
86  template <class ImageWs, class ImageIn, class ImageGrad, typename _alpha1,
87  typename _alpha2, typename _alpha3, class SE, class BoostGraph>
88  RES_C t_TreeReweighting_old(const ImageWs &imWs, const ImageIn &imIn,
89  const ImageGrad &imGrad, BoostGraph &Treein,
90  const _alpha1 alpha1, const _alpha2 alpha2,
91  const _alpha3 alpha3, const SE &nl,
92  BoostGraph &Tree_out)
93  {
94  MORPHEE_ENTER_FUNCTION("t_TreeReweighting");
95 
96  if ((!imWs.isAllocated())) {
97  MORPHEE_REGISTER_ERROR("Not allocated");
98  return RES_NOT_ALLOCATED;
99  }
100 
101  if ((!imIn.isAllocated())) {
102  MORPHEE_REGISTER_ERROR("Not allocated");
103  return RES_NOT_ALLOCATED;
104  }
105 
106  if ((!imGrad.isAllocated())) {
107  MORPHEE_REGISTER_ERROR("Not allocated");
108  return RES_NOT_ALLOCATED;
109  }
110 
111  // common image iterator
112  typename ImageWs::const_iterator it, iend;
113  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
114  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
115  offset_t o0;
116  offset_t o1;
117 
118  typename BoostGraph::EdgeIterator ed_it, ed_end;
119  typename BoostGraph::EdgeIterator ed_it2, ed_end2;
120  typename BoostGraph::EdgeIterator ed_it3, ed_end3;
121  typename BoostGraph::EdgeIterator ed_it4, ed_end4;
122 
123  typename BoostGraph::VertexIterator v_it, v_end;
124 
125  typename BoostGraph::VertexProperty vdata1, vdata2, vdata11, vdata22;
126  typename BoostGraph::VertexProperty label1, label2;
127 
128  bool in1;
129  int numVert = 0;
130  int numEdges = 0;
131  typename BoostGraph::EdgeDescriptor e1, e2;
132  typename BoostGraph::VertexDescriptor vs, vt;
133  typename BoostGraph::EdgeProperty tmp, tmp2, tmp3;
134 
135  std::vector<double> val_edges;
136  std::vector<double> val_edges2;
137  val_edges.push_back(0.0);
138 
139  std::cout << "build Region Adjacency Graph" << std::endl;
140 
141  for (it = imWs.begin(), iend = imWs.end(); it != iend;
142  ++it) // for all pixels in imIn create a vertex
143  {
144  o0 = it.getOffset();
145  int val = imWs.pixelFromOffset(o0);
146 
147  if (val > numVert) {
148  numVert = val;
149  }
150  }
151 
152  std::cout << "Compute mean and quaderror" << std::endl;
153  std::vector<double> mean_values;
154  std::vector<double> number_of_values;
155  std::vector<double> quad_error;
156  std::vector<double> min_gradient_values;
157  std::vector<double> max_gradient_values;
158  std::vector<double> area_values;
159 
160  int **histogram;
161  histogram = new int *[numVert];
162 
163  float *histogram_region1;
164  histogram_region1 = new float[255];
165 
166  float *histogram_region2;
167  histogram_region2 = new float[255];
168 
169  float *cumul_histogram_region1;
170  cumul_histogram_region1 = new float[255];
171 
172  float *cumul_histogram_region2;
173  cumul_histogram_region2 = new float[255];
174 
175  for (int dim_allouee0 = 0; dim_allouee0 < numVert; ++dim_allouee0) {
176  histogram[dim_allouee0] = new int[255];
177  }
178 
179  for (int dim_allouee0 = 0; dim_allouee0 < numVert; ++dim_allouee0) {
180  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
181  histogram[dim_allouee0][dim_allouee1] = 0;
182  }
183  }
184 
186  for (int i = 0; i < numVert; i++) {
187  mean_values.push_back(0);
188  number_of_values.push_back(0);
189  quad_error.push_back(0);
190  min_gradient_values.push_back(1000000000000);
191  max_gradient_values.push_back(0);
192  area_values.push_back(0);
193  }
194 
196  for (it = imWs.begin(), iend = imWs.end(); it != iend;
197  ++it) // for all pixels in imIn create a vertex
198  {
199  o1 = it.getOffset();
200  int val = imWs.pixelFromOffset(o1);
201  double val_image = imIn.pixelFromOffset(o1);
202  double val_gradient = imGrad.pixelFromOffset(o1);
203 
204  mean_values[val - 1] = mean_values[val - 1] + val_image;
205  number_of_values[val - 1] = number_of_values[val - 1] + 1.0;
206 
207  if (val_gradient < min_gradient_values[val - 1])
208  min_gradient_values[val - 1] = val_gradient;
209  if (val_gradient > max_gradient_values[val - 1])
210  max_gradient_values[val - 1] = val_gradient;
211 
212  area_values[val - 1] = area_values[val - 1] + 1;
213  int vald = (int) (val_image);
214  histogram[val - 1][vald] = histogram[val - 1][vald] + 1;
215  }
216 
218  for (int i = 0; i < numVert; i++) {
219  mean_values[i] = mean_values[i] / number_of_values[i];
220  }
221 
223  float max_quad_val = 0.0f;
224  for (it = imWs.begin(), iend = imWs.end(); it != iend;
225  ++it) // for all pixels in imIn create a vertex and an edge
226  {
227  o1 = it.getOffset();
228  int val = imWs.pixelFromOffset(o1);
229  double val_image = imIn.pixelFromOffset(o1);
230 
231  quad_error[val - 1] =
232  (double) quad_error[val - 1] +
233  std::pow(std::abs(val_image - (double) mean_values[val - 1]), 2);
234 
235  if (quad_error[val - 1] > max_quad_val)
236  max_quad_val = quad_error[val - 1];
237  }
238 
239  std::cout << "build Region Adjacency Graph Vertices" << std::endl;
240  std::cout << "number of Vertices:" << numVert << std::endl;
241 
242  // create some temp graphs
243  Tree_out = morphee::graph::CommonGraph32(numVert);
244 
245  BoostGraph Gout = morphee::graph::CommonGraph32(numVert);
246  BoostGraph Gout_t = morphee::graph::CommonGraph32(numVert);
247  BoostGraph Gtemp = morphee::graph::CommonGraph32(numVert);
248 
249  BoostGraph Tree_temp = morphee::graph::CommonGraph32(numVert);
250  BoostGraph Tree_temp2 = morphee::graph::CommonGraph32(numVert);
251 
252  BoostGraph Gclassic = morphee::graph::CommonGraph32(numVert);
253 
254  morphee::morphoBase::t_NeighborhoodGraphFromMosaic(imWs, nl, Gclassic);
255 
256  // project area of regions on the graph nodes
257  ImageWs ImTempSurfaces = imWs.getSame();
258  morphee::morphoBase::t_ImLabelFlatZonesWithArea(imWs, nl, ImTempSurfaces);
259  morphee::graph::t_ProjectMarkersOnGraph(ImTempSurfaces, imWs, Gclassic);
260 
261  morphee::morphoBase::t_ImLabelFlatZonesWithVolume(imWs, imGrad, nl,
262  ImTempSurfaces);
263  morphee::graph::t_ProjectMarkersOnGraph(ImTempSurfaces, imWs, Gout);
264 
265  std::cout << "build Region Adjacency Graph Edges" << std::endl;
266 
267  double volume = 0.0;
268  double local_volume = 0.0;
269  double area_total = 0.0;
270 
272  for (boost::tie(v_it, v_end) = boost::vertices(Gout.getBoostGraph());
273  v_it != v_end; ++v_it) {
274  local_volume =
275  area_values[(int) *v_it] * (max_gradient_values[(int) *v_it] -
276  min_gradient_values[(int) *v_it]);
277 
278  Gout.setVertexData(*v_it, (float) local_volume);
279  volume = volume + (double) local_volume;
280 
281  // Gout.vertexData(*v_it, &vdata1);
282  // volume = volume + (double) vdata1;
283 
284  Gclassic.vertexData(*v_it, &vdata1);
285  area_total = area_total + (double) vdata1;
286  }
287 
289  for (it = imWs.begin(), iend = imWs.end(); it != iend;
290  ++it) // for all pixels in imIn create a vertex and an edge
291  {
292  o1 = it.getOffset();
293  int val = imWs.pixelFromOffset(o1);
294 
295  if (val > 0) {
296  neighb.setCenter(o1);
297 
298  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
299  const offset_t o2 = nit.getOffset();
300  int val2 = imWs.pixelFromOffset(o2);
301 
302  if (o2 > o1 || o1 < o2) {
303  if (val != val2) {
304  boost::tie(e1, in1) =
305  boost::edge(val - 1, val2 - 1, Gout.getBoostGraph());
306  boost::tie(e2, in1) =
307  boost::edge(val - 1, val2 - 1, Gtemp.getBoostGraph());
308 
309  double val3 = imGrad.pixelFromOffset(o1);
310  double val4 = imGrad.pixelFromOffset(o2);
311  double maxi = std::max(val3, val4);
312 
313  if (in1 == 0) {
314  numEdges++;
315  Gout.addEdge(val - 1, val2 - 1, maxi);
316  Gtemp.addEdge(val - 1, val2 - 1, 1);
317  } else {
318  Gout.edgeWeight(e1, &tmp);
319  Gout.setEdgeWeight(e1, tmp + maxi);
320 
321  Gtemp.edgeWeight(e2, &tmp2);
322  Gtemp.setEdgeWeight(e2, tmp2 + 1);
323  }
324  }
325  }
326  }
327  }
328  }
329 
330  std::cout << "number of Edges : " << numEdges << std::endl;
331 
332  Gout_t = t_CopyGraph(Gout);
333  boost::tie(ed_it2, ed_end2) = boost::edges(Gtemp.getBoostGraph());
334  boost::tie(ed_it3, ed_end3) = boost::edges(Gclassic.getBoostGraph());
335  boost::tie(ed_it4, ed_end4) = boost::edges(Gout_t.getBoostGraph());
336  float current_max_value = 0.0f;
337 
338  // Weights the graph Gout with mean gradient value along boundary
339  for (boost::tie(ed_it, ed_end) = boost::edges(Gout.getBoostGraph());
340  ed_it != ed_end, ed_it2 != ed_end2, ed_it3 != ed_end3,
341  ed_it4 != ed_end4;
342  ++ed_it, ++ed_it2, ++ed_it3, ++ed_it4) {
343  Gout.edgeWeight(*ed_it, &tmp); // GRADIENT SUM
344  Gtemp.edgeWeight(*ed_it2, &tmp2); // REGION BOUNDARY LENGTH
345  Gout_t.setEdgeWeight(*ed_it4, ((double) tmp2)); // length
346  }
347 
348  // Gtemp is the min spanning tree of Gclassic weighted with pass-values
349  // Gtemp = morphee::MinimumSpanningTreeFromGraph(Gclassic);
350  // t_AverageLinkageTree(imWs, imGrad, nl, Gtemp) ;
351 
352  Gtemp = t_CopyGraph(Treein);
353 
354  for (boost::tie(ed_it, ed_end) = boost::edges(Gtemp.getBoostGraph());
355  ed_it != ed_end; ++ed_it) {
356  Gtemp.edgeWeight(*ed_it, &tmp); // PASS VALUE
357  val_edges.push_back(tmp);
358  }
359 
360  std::vector<typename BoostGraph::EdgeDescriptor> removed_edges;
361 
362  Tree_out = t_CopyGraph(Gtemp);
363  Tree_temp = t_CopyGraph(Gtemp);
364  Tree_temp2 = t_CopyGraph(Gtemp);
365 
366  // sort edges weights to explore the hierarchy
367  std::cout << "sort" << std::endl;
368  std::sort(val_edges.begin(), val_edges.end(), std::less<double>());
369 
370  double last_edge_value = val_edges.back();
371  double last_analyzed = last_edge_value;
372 
373  while (val_edges.size() > 1) {
374  std::cout << last_edge_value << std::endl;
375 
376  // remove edge of maximal weight
377  for (boost::tie(ed_it, ed_end) = boost::edges(Gtemp.getBoostGraph());
378  ed_it != ed_end; ++ed_it) {
379  Gtemp.edgeWeight(*ed_it, &tmp);
380 
381  if (tmp == last_edge_value) { // check is current max weight
382  vs = Gtemp.edgeSource(*ed_it);
383  vt = Gtemp.edgeTarget(*ed_it);
384  boost::tie(e1, in1) = boost::edge(vs, vt, Gtemp.getBoostGraph());
385  removed_edges.push_back(e1);
386  Tree_temp.removeEdge(vs, vt);
387  }
388  }
389 
390  // label trees
391  t_LabelConnectedComponent(Tree_temp, Tree_temp2);
392 
393  // local variable for mean values and areas of regions
394  float mean_value = 0.0f;
395  float number_of_points = 0.0f;
396  float volume1 = 0.0f;
397  float volume2 = 0.0f;
398 
399  float volume11 = 0.0f;
400  float volume22 = 0.0f;
401 
402  float area1 = 0.0f;
403  float area2 = 0.0f;
404  float quad1 = 0.0f;
405  float quad2 = 0.0f;
406  float mean_val_1 = 0.0f;
407  float mean_val_2 = 0.0f;
408  float nb_val_1 = 0.0f;
409  float nb_val_2 = 0.0f;
410  float mean_value_1 = 0.0f;
411  float mean_value_2 = 0.0f;
412  float number_of_points1 = 0.0f;
413  float number_of_points2 = 0.0f;
414  float dist_histo = 0.0f;
415 
416  // go through removed edges and look caracteristics of regions connected
417  // to it
418  while (removed_edges.size() > 0) {
419  volume1 = 0.0f;
420  volume2 = 0.0f;
421  area1 = 0.0f;
422  area2 = 0.0f;
423  quad1 = 0.0f;
424  quad2 = 0.0f;
425  number_of_points = 0.0f;
426 
427  mean_value_1 = 0.0f;
428  mean_value_2 = 0.0f;
429  number_of_points1 = 0.0f;
430  number_of_points2 = 0.0f;
431 
432  mean_value = 0.0f;
433  mean_val_1 = 0.0f;
434  mean_val_2 = 0.0f;
435  nb_val_1 = 0.0f;
436  nb_val_2 = 0.0f;
437 
438  volume11 = 0.0f;
439  volume22 = 0.0f;
440 
441  dist_histo = 0.0f;
442 
443  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
444  histogram_region1[dim_allouee1] = 0;
445  histogram_region2[dim_allouee1] = 0;
446  cumul_histogram_region1[dim_allouee1] = 0;
447  cumul_histogram_region2[dim_allouee1] = 0;
448  }
449 
450  e1 = removed_edges.back();
451  removed_edges.pop_back();
452 
453  // Get label of the regions
454  Tree_temp2.vertexData(Tree_temp2.edgeSource(e1), &label1);
455  Tree_temp2.vertexData(Tree_temp2.edgeTarget(e1), &label2);
456 
457  boost::tie(ed_it4, ed_end4) = boost::edges(Gout_t.getBoostGraph());
458 
459  for (boost::tie(ed_it, ed_end) = boost::edges(Gout.getBoostGraph());
460  ed_it != ed_end, ed_it4 != ed_end4; ++ed_it, ++ed_it4) {
461  vs = Gout.edgeSource(*ed_it);
462  vt = Gout.edgeTarget(*ed_it);
463 
464  // labels of the regions
465  Tree_temp2.vertexData(vs, &vdata1);
466  Tree_temp2.vertexData(vt, &vdata2);
467 
468  // compute avergage mean gradient along regions
469  if ((vdata1 == label1 && vdata2 == label2) ||
470  (vdata1 == label2 && vdata2 == label1)) {
471  Gout.edgeWeight(*ed_it, &tmp);
472  Gout_t.edgeWeight(*ed_it4, &tmp2);
473 
474  mean_value = mean_value + (float) tmp;
475  number_of_points = number_of_points + (float) tmp2;
476  }
477 
478  // compute avergage mean gradient along regions 1
479  if ((vdata1 == label1 && vdata2 != label1) ||
480  (vdata2 == label1 && vdata1 != label1)) {
481  Gout.edgeWeight(*ed_it, &tmp);
482  Gout_t.edgeWeight(*ed_it4, &tmp2);
483 
484  mean_value_1 = mean_value_1 + (float) tmp;
485  number_of_points1 = number_of_points1 + (float) tmp2;
486  }
487 
488  // compute avergage mean gradient along regions 2
489  if ((vdata1 == label2 && vdata2 != label2) ||
490  (vdata2 == label2 && vdata1 != label2)) {
491  Gout.edgeWeight(*ed_it, &tmp);
492  Gout_t.edgeWeight(*ed_it4, &tmp2);
493 
494  mean_value_2 = mean_value_2 + (float) tmp;
495  number_of_points2 = number_of_points2 + (float) tmp2;
496  }
497  }
498 
499  // copying the properties of each vertex
500  for (boost::tie(v_it, v_end) = boost::vertices(Gout.getBoostGraph());
501  v_it != v_end; ++v_it) {
502  // Get label of the regions
503  Tree_temp2.vertexData(*v_it, &vdata1);
504  Gout.vertexData(*v_it, &vdata11);
505 
506  Tree_out.setVertexData(*v_it, (float) alpha1 * vdata11 +
507  (float) alpha3 *
508  quad_error[(int) *v_it]);
509 
510  // compute area of each regions
511  if (vdata1 == label1) {
512  volume1 =
513  volume1 +
514  (float) vdata11; // NODES OF GOUT ARE WEIGHTED WITH VOLUME
515  Gclassic.vertexData(
516  *v_it, &vdata11); // NODES OF GCLASSIC ARE WEIGHTED WITH AREA
517  area1 = area1 + (float) vdata11;
518  mean_val_1 = mean_val_1 + mean_values[(int) *v_it];
519  nb_val_1 = nb_val_1 + 1.0f;
520 
521  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
522  histogram_region1[dim_allouee1] =
523  histogram_region1[dim_allouee1] +
524  histogram[(int) *v_it][dim_allouee1];
525  }
526  }
527  if (vdata1 == label2) {
528  volume2 =
529  volume2 +
530  (float) vdata11; // NODES OF GOUT ARE WEIGHTED WITH VOLUME
531  Gclassic.vertexData(
532  *v_it, &vdata11); // NODES OF GCLASSIC ARE WEIGHTED WITH AREA
533  area2 = area2 + (float) vdata11;
534  mean_val_2 = mean_val_2 + mean_values[(int) *v_it];
535  nb_val_2 = nb_val_2 + 1.0f;
536 
537  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
538  histogram_region2[dim_allouee1] =
539  histogram_region2[dim_allouee1] +
540  histogram[(int) *v_it][dim_allouee1];
541  }
542  }
543  }
544 
545  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
546  for (int dim_allouee0 = 0; dim_allouee0 <= dim_allouee1;
547  ++dim_allouee0) {
548  cumul_histogram_region1[dim_allouee1] =
549  cumul_histogram_region1[dim_allouee1] +
550  (float) histogram_region1[dim_allouee0] / (float) area1;
551  cumul_histogram_region2[dim_allouee1] =
552  cumul_histogram_region2[dim_allouee1] +
553  (float) histogram_region2[dim_allouee0] / (float) area2;
554  }
555  }
556 
557  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
558  dist_histo =
559  dist_histo + std::pow(cumul_histogram_region1[dim_allouee1] -
560  cumul_histogram_region2[dim_allouee1],
561  2);
562  }
563 
564  // copying the properties of each vertex
565  for (boost::tie(v_it, v_end) = boost::vertices(Gout.getBoostGraph());
566  v_it != v_end; ++v_it) {
567  // Get label of the regions
568  Tree_temp2.vertexData(*v_it, &vdata1);
569 
570  // compute area of each regions
571  if (vdata1 == label1) {
572  quad1 = quad1 +
573  (mean_values[(int) *v_it] - mean_val_1 / nb_val_1) *
574  (mean_values[(int) *v_it] - mean_val_1 / nb_val_1);
575  }
576  if (vdata1 == label2) {
577  quad2 = quad2 +
578  (mean_values[(int) *v_it] - mean_val_2 / nb_val_2) *
579  (mean_values[(int) *v_it] - mean_val_2 / nb_val_2);
580  }
581  }
582 
583  quad1 = quad1 / nb_val_1;
584  quad2 = quad2 / nb_val_2;
585 
586  volume11 = area1 * mean_value_1 / number_of_points1;
587  volume22 = area2 * mean_value_2 / number_of_points2;
588 
589  float probability_volume =
590  (1.0 - std::pow(1.0 - volume11 / ((double) volume), 50) -
591  std::pow(1.0 - volume22 / ((double) volume), 50) +
592  std::pow(1.0 - (volume11 + volume22) / ((double) volume), 50));
593 
594  // float probability_volume = ( 1.0 - std::pow( 1.0 -
595  // volume1/((double) volume) , 20 ) - std::pow( 1.0 -
596  // volume2/((double) volume) , 20 ) + std::pow( 1.0 -
597  // (volume1+volume2)/((double) volume) , 20 ) );
598  float probability_area =
599  (1.0 - std::pow(1.0 - area1 / ((double) area_total), 20) -
600  std::pow(1.0 - area2 / ((double) area_total), 20) +
601  std::pow(1.0 - (area1 + area2) / ((double) area_total), 20));
602  float diff_mean =
603  std::abs((mean_val_2 / nb_val_2) - (mean_val_1 / nb_val_1));
604 
605  probability_volume = std::min(probability_volume, 0.05f);
606  // probability_area = std::min( probability_area , 0.5f ) ;
607 
608  // GET EDGE IN TRee_OUt
609  boost::tie(e2, in1) =
610  boost::edge(Tree_out.edgeSource(e1), Tree_out.edgeTarget(e1),
611  Tree_out.getBoostGraph());
612  float val_gradient_mean_t =
613  std::min(((float) last_edge_value) / (65535.0f), 0.7f);
614 
615  if (number_of_points > 0.0f) {
616  // float value_test = 100000.0f * std::pow(dist_histo,(float)
617  // alpha2) * std::pow( ((float) mean_value/ (float) number_of_points
618  // )/( 65535.0f ) , (float) alpha1 ) * std::pow( probability_volume ,
619  // (float) alpha3 ) ;
620  float value_test = 2000000.0f *
621  std::pow(val_gradient_mean_t, (float) alpha1) *
622  std::pow(probability_volume, (float) alpha3);
623 
624  Tree_out.setEdgeWeight(e2, value_test);
625 
626  if (value_test > current_max_value)
627  current_max_value = value_test;
628 
629  } else {
630  Tree_out.setEdgeWeight(e2, 0.0f);
631  }
632  }
633 
634  while (last_edge_value == last_analyzed) {
635  last_edge_value = val_edges.back();
636  val_edges.pop_back();
637  }
638  last_analyzed = last_edge_value;
639  }
640 
641  std::cout << "current_max_value" << current_max_value << std::endl;
642 
643  for (boost::tie(ed_it, ed_end) = boost::edges(Tree_out.getBoostGraph());
644  ed_it != ed_end; ++ed_it) {
645  Tree_out.edgeWeight(*ed_it, &tmp);
646  float value_test = 65535.0f * std::pow((float) tmp / current_max_value,
647  (float) alpha2);
648  Tree_out.setEdgeWeight(*ed_it, value_test);
649  }
650 
651  std::cout << "alpha2" << alpha2 << std::endl;
652 
653  // morphee::Morpho_Graph::t_Order_Edges_Weights(Tree_out, Tree_temp);
654  // boost::tie(ed_it2, ed_end2)=boost::edges(Tree_temp.getBoostGraph());
655 
656  // for (boost::tie(ed_it, ed_end)=boost::edges(Tree_out.getBoostGraph()) ;
657  // ed_it != ed_end, ed_it2 != ed_end2 ; ++ed_it, ++ed_it2)
658  //{
659  // Tree_temp.edgeWeight(*ed_it2,&tmp);
660  // Tree_out.setEdgeWeight(*ed_it, (float) tmp );
661  //}
662 
663  return RES_OK;
664  }
665 
666  template <class ImageWs, class ImageIn, class ImageGrad, typename _alpha1,
667  typename _alpha2, typename _alpha3, class SE, class BoostGraph>
668  RES_C t_TreeReweighting2(const ImageWs &imWs, const ImageIn &imIn,
669  const ImageGrad &imGrad, BoostGraph &Treein,
670  const _alpha1 alpha1, const _alpha2 alpha2,
671  const _alpha3 alpha3, const SE &nl,
672  BoostGraph &Tree_out)
673  {
674  MORPHEE_ENTER_FUNCTION("t_TreeReweighting");
675 
676  if ((!imWs.isAllocated())) {
677  MORPHEE_REGISTER_ERROR("Not allocated");
678  return RES_NOT_ALLOCATED;
679  }
680 
681  if ((!imIn.isAllocated())) {
682  MORPHEE_REGISTER_ERROR("Not allocated");
683  return RES_NOT_ALLOCATED;
684  }
685 
686  if ((!imGrad.isAllocated())) {
687  MORPHEE_REGISTER_ERROR("Not allocated");
688  return RES_NOT_ALLOCATED;
689  }
690 
691  // common image iterator
692  typename ImageWs::const_iterator it, iend;
693  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
694  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
695  offset_t o0;
696  offset_t o1;
697 
698  typename BoostGraph::EdgeIterator ed_it, ed_end;
699  typename BoostGraph::EdgeIterator ed_it2, ed_end2;
700  typename BoostGraph::EdgeIterator ed_it3, ed_end3;
701  typename BoostGraph::EdgeIterator ed_it4, ed_end4;
702 
703  typename BoostGraph::VertexIterator v_it, v_end;
704 
705  typename BoostGraph::VertexProperty vdata1, vdata2, vdata11, vdata22;
706  typename BoostGraph::VertexProperty label1, label2;
707 
708  bool in1;
709  int numVert = 0;
710  int numEdges = 0;
711  typename BoostGraph::EdgeDescriptor e1, e2;
712  typename BoostGraph::VertexDescriptor vs, vt;
713  typename BoostGraph::EdgeProperty tmp, tmp2, tmp3;
714 
715  std::vector<double> val_edges;
716  std::vector<double> val_edges2;
717  val_edges.push_back(0.0);
718 
719  std::cout << "build Region Adjacency Graph" << std::endl;
720 
721  for (it = imWs.begin(), iend = imWs.end(); it != iend;
722  ++it) // for all pixels in imIn create a vertex
723  {
724  o0 = it.getOffset();
725  int val = imWs.pixelFromOffset(o0);
726 
727  if (val > numVert) {
728  numVert = val;
729  }
730  }
731 
732  std::cout << "Compute mean and quaderror" << std::endl;
733  std::vector<double> mean_values;
734  std::vector<double> number_of_values;
735  std::vector<double> quad_error;
736  std::vector<double> min_gradient_values;
737  std::vector<double> max_gradient_values;
738  std::vector<double> area_values;
739 
740  int **histogram; // image histogram
741  histogram = new int *[numVert];
742 
743  float *histogram_region1; // region 1 histogram
744  histogram_region1 = new float[255];
745 
746  float *histogram_region2; // region 2 histogram
747  histogram_region2 = new float[255];
748 
749  float *cumul_histogram_region1; // cummulated region 1 histogram
750  cumul_histogram_region1 = new float[255];
751 
752  float *cumul_histogram_region2; // cummulated region 2 histogram
753  cumul_histogram_region2 = new float[255];
754 
755  for (int dim_allouee0 = 0; dim_allouee0 < numVert; ++dim_allouee0) {
756  histogram[dim_allouee0] = new int[255];
757  }
758 
759  for (int dim_allouee0 = 0; dim_allouee0 < numVert; ++dim_allouee0) {
760  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
761  histogram[dim_allouee0][dim_allouee1] = 0;
762  }
763  }
764 
766  for (int i = 0; i < numVert; i++) {
767  mean_values.push_back(0);
768  number_of_values.push_back(0);
769  quad_error.push_back(0);
770  min_gradient_values.push_back(1000000000000);
771  max_gradient_values.push_back(0);
772  area_values.push_back(0);
773  }
774 
776  for (it = imWs.begin(), iend = imWs.end(); it != iend;
777  ++it) // for all pixels in imIn create a vertex
778  {
779  o1 = it.getOffset();
780  int val = imWs.pixelFromOffset(o1);
781  double val_image = imIn.pixelFromOffset(o1);
782  double val_gradient = imGrad.pixelFromOffset(o1);
783 
784  mean_values[val - 1] = mean_values[val - 1] + val_image;
785  number_of_values[val - 1] = number_of_values[val - 1] + 1.0;
786 
787  if (val_gradient < min_gradient_values[val - 1])
788  min_gradient_values[val - 1] = val_gradient;
789  if (val_gradient > max_gradient_values[val - 1])
790  max_gradient_values[val - 1] = val_gradient;
791 
792  area_values[val - 1] = area_values[val - 1] + 1;
793  int vald = (int) (val_image);
794  histogram[val - 1][vald] = histogram[val - 1][vald] + 1;
795  }
796 
798  for (int i = 0; i < numVert; i++) {
799  mean_values[i] = mean_values[i] / number_of_values[i];
800  }
801 
803  float max_quad_val = 0.0f;
804  for (it = imWs.begin(), iend = imWs.end(); it != iend;
805  ++it) // for all pixels in imIn create a vertex and an edge
806  {
807  o1 = it.getOffset();
808  int val = imWs.pixelFromOffset(o1);
809  double val_image = imIn.pixelFromOffset(o1);
810 
811  quad_error[val - 1] =
812  (double) quad_error[val - 1] +
813  std::pow(std::abs(val_image - (double) mean_values[val - 1]), 2);
814 
815  if (quad_error[val - 1] > max_quad_val)
816  max_quad_val = quad_error[val - 1];
817  }
818 
819  std::cout << "build Region Adjacency Graph Vertices" << std::endl;
820  std::cout << "number of Vertices:" << numVert << std::endl;
821 
822  // create some temp graphs
823  Tree_out = morphee::graph::CommonGraph32(numVert);
824 
825  BoostGraph Gout = morphee::graph::CommonGraph32(numVert);
826  BoostGraph Gout_t = morphee::graph::CommonGraph32(numVert);
827  BoostGraph Gtemp = morphee::graph::CommonGraph32(numVert);
828 
829  BoostGraph Tree_temp = morphee::graph::CommonGraph32(numVert);
830  BoostGraph Tree_temp2 = morphee::graph::CommonGraph32(numVert);
831 
832  // GRAPH WHOSE NODES ARE WEIGHTED WITH AREA
833  BoostGraph G_area = morphee::graph::CommonGraph32(numVert);
834  morphee::morphoBase::t_NeighborhoodGraphFromMosaic(imWs, nl, G_area);
835 
836  // project area of regions on the graph nodes
837  ImageWs ImTempSurfaces = imWs.getSame();
838  morphee::morphoBase::t_ImLabelFlatZonesWithArea(imWs, nl, ImTempSurfaces);
839  morphee::graph::t_ProjectMarkersOnGraph(ImTempSurfaces, imWs, G_area);
840 
841  // GRAPH WHOSE NODES ARE WEIGHTED WITH VOLUME
842  morphee::morphoBase::t_ImLabelFlatZonesWithVolume(imWs, imGrad, nl,
843  ImTempSurfaces);
844  morphee::graph::t_ProjectMarkersOnGraph(ImTempSurfaces, imWs, Gout);
845 
846  std::cout << "build Region Adjacency Graph Edges" << std::endl;
847 
848  double volume = 0.0;
849  double local_volume = 0.0;
850  double area_total = 0.0;
851 
853  for (boost::tie(v_it, v_end) = boost::vertices(Gout.getBoostGraph());
854  v_it != v_end; ++v_it) {
855  local_volume =
856  area_values[(int) *v_it] * (max_gradient_values[(int) *v_it] -
857  min_gradient_values[(int) *v_it]);
858 
859  Gout.vertexData(*v_it, &vdata1);
860  volume = volume + (double) vdata1;
861 
862  G_area.vertexData(*v_it, &vdata1);
863  area_total = area_total + (double) vdata1;
864  }
865 
867  for (it = imWs.begin(), iend = imWs.end(); it != iend;
868  ++it) // for all pixels in imIn create a vertex and an edge
869  {
870  o1 = it.getOffset();
871  int val = imWs.pixelFromOffset(o1);
872 
873  if (val > 0) {
874  neighb.setCenter(o1);
875 
876  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
877  const offset_t o2 = nit.getOffset();
878  int val2 = imWs.pixelFromOffset(o2);
879 
880  if (o2 > o1) {
881  if (val != val2) {
882  boost::tie(e1, in1) =
883  boost::edge(val - 1, val2 - 1, Gout.getBoostGraph());
884  boost::tie(e2, in1) =
885  boost::edge(val - 1, val2 - 1, Gtemp.getBoostGraph());
886 
887  double val3 = imGrad.pixelFromOffset(o1);
888  double val4 = imGrad.pixelFromOffset(o2);
889  double maxi = std::max(val3, val4);
890 
891  if (in1 == 0) {
892  numEdges++;
893  Gout.addEdge(val - 1, val2 - 1, maxi);
894  Gtemp.addEdge(val - 1, val2 - 1, 1);
895  } else {
896  Gout.edgeWeight(e1, &tmp);
897  Gout.setEdgeWeight(e1, tmp + maxi);
898 
899  Gtemp.edgeWeight(e2, &tmp2);
900  Gtemp.setEdgeWeight(e2, tmp2 + 1);
901  }
902  }
903  }
904  }
905  }
906  }
907 
908  std::cout << "number of Edges : " << numEdges << std::endl;
909 
910  Gout_t = t_CopyGraph(Gout);
911  boost::tie(ed_it2, ed_end2) = boost::edges(Gtemp.getBoostGraph());
912  boost::tie(ed_it3, ed_end3) = boost::edges(G_area.getBoostGraph());
913  boost::tie(ed_it4, ed_end4) = boost::edges(Gout_t.getBoostGraph());
914  float current_max_value = 0.0f;
915 
916  // Weights the graph Gout with mean gradient value along boundary
917  for (boost::tie(ed_it, ed_end) = boost::edges(Gout.getBoostGraph());
918  ed_it != ed_end, ed_it2 != ed_end2, ed_it3 != ed_end3,
919  ed_it4 != ed_end4;
920  ++ed_it, ++ed_it2, ++ed_it3, ++ed_it4) {
921  Gout.edgeWeight(*ed_it, &tmp); // GRADIENT SUM
922  Gtemp.edgeWeight(*ed_it2, &tmp2); // REGION BOUNDARY LENGTH
923  Gout_t.setEdgeWeight(*ed_it4, ((double) tmp2)); // length
924  }
925 
926  // Gtemp is the min spanning tree of G_area weighted with pass-values
927  // Gtemp = morphee::MinimumSpanningTreeFromGraph(G_area);
928  // t_AverageLinkageTree(imWs, imGrad, nl, Gtemp) ;
929 
930  Gtemp = t_CopyGraph(Treein);
931 
932  for (boost::tie(ed_it, ed_end) = boost::edges(Gtemp.getBoostGraph());
933  ed_it != ed_end; ++ed_it) {
934  Gtemp.edgeWeight(*ed_it, &tmp); // PASS VALUE
935  val_edges.push_back(tmp);
936  }
937 
938  std::vector<typename BoostGraph::EdgeDescriptor> removed_edges;
939 
940  Tree_out = t_CopyGraph(Gtemp);
941  Tree_temp = t_CopyGraph(Gtemp);
942  Tree_temp2 = t_CopyGraph(Gtemp);
943 
944  // sort edges weights to explore the hierarchy
945  std::cout << "sort" << std::endl;
946  std::sort(val_edges.begin(), val_edges.end(), std::less<double>());
947 
948  double last_edge_value = val_edges.back();
949  double last_analyzed = last_edge_value;
950 
951  while (val_edges.size() > 1) {
952  std::cout << last_edge_value << std::endl;
953 
954  // remove edge of maximal weight
955  for (boost::tie(ed_it, ed_end) = boost::edges(Gtemp.getBoostGraph());
956  ed_it != ed_end; ++ed_it) {
957  Gtemp.edgeWeight(*ed_it, &tmp);
958 
959  if (tmp == last_edge_value) { // check is current max weight
960  vs = Gtemp.edgeSource(*ed_it);
961  vt = Gtemp.edgeTarget(*ed_it);
962  boost::tie(e1, in1) = boost::edge(vs, vt, Gtemp.getBoostGraph());
963  removed_edges.push_back(e1);
964  Tree_temp.removeEdge(vs, vt);
965  }
966  }
967 
968  // label trees
969  int nb_of_connected = t_LabelConnectedComponent(Tree_temp, Tree_temp2);
970 
971  // std::cout<<" number of connected components =
972  // "<<nb_of_connected<<std::endl;
973 
974  // local variable for mean values and areas of regions
975  float mean_value = 0.0f;
976  float number_of_points = 0.0f;
977  float volume1 = 0.0f;
978  float volume2 = 0.0f;
979 
980  float volume11 = 0.0f;
981  float volume22 = 0.0f;
982 
983  float area1 = 0.0f;
984  float area2 = 0.0f;
985  float quad1 = 0.0f;
986  float quad2 = 0.0f;
987  float mean_val_1 = 0.0f;
988  float mean_val_2 = 0.0f;
989  float nb_val_1 = 0.0f;
990  float nb_val_2 = 0.0f;
991  float mean_value_1 = 0.0f;
992  float mean_value_2 = 0.0f;
993  float number_of_points1 = 0.0f;
994  float number_of_points2 = 0.0f;
995  float dist_histo = 0.0f;
996 
997  // go through removed edges and look caracteristics of regions connected
998  // to it
999  while (removed_edges.size() > 0) {
1000  volume1 = 0.0f;
1001  volume2 = 0.0f;
1002  area1 = 0.0f;
1003  area2 = 0.0f;
1004  quad1 = 0.0f;
1005  quad2 = 0.0f;
1006  number_of_points = 0.0f;
1007 
1008  mean_value_1 = 0.0f;
1009  mean_value_2 = 0.0f;
1010  number_of_points1 = 0.0f;
1011  number_of_points2 = 0.0f;
1012 
1013  mean_value = 0.0f;
1014  mean_val_1 = 0.0f;
1015  mean_val_2 = 0.0f;
1016  nb_val_1 = 0.0f;
1017  nb_val_2 = 0.0f;
1018 
1019  volume11 = 0.0f;
1020  volume22 = 0.0f;
1021 
1022  dist_histo = 0.0f;
1023 
1024  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
1025  histogram_region1[dim_allouee1] = 0;
1026  histogram_region2[dim_allouee1] = 0;
1027  cumul_histogram_region1[dim_allouee1] = 0;
1028  cumul_histogram_region2[dim_allouee1] = 0;
1029  }
1030 
1031  e1 = removed_edges.back();
1032  removed_edges.pop_back();
1033 
1034  // Get label of the regions
1035  Tree_temp2.vertexData(Tree_temp2.edgeSource(e1), &label1);
1036  Tree_temp2.vertexData(Tree_temp2.edgeTarget(e1), &label2);
1037 
1038  boost::tie(ed_it4, ed_end4) = boost::edges(Gout_t.getBoostGraph());
1039 
1040  for (boost::tie(ed_it, ed_end) = boost::edges(Gout.getBoostGraph());
1041  ed_it != ed_end, ed_it4 != ed_end4; ++ed_it, ++ed_it4) {
1042  vs = Gout.edgeSource(*ed_it);
1043  vt = Gout.edgeTarget(*ed_it);
1044 
1045  // labels of the regions
1046  Tree_temp2.vertexData(vs, &vdata1);
1047  Tree_temp2.vertexData(vt, &vdata2);
1048 
1049  // compute avergage mean gradient along regions
1050  if ((vdata1 == label1 && vdata2 == label2) ||
1051  (vdata1 == label2 && vdata2 == label1)) {
1052  Gout.edgeWeight(*ed_it, &tmp);
1053  Gout_t.edgeWeight(*ed_it4, &tmp2);
1054 
1055  mean_value = mean_value + (float) tmp;
1056  number_of_points = number_of_points + (float) tmp2;
1057  }
1058 
1059  // compute avergage mean gradient along regions 1
1060  if ((vdata1 == label1 && vdata2 != label1) ||
1061  (vdata2 == label1 && vdata1 != label1)) {
1062  Gout.edgeWeight(*ed_it, &tmp);
1063  Gout_t.edgeWeight(*ed_it4, &tmp2);
1064 
1065  mean_value_1 = mean_value_1 + (float) tmp;
1066  number_of_points1 = number_of_points1 + (float) tmp2;
1067  }
1068 
1069  // compute avergage mean gradient along regions 2
1070  if ((vdata1 == label2 && vdata2 != label2) ||
1071  (vdata2 == label2 && vdata1 != label2)) {
1072  Gout.edgeWeight(*ed_it, &tmp);
1073  Gout_t.edgeWeight(*ed_it4, &tmp2);
1074 
1075  mean_value_2 = mean_value_2 + (float) tmp;
1076  number_of_points2 = number_of_points2 + (float) tmp2;
1077  }
1078  }
1079 
1080  // copying the properties of each vertex
1081  for (boost::tie(v_it, v_end) = boost::vertices(Gout.getBoostGraph());
1082  v_it != v_end; ++v_it) {
1083  // Get label of the regions
1084  Tree_temp2.vertexData(*v_it, &vdata1);
1085  Gout.vertexData(*v_it, &vdata11);
1086 
1087  Tree_out.setVertexData(*v_it, (float) alpha1 * vdata11 +
1088  (float) alpha3 *
1089  quad_error[(int) *v_it]);
1090 
1091  // compute area of each regions
1092  if (vdata1 == label1) {
1093  volume1 =
1094  volume1 +
1095  (float) vdata11; // NODES OF GOUT ARE WEIGHTED WITH VOLUME
1096  G_area.vertexData(
1097  *v_it, &vdata11); // NODES OF GCLASSIC ARE WEIGHTED WITH AREA
1098  area1 = area1 + (float) vdata11;
1099  mean_val_1 = mean_val_1 + mean_values[(int) *v_it];
1100  nb_val_1 = nb_val_1 + 1.0f;
1101 
1102  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
1103  histogram_region1[dim_allouee1] =
1104  histogram_region1[dim_allouee1] +
1105  histogram[(int) *v_it][dim_allouee1];
1106  }
1107  }
1108  if (vdata1 == label2) {
1109  volume2 =
1110  volume2 +
1111  (float) vdata11; // NODES OF GOUT ARE WEIGHTED WITH VOLUME
1112  G_area.vertexData(
1113  *v_it, &vdata11); // NODES OF GCLASSIC ARE WEIGHTED WITH AREA
1114  area2 = area2 + (float) vdata11;
1115  mean_val_2 = mean_val_2 + mean_values[(int) *v_it];
1116  nb_val_2 = nb_val_2 + 1.0f;
1117 
1118  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
1119  histogram_region2[dim_allouee1] =
1120  histogram_region2[dim_allouee1] +
1121  histogram[(int) *v_it][dim_allouee1];
1122  }
1123  }
1124  }
1125 
1126  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
1127  for (int dim_allouee0 = 0; dim_allouee0 <= dim_allouee1;
1128  ++dim_allouee0) {
1129  cumul_histogram_region1[dim_allouee1] =
1130  cumul_histogram_region1[dim_allouee1] +
1131  (float) histogram_region1[dim_allouee0] / (float) area1;
1132  cumul_histogram_region2[dim_allouee1] =
1133  cumul_histogram_region2[dim_allouee1] +
1134  (float) histogram_region2[dim_allouee0] / (float) area2;
1135  }
1136  }
1137 
1138  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
1139  dist_histo =
1140  dist_histo + std::pow(cumul_histogram_region1[dim_allouee1] -
1141  cumul_histogram_region2[dim_allouee1],
1142  2);
1143  }
1144 
1145  // copying the properties of each vertex
1146  for (boost::tie(v_it, v_end) = boost::vertices(Gout.getBoostGraph());
1147  v_it != v_end; ++v_it) {
1148  // Get label of the regions
1149  Tree_temp2.vertexData(*v_it, &vdata1);
1150 
1151  // compute area of each regions
1152  if (vdata1 == label1) {
1153  quad1 = quad1 +
1154  (mean_values[(int) *v_it] - mean_val_1 / nb_val_1) *
1155  (mean_values[(int) *v_it] - mean_val_1 / nb_val_1);
1156  }
1157  if (vdata1 == label2) {
1158  quad2 = quad2 +
1159  (mean_values[(int) *v_it] - mean_val_2 / nb_val_2) *
1160  (mean_values[(int) *v_it] - mean_val_2 / nb_val_2);
1161  }
1162  }
1163 
1164  quad1 = quad1 / nb_val_1;
1165  quad2 = quad2 / nb_val_2;
1166 
1167  /*volume11 = area1 * mean_value_1/number_of_points1;
1168  volume22 = area2 * mean_value_2/number_of_points2;*/
1169 
1170  volume11 = area1 * last_edge_value / number_of_points1;
1171  volume22 = area2 * last_edge_value / number_of_points2;
1172 
1174  // float probability_volume = ( 1.0 - std::pow( 1.0 -
1175  // volume11/((double) volume) , 50 ) - std::pow( 1.0 -
1176  // volume22/((double) volume) , 50 ) + std::pow( 1.0 -
1177  // (volume11+volume22)/((double) volume) , 50 ) );
1178  float probability_volume =
1179  (1.0 - std::pow(1.0 - volume1 / ((double) volume), (int) alpha1) -
1180  std::pow(1.0 - volume2 / ((double) volume), (int) alpha1) +
1181  std::pow(1.0 - (volume1 + volume2) / ((double) volume),
1182  (int) alpha1));
1183  float probability_area =
1184  (1.0 -
1185  std::pow(1.0 - area1 / ((double) area_total), (int) alpha1) -
1186  std::pow(1.0 - area2 / ((double) area_total), (int) alpha1) +
1187  std::pow(1.0 - (area1 + area2) / ((double) area_total),
1188  (int) alpha1));
1189 
1190  float deterministic_area =
1191  std::min(area1, area2) / ((double) area_total);
1192  float deterministic_volume =
1193  std::min(volume11, volume22) / ((double) volume);
1194 
1195  float diff_mean =
1196  std::abs((mean_val_2 / nb_val_2) - (mean_val_1 / nb_val_1));
1197  float mean_gradient = mean_value / number_of_points;
1198 
1199  float mean_gradient_1 = mean_value_1 / number_of_points1;
1200  float mean_gradient_2 = mean_value_2 / number_of_points2;
1201 
1202  float shape_factor_1 =
1203  4.0f * M_PI * area1 / (number_of_points1 * number_of_points1);
1204  float shape_factor_2 =
1205  4.0f * M_PI * area2 / (number_of_points2 * number_of_points2);
1206 
1207  shape_factor_1 = std::min(shape_factor_1, (float) 1.0);
1208  shape_factor_2 = std::min(shape_factor_2, (float) 1.0);
1209 
1210  // std::cout<<"shape_factor_1"<<shape_factor_1<<std::endl;
1211  // std::cout<<"shape_factor_2"<<shape_factor_2<<std::endl;
1212 
1213  // probability_volume = std::min( probability_volume , 0.05f ) ;
1214  // probability_area = std::min( probability_area , 0.5f ) ;
1215 
1217  boost::tie(e2, in1) =
1218  boost::edge(Tree_out.edgeSource(e1), Tree_out.edgeTarget(e1),
1219  Tree_out.getBoostGraph());
1220  // float val_gradient_mean_t = std::min( ((float) last_edge_value)/(
1221  // 65535.0f ) , 0.7f );
1222 
1223  // std::cout<<"mean_gradient"<<mean_gradient/65535.0f<<std::endl;
1224  // std::cout<<"probability_volume"<<probability_volume<<std::endl;
1225 
1226  if (number_of_points > 0.0f) {
1227  // float value_test = 100000.0f * std::pow(dist_histo,(float)
1228  // alpha2) * std::pow( ((float) mean_value/ (float) number_of_points
1229  // )/( 65535.0f ) , (float) alpha1 ) * std::pow( probability_volume ,
1230  // (float) alpha3 ) ; float value_test = 2000000.0f * std::pow(
1231  // mean_gradient/65535.0f , (float) alpha1 ) * std::pow( std::min(
1232  // mean_gradient_1/65535.0f, mean_gradient_2/65535.0f ) , (float)
1233  // alpha2 ) * std::pow( probability_volume , (float) alpha3 ) ; float
1234  // value_test = 65535.0f * std::pow( (float) last_edge_value/(
1235  // 65535.0f ) , (float) alpha1 ) * std::pow( std::max( shape_factor_1
1236  // , shape_factor_2 ) , (float) alpha2 ) * std::pow(
1237  // probability_volume , (float) alpha3 ) ; float value_test =
1238  // 65535.0f * std::pow( mean_gradient/65535.0f , (float) alpha1 ) *
1239  // std::pow( (float) diff_mean/( 65535.0f ) , (float) alpha2 ) *
1240  // std::pow( probability_volume , (float) alpha3 ) ; float value_test
1241  // = 65535.0f * std::pow( mean_gradient/65535.0f , (float) alpha1 ) *
1242  // std::pow( probability_area , (float) alpha2 ) * std::pow(
1243  // probability_volume , (float) alpha3 ) ;
1244  float value_test = 65535.0f * (mean_gradient / 65535.0f) *
1245  std::pow(probability_area, (float) alpha2) *
1246  std::pow(probability_volume, (float) alpha3);
1247  // float value_test = 65535.0f * std::pow( mean_gradient/65535.0f ,
1248  // (float) alpha1 ) * std::pow( std::max( shape_factor_1 ,
1249  // shape_factor_2 ) , (float) alpha2 ) * std::pow( probability_volume
1250  // , (float) alpha3 ) ;
1251  Tree_out.setEdgeWeight(e2, value_test);
1252 
1253  if (value_test > current_max_value)
1254  current_max_value = value_test;
1255 
1256  } else {
1257  Tree_out.setEdgeWeight(e2, 0.0f);
1258  }
1259  }
1260 
1261  while (last_edge_value == last_analyzed) {
1262  last_edge_value = val_edges.back();
1263  val_edges.pop_back();
1264  }
1265  last_analyzed = last_edge_value;
1266  }
1267 
1268  std::cout << "current_max_value" << current_max_value << std::endl;
1269 
1270  return RES_OK;
1271  }
1272 
1273  template <class ImageWs, class ImageIn, class ImageGrad, typename _alpha1,
1274  typename _alpha2, typename _alpha3, class SE, class BoostGraph>
1275  RES_C t_TreeReweighting(const ImageWs &imWs, const ImageIn &imIn,
1276  const ImageGrad &imGrad, BoostGraph &Treein,
1277  const _alpha1 alpha1, const _alpha2 alpha2,
1278  const _alpha3 alpha3, const SE &nl,
1279  BoostGraph &Tree_out)
1280  {
1281  MORPHEE_ENTER_FUNCTION("t_TreeReweighting");
1282 
1283  if ((!imWs.isAllocated())) {
1284  MORPHEE_REGISTER_ERROR("Not allocated");
1285  return RES_NOT_ALLOCATED;
1286  }
1287 
1288  if ((!imIn.isAllocated())) {
1289  MORPHEE_REGISTER_ERROR("Not allocated");
1290  return RES_NOT_ALLOCATED;
1291  }
1292 
1293  if ((!imGrad.isAllocated())) {
1294  MORPHEE_REGISTER_ERROR("Not allocated");
1295  return RES_NOT_ALLOCATED;
1296  }
1297 
1298  // common image iterator
1299  typename ImageWs::const_iterator it, iend;
1300  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
1301  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
1302  offset_t o0;
1303  offset_t o1;
1304 
1305  typename BoostGraph::EdgeIterator ed_it, ed_end;
1306  typename BoostGraph::EdgeIterator ed_it2, ed_end2;
1307  typename BoostGraph::EdgeIterator ed_it3, ed_end3;
1308  typename BoostGraph::EdgeIterator ed_it4, ed_end4;
1309 
1310  typename BoostGraph::VertexIterator v_it, v_end;
1311 
1312  typename BoostGraph::VertexProperty vdata1, vdata2, vdata11, vdata22;
1313  typename BoostGraph::VertexProperty label1, label2;
1314 
1315  bool in1;
1316  int numVert = 0;
1317  int numEdges = 0;
1318  typename BoostGraph::EdgeDescriptor e1, e2;
1319  typename BoostGraph::VertexDescriptor vs, vt;
1320  typename BoostGraph::EdgeProperty tmp, tmp2, tmp3;
1321 
1322  std::vector<double> val_edges;
1323  std::vector<double> val_edges2;
1324  val_edges.push_back(0.0);
1325 
1326  std::cout << "build Region Adjacency Graph" << std::endl;
1327 
1328  for (it = imWs.begin(), iend = imWs.end(); it != iend;
1329  ++it) // for all pixels in imIn create a vertex
1330  {
1331  o0 = it.getOffset();
1332  int val = imWs.pixelFromOffset(o0);
1333 
1334  if (val > numVert) {
1335  numVert = val;
1336  }
1337  }
1338 
1339  std::cout << "Compute mean and quaderror" << std::endl;
1340  std::vector<double> mean_values;
1341  std::vector<double> number_of_values;
1342  std::vector<double> quad_error;
1343  std::vector<double> min_gradient_values;
1344  std::vector<double> max_gradient_values;
1345  std::vector<double> area_values;
1346 
1347  int **histogram; // image histogram
1348  histogram = new int *[numVert];
1349 
1350  float *histogram_region1; // region 1 histogram
1351  histogram_region1 = new float[255];
1352 
1353  float *histogram_region2; // region 2 histogram
1354  histogram_region2 = new float[255];
1355 
1356  float *cumul_histogram_region1; // cummulated region 1 histogram
1357  cumul_histogram_region1 = new float[255];
1358 
1359  float *cumul_histogram_region2; // cummulated region 2 histogram
1360  cumul_histogram_region2 = new float[255];
1361 
1362  for (int dim_allouee0 = 0; dim_allouee0 < numVert; ++dim_allouee0) {
1363  histogram[dim_allouee0] = new int[255];
1364  }
1365 
1366  for (int dim_allouee0 = 0; dim_allouee0 < numVert; ++dim_allouee0) {
1367  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
1368  histogram[dim_allouee0][dim_allouee1] = 0;
1369  }
1370  }
1371 
1373  for (int i = 0; i < numVert; i++) {
1374  mean_values.push_back(0);
1375  number_of_values.push_back(0);
1376  quad_error.push_back(0);
1377  min_gradient_values.push_back(1000000000000);
1378  max_gradient_values.push_back(0);
1379  area_values.push_back(0);
1380  }
1381 
1383  for (it = imWs.begin(), iend = imWs.end(); it != iend;
1384  ++it) // for all pixels in imIn create a vertex
1385  {
1386  o1 = it.getOffset();
1387  int val = imWs.pixelFromOffset(o1);
1388  double val_image = imIn.pixelFromOffset(o1);
1389  double val_gradient = imGrad.pixelFromOffset(o1);
1390 
1391  mean_values[val - 1] = mean_values[val - 1] + val_image;
1392  number_of_values[val - 1] = number_of_values[val - 1] + 1.0;
1393 
1394  if (val_gradient < min_gradient_values[val - 1])
1395  min_gradient_values[val - 1] = val_gradient;
1396  if (val_gradient > max_gradient_values[val - 1])
1397  max_gradient_values[val - 1] = val_gradient;
1398 
1399  area_values[val - 1] = area_values[val - 1] + 1;
1400  int vald = (int) (val_image);
1401  histogram[val - 1][vald] = histogram[val - 1][vald] + 1;
1402  }
1403 
1405  for (int i = 0; i < numVert; i++) {
1406  mean_values[i] = mean_values[i] / number_of_values[i];
1407  }
1408 
1410  float max_quad_val = 0.0f;
1411  for (it = imWs.begin(), iend = imWs.end(); it != iend;
1412  ++it) // for all pixels in imIn create a vertex and an edge
1413  {
1414  o1 = it.getOffset();
1415  int val = imWs.pixelFromOffset(o1);
1416  double val_image = imIn.pixelFromOffset(o1);
1417 
1418  quad_error[val - 1] =
1419  (double) quad_error[val - 1] +
1420  std::pow(std::abs(val_image - (double) mean_values[val - 1]), 2);
1421 
1422  if (quad_error[val - 1] > max_quad_val)
1423  max_quad_val = quad_error[val - 1];
1424  }
1425 
1426  std::cout << "build Region Adjacency Graph Vertices" << std::endl;
1427  std::cout << "number of Vertices:" << numVert << std::endl;
1428 
1429  // create some temp graphs
1430  Tree_out = morphee::graph::CommonGraph32(numVert);
1431 
1432  BoostGraph Gout = morphee::graph::CommonGraph32(numVert);
1433  BoostGraph Gout_t = morphee::graph::CommonGraph32(numVert);
1434  BoostGraph Gtemp = morphee::graph::CommonGraph32(numVert);
1435 
1436  BoostGraph Tree_temp = morphee::graph::CommonGraph32(numVert);
1437  BoostGraph Tree_temp2 = morphee::graph::CommonGraph32(numVert);
1438 
1439  // GRAPH WHOSE NODES ARE WEIGHTED WITH AREA
1440  BoostGraph G_area = morphee::graph::CommonGraph32(numVert);
1441  morphee::morphoBase::t_NeighborhoodGraphFromMosaic(imWs, nl, G_area);
1442 
1443  // project area of regions on the graph nodes
1444  ImageWs ImTempSurfaces = imWs.getSame();
1445  morphee::morphoBase::t_ImLabelFlatZonesWithArea(imWs, nl, ImTempSurfaces);
1446  morphee::graph::t_ProjectMarkersOnGraph(ImTempSurfaces, imWs, G_area);
1447 
1448  // GRAPH WHOSE NODES ARE WEIGHTED WITH VOLUME
1449  morphee::morphoBase::t_ImLabelFlatZonesWithVolume(imWs, imGrad, nl,
1450  ImTempSurfaces);
1451  morphee::graph::t_ProjectMarkersOnGraph(ImTempSurfaces, imWs, Gout);
1452 
1453  std::cout << "build Region Adjacency Graph Edges" << std::endl;
1454 
1455  double volume = 0.0;
1456  double area_total = 0.0;
1457 
1459  for (boost::tie(v_it, v_end) = boost::vertices(Gout.getBoostGraph());
1460  v_it != v_end; ++v_it) {
1461  Gout.vertexData(*v_it, &vdata1);
1462  volume = volume + (double) vdata1;
1463 
1464  G_area.vertexData(*v_it, &vdata1);
1465  area_total = area_total + (double) vdata1;
1466  }
1467 
1469  for (it = imWs.begin(), iend = imWs.end(); it != iend;
1470  ++it) // for all pixels in imIn create a vertex and an edge
1471  {
1472  o1 = it.getOffset();
1473  int val = imWs.pixelFromOffset(o1);
1474 
1475  if (val > 0) {
1476  neighb.setCenter(o1);
1477 
1478  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
1479  const offset_t o2 = nit.getOffset();
1480  int val2 = imWs.pixelFromOffset(o2);
1481 
1482  if (o2 > o1) {
1483  if (val != val2) {
1484  boost::tie(e1, in1) =
1485  boost::edge(val - 1, val2 - 1, Gout.getBoostGraph());
1486  boost::tie(e2, in1) =
1487  boost::edge(val - 1, val2 - 1, Gtemp.getBoostGraph());
1488 
1489  double val3 = imGrad.pixelFromOffset(o1);
1490  double val4 = imGrad.pixelFromOffset(o2);
1491  double maxi = std::max(val3, val4);
1492 
1493  if (in1 == 0) {
1494  numEdges++;
1495  Gout.addEdge(val - 1, val2 - 1, maxi);
1496  Gtemp.addEdge(val - 1, val2 - 1, 1);
1497  } else {
1498  Gout.edgeWeight(e1, &tmp);
1499  Gout.setEdgeWeight(e1, tmp + maxi);
1500 
1501  Gtemp.edgeWeight(e2, &tmp2);
1502  Gtemp.setEdgeWeight(e2, tmp2 + 1);
1503  }
1504  }
1505  }
1506  }
1507  }
1508  }
1509 
1510  std::cout << "number of Edges : " << numEdges << std::endl;
1511 
1512  Gout_t = t_CopyGraph(Gout);
1513  boost::tie(ed_it2, ed_end2) = boost::edges(Gtemp.getBoostGraph());
1514  boost::tie(ed_it3, ed_end3) = boost::edges(G_area.getBoostGraph());
1515  boost::tie(ed_it4, ed_end4) = boost::edges(Gout_t.getBoostGraph());
1516  float current_max_value = 0.0f;
1517 
1518  // Weights the graph
1519  for (boost::tie(ed_it, ed_end) = boost::edges(Gout.getBoostGraph());
1520  ed_it != ed_end, ed_it2 != ed_end2, ed_it3 != ed_end3,
1521  ed_it4 != ed_end4;
1522  ++ed_it, ++ed_it2, ++ed_it3, ++ed_it4) {
1523  Gout.edgeWeight(*ed_it, &tmp); // GRADIENT SUM
1524  Gtemp.edgeWeight(*ed_it2, &tmp2); // REGION BOUNDARY LENGTH
1525  Gout_t.setEdgeWeight(*ed_it4, ((double) tmp2)); // length
1526  }
1527 
1528  Gtemp = t_CopyGraph(Treein);
1529 
1530  for (boost::tie(ed_it, ed_end) = boost::edges(Gtemp.getBoostGraph());
1531  ed_it != ed_end; ++ed_it) {
1532  Gtemp.edgeWeight(*ed_it, &tmp); // MEAN GRADIENT VALUE
1533  val_edges.push_back(tmp);
1534  }
1535 
1536  std::vector<typename BoostGraph::EdgeDescriptor> removed_edges;
1537 
1538  Tree_out = t_CopyGraph(Gtemp);
1539  Tree_temp = t_CopyGraph(Gtemp);
1540  Tree_temp2 = t_CopyGraph(Gtemp);
1541 
1542  // sort edges weights to explore the hierarchy
1543  std::cout << "sort" << std::endl;
1544  std::sort(val_edges.begin(), val_edges.end(), std::less<double>());
1545  double last_edge_value = val_edges.back();
1546  double last_analyzed = last_edge_value;
1547 
1548  /*int min_nb_of_edges = (int) alpha1-1 ;
1549  int current_nb_of_edges = 0 ;
1550 
1551  for( int i = val_edges.size()-1 ; i>=0; i--){
1552 
1553 
1554  if( current_nb_of_edges < min_nb_of_edges ){
1555  last_edge_value = val_edges[i];
1556  last_analyzed = last_edge_value;
1557  val_edges.pop_back();
1558  current_nb_of_edges++;
1559  }
1560 
1561  }*/
1562 
1563  int iteration = 1;
1564 
1565  while (val_edges.size() > 1) {
1566  std::cout << last_edge_value << std::endl;
1567 
1568  // remove edge of maximal weight
1569  for (boost::tie(ed_it, ed_end) = boost::edges(Gtemp.getBoostGraph());
1570  ed_it != ed_end; ++ed_it) {
1571  Gtemp.edgeWeight(*ed_it, &tmp);
1572  vs = Gtemp.edgeSource(*ed_it);
1573  vt = Gtemp.edgeTarget(*ed_it);
1574  boost::tie(e1, in1) = boost::edge(vs, vt, Tree_temp.getBoostGraph());
1575 
1576  if (tmp >= last_edge_value && in1) { // check is current max weight
1577  removed_edges.push_back(e1);
1578  Tree_temp.removeEdge(vs, vt);
1579  }
1580  }
1581 
1582  // label trees
1583  int nb_of_connected;
1584  t_LabelConnectedComponent(Tree_temp, Tree_temp2, &nb_of_connected);
1585 
1586  std::cout << " number of connected components = " << nb_of_connected
1587  << std::endl;
1588 
1589  // local variable for mean values and areas of regions
1590  float mean_value = 0.0f;
1591  float min_value_b = 1000000000000.0f;
1592  float number_of_points = 0.0f;
1593  float volume1 = 0.0f;
1594  float volume2 = 0.0f;
1595 
1596  float volume11 = 0.0f;
1597  float volume22 = 0.0f;
1598 
1599  float area1 = 0.0f;
1600  float area2 = 0.0f;
1601 
1602  float quad1 = 0.0f;
1603  float quad2 = 0.0f;
1604 
1605  float mean_val_1 = 0.0f;
1606  float mean_val_2 = 0.0f;
1607 
1608  float nb_val_1 = 0.0f;
1609  float nb_val_2 = 0.0f;
1610 
1611  float mean_value_1 = 0.0f;
1612  float mean_value_2 = 0.0f;
1613 
1614  float number_of_points1 = 0.0f;
1615  float number_of_points2 = 0.0f;
1616 
1617  float dist_histo = 0.0f;
1618 
1619  // go through removed edges and look caracteristics of regions connected
1620  // to it
1621  while (removed_edges.size() > 0) {
1622  volume1 = 0.0f;
1623  volume2 = 0.0f;
1624  area1 = 0.0f;
1625  area2 = 0.0f;
1626  quad1 = 0.0f;
1627  quad2 = 0.0f;
1628  number_of_points = 0.0f;
1629 
1630  mean_value_1 = 0.0f;
1631  mean_value_2 = 0.0f;
1632  number_of_points1 = 0.0f;
1633  number_of_points2 = 0.0f;
1634 
1635  mean_value = 0.0f;
1636  mean_val_1 = 0.0f;
1637  mean_val_2 = 0.0f;
1638  nb_val_1 = 0.0f;
1639  nb_val_2 = 0.0f;
1640 
1641  volume11 = 0.0f;
1642  volume22 = 0.0f;
1643 
1644  dist_histo = 0.0f;
1645 
1646  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
1647  histogram_region1[dim_allouee1] = 0;
1648  histogram_region2[dim_allouee1] = 0;
1649  cumul_histogram_region1[dim_allouee1] = 0;
1650  cumul_histogram_region2[dim_allouee1] = 0;
1651  }
1652 
1653  e1 = removed_edges.back();
1654  removed_edges.pop_back();
1655 
1656  // Get label of the regions
1657  Tree_temp2.vertexData(Tree_temp2.edgeSource(e1), &label1);
1658  Tree_temp2.vertexData(Tree_temp2.edgeTarget(e1), &label2);
1659 
1660  boost::tie(ed_it4, ed_end4) = boost::edges(Gout_t.getBoostGraph());
1661 
1662  for (boost::tie(ed_it, ed_end) = boost::edges(Gout.getBoostGraph());
1663  ed_it != ed_end, ed_it4 != ed_end4; ++ed_it, ++ed_it4) {
1664  vs = Gout.edgeSource(*ed_it);
1665  vt = Gout.edgeTarget(*ed_it);
1666 
1667  // labels of the regions
1668  Tree_temp2.vertexData(vs, &vdata1);
1669  Tree_temp2.vertexData(vt, &vdata2);
1670 
1671  // compute avergage mean gradient along regions
1672  if ((vdata1 == label1 && vdata2 == label2) ||
1673  (vdata1 == label2 && vdata2 == label1)) {
1674  Gout.edgeWeight(*ed_it, &tmp);
1675  Gout_t.edgeWeight(*ed_it4, &tmp2);
1676 
1677  mean_value = mean_value + (float) tmp;
1678  number_of_points = number_of_points + (float) tmp2;
1679 
1680  if (((float) tmp / (float) tmp2) < min_value_b)
1681  min_value_b = ((float) tmp / (float) tmp2);
1682  }
1683 
1684  // compute avergage mean gradient along regions 1
1685  if ((vdata1 == label1 && vdata2 != label1) ||
1686  (vdata2 == label1 && vdata1 != label1)) {
1687  Gout.edgeWeight(*ed_it, &tmp);
1688  Gout_t.edgeWeight(*ed_it4, &tmp2);
1689 
1690  mean_value_1 = mean_value_1 + (float) tmp;
1691  number_of_points1 = number_of_points1 + (float) tmp2;
1692  }
1693 
1694  // compute avergage mean gradient along regions 2
1695  if ((vdata1 == label2 && vdata2 != label2) ||
1696  (vdata2 == label2 && vdata1 != label2)) {
1697  Gout.edgeWeight(*ed_it, &tmp);
1698  Gout_t.edgeWeight(*ed_it4, &tmp2);
1699 
1700  mean_value_2 = mean_value_2 + (float) tmp;
1701  number_of_points2 = number_of_points2 + (float) tmp2;
1702  }
1703  }
1704 
1705  // copying the properties of each vertex
1706  for (boost::tie(v_it, v_end) = boost::vertices(Gout.getBoostGraph());
1707  v_it != v_end; ++v_it) {
1708  // Get label of the regions
1709  Tree_temp2.vertexData(*v_it, &vdata1);
1710  Gout.vertexData(*v_it, &vdata11);
1711 
1712  Tree_out.setVertexData(*v_it, (float) alpha1 * vdata11 +
1713  (float) alpha3 *
1714  quad_error[(int) *v_it]);
1715 
1716  // compute area of each regions
1717  if (vdata1 == label1) {
1718  volume1 =
1719  volume1 +
1720  (float) vdata11; // NODES OF GOUT ARE WEIGHTED WITH VOLUME
1721  G_area.vertexData(
1722  *v_it, &vdata11); // NODES OF GCLASSIC ARE WEIGHTED WITH AREA
1723  area1 = area1 + (float) vdata11;
1724  mean_val_1 = mean_val_1 + mean_values[(int) *v_it];
1725  nb_val_1 = nb_val_1 + 1.0f;
1726 
1727  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
1728  histogram_region1[dim_allouee1] =
1729  histogram_region1[dim_allouee1] +
1730  histogram[(int) *v_it][dim_allouee1];
1731  }
1732  }
1733  if (vdata1 == label2) {
1734  volume2 =
1735  volume2 +
1736  (float) vdata11; // NODES OF GOUT ARE WEIGHTED WITH VOLUME
1737  G_area.vertexData(
1738  *v_it, &vdata11); // NODES OF GCLASSIC ARE WEIGHTED WITH AREA
1739  area2 = area2 + (float) vdata11;
1740  mean_val_2 = mean_val_2 + mean_values[(int) *v_it];
1741  nb_val_2 = nb_val_2 + 1.0f;
1742 
1743  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
1744  histogram_region2[dim_allouee1] =
1745  histogram_region2[dim_allouee1] +
1746  histogram[(int) *v_it][dim_allouee1];
1747  }
1748  }
1749  }
1750 
1751  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
1752  for (int dim_allouee0 = 0; dim_allouee0 <= dim_allouee1;
1753  ++dim_allouee0) {
1754  cumul_histogram_region1[dim_allouee1] =
1755  cumul_histogram_region1[dim_allouee1] +
1756  (float) histogram_region1[dim_allouee0] / (float) area1;
1757  cumul_histogram_region2[dim_allouee1] =
1758  cumul_histogram_region2[dim_allouee1] +
1759  (float) histogram_region2[dim_allouee0] / (float) area2;
1760  }
1761  }
1762 
1763  for (int dim_allouee1 = 0; dim_allouee1 < 255; ++dim_allouee1) {
1764  dist_histo =
1765  dist_histo + std::pow(cumul_histogram_region1[dim_allouee1] -
1766  cumul_histogram_region2[dim_allouee1],
1767  2);
1768  }
1769 
1770  // copying the properties of each vertex
1771  for (boost::tie(v_it, v_end) = boost::vertices(Gout.getBoostGraph());
1772  v_it != v_end; ++v_it) {
1773  // Get label of the regions
1774  Tree_temp2.vertexData(*v_it, &vdata1);
1775 
1776  // compute area of each regions
1777  if (vdata1 == label1) {
1778  quad1 = quad1 +
1779  (mean_values[(int) *v_it] - mean_val_1 / nb_val_1) *
1780  (mean_values[(int) *v_it] - mean_val_1 / nb_val_1);
1781  }
1782  if (vdata1 == label2) {
1783  quad2 = quad2 +
1784  (mean_values[(int) *v_it] - mean_val_2 / nb_val_2) *
1785  (mean_values[(int) *v_it] - mean_val_2 / nb_val_2);
1786  }
1787  }
1788 
1789  quad1 = quad1 / nb_val_1;
1790  quad2 = quad2 / nb_val_2;
1791 
1792  /*volume11 = area1 * mean_value_1/number_of_points1;
1793  volume22 = area2 * mean_value_2/number_of_points2;*/
1794 
1795  volume11 = area1 * mean_value / number_of_points;
1796  volume22 = area2 * mean_value / number_of_points;
1797 
1798  // std::cout<<"dist_histo ="<<dist_histo<<std::endl;
1799 
1801  float probability_volume =
1802  (1.0 - std::pow(1.0 - volume1 / ((double) volume), (int) alpha1) -
1803  std::pow(1.0 - volume2 / ((double) volume), (int) alpha1) +
1804  std::pow(1.0 - (volume1 + volume2) / ((double) volume),
1805  (int) alpha1));
1806  float probability_area =
1807  (1.0 -
1808  std::pow(1.0 - area1 / ((double) area_total), (int) alpha1) -
1809  std::pow(1.0 - area2 / ((double) area_total), (int) alpha1) +
1810  std::pow(1.0 - (area1 + area2) / ((double) area_total),
1811  (int) alpha1));
1812 
1813  float deterministic_area =
1814  std::min(area1, area2) / ((double) area_total);
1815  float deterministic_volume =
1816  std::min(volume11, volume22) / ((double) volume);
1817 
1818  float diff_mean =
1819  std::abs((mean_val_2 / nb_val_2) - (mean_val_1 / nb_val_1));
1820  float mean_gradient = mean_value / number_of_points;
1821 
1822  float mean_gradient_1 = mean_value_1 / number_of_points1;
1823  float mean_gradient_2 = mean_value_2 / number_of_points2;
1824 
1825  dist_histo = deterministic_area * dist_histo / 255.0f;
1826 
1828  boost::tie(e2, in1) =
1829  boost::edge(Tree_out.edgeSource(e1), Tree_out.edgeTarget(e1),
1830  Tree_out.getBoostGraph());
1831 
1832  if (number_of_points > 0.0f) {
1833  // float value_test = 65535.0f * std::pow( (
1834  // (float)last_edge_value/65535.0f) , (float) alpha2 ) * std::pow(
1835  // dist_histo , (float) alpha2 ) * std::pow( probability_volume ,
1836  // (float) alpha3 ) ;
1837  float value_test =
1838  65535.0f *
1839  std::pow(((float) mean_gradient / 65535.0f), (float) alpha2) *
1840  std::pow(probability_volume, (float) alpha3);
1841  // float value_test = 65535.0f * std::min( std::pow( (
1842  // (float)last_edge_value/65535.0f) , (float) alpha2 ) , std::pow(
1843  // probability_volume , (float) alpha3 ) ) ; value_test = std::min(
1844  // 65535.0f * log( 1.0f+value_test )/(log(65536.0f)) , 65535.0f ) ;
1845  value_test = std::min(value_test, 65535.0f);
1846  Tree_out.setEdgeWeight(e2, value_test);
1847 
1848  if (value_test > current_max_value)
1849  current_max_value = value_test;
1850 
1851  } else {
1852  Tree_out.setEdgeWeight(e2, 0.0f);
1853  }
1854  }
1855 
1856  while (last_edge_value == last_analyzed) {
1857  last_edge_value = val_edges.back();
1858  val_edges.pop_back();
1859  }
1860  last_analyzed = last_edge_value;
1861  iteration++;
1862  }
1863 
1864  std::cout << "current_max_value" << current_max_value << std::endl;
1865 
1866  return RES_OK;
1867  }
1868 
1869  void Addition(const affine_par_morceaux &A, const affine_par_morceaux &B,
1870  affine_par_morceaux &S, int Pmax)
1871  {
1872  affine_par_morceaux::const_reverse_iterator ia = A.rbegin(),
1873  eia = A.rend();
1874  affine_par_morceaux::const_reverse_iterator ib = B.rbegin(),
1875  eib = B.rend();
1876  // Double parcours des morceaux de A et B, en sens inverse
1877  while ((ia != eia) && (ib != eib) && (S.size() < Pmax)) {
1878  // Si l'origine du morceau courant de A est >= a celle du morceau
1879  // courant de B Un morceau doit etre cree avec cette origine
1880  if ((*ia).x >= (*ib).x) {
1881  morceau nouveau = *ia;
1882  // On ajoute a l'ordonne du nouveau l'ordonnee de (*ib) au point
1883  // (*ia).x
1884  nouveau.y += (*ib).y + (*ib).p * ((*ia).x - (*ib).x);
1885  // Ajout des pentes
1886  nouveau.p += (*ib).p;
1887  // Empilement au debut de la somme
1888  S.push_front(nouveau);
1889  // Si les debuts des morceaux sont egaux : il faut aussi passer
1890  // au morceau precedent de B
1891  if ((*ia).x == (*ib).x)
1892  ++ib;
1893  ++ia;
1894  }
1895  // Memes operations mais en inversant les roles de (*ia) et (*ib)
1896  else {
1897  morceau nouveau = *ib;
1898  nouveau.y += (*ia).y + (*ia).p * ((*ib).x - (*ia).x);
1899  nouveau.p += (*ia).p;
1900  S.push_front(nouveau);
1901  ++ib;
1902  }
1903  }
1904  // Remise en 0 de l'origine du premier morceau :
1905  // si l'addition a ete stoppee par Pmax, le dernier morceau ajoute peut
1906  // avoir x>0
1907  if (S.front().x > 0) {
1908  S.front().y -= S.front().p * S.front().x;
1909  S.front().x = 0;
1910  }
1911  // FIN
1912  }
1913 
1914  float Inf_affine(affine_par_morceaux &A, const morceau &m)
1915  {
1916  // utilisation d'un iterateur bidirectionnel comme un reverse_iterator
1917  affine_par_morceaux::iterator i = A.end(), ei = A.begin();
1918  --i;
1919  --ei;
1920  // cas particulier de fonction de cout additive :
1921  // les pentes de m et du dernier morceau de A sont alors egales
1922  if (m.p == (*i).p) {
1923  // ordonnee de m en (*i).x
1924  float y = m.y + m.p * ((*i).x - m.x);
1925  // Si m est au dessus de (*i) : intersection en +infini
1926  if (y > (*i).y) {
1927  return 0;
1928  }
1929  // Si m est confondu a (*i) : apparition au debut de (*i)
1930  else if (y == (*i).y) {
1931  return (*i).x;
1932  }
1933  // Sinon, l'intersection se situe sur un morceau precedent,
1934  // on passe le dernier morceau et on continue
1935  else {
1936  --i;
1937  }
1938  }
1939  // Recherche du morceau sur lequel se situe l'intersection
1940  float xi;
1941  for (; i != ei; --i) {
1942  xi = (m.x * m.p - (*i).x * (*i).p - (m.y - (*i).y)) / (m.p - (*i).p);
1943  if (xi > (*i).x)
1944  break;
1945  }
1946  // Suppression des morceaux suivant l'intersection
1947  A.erase(++i, A.end());
1948  // Insertion nouveau morceau final
1949  morceau m1;
1950  m1.x = xi;
1951  m1.y = m.y + m.p * (xi - m.x);
1952  m1.p = m.p;
1953  A.push_back(m1);
1954  // FIN
1955  return xi;
1956  }
1957 
1958  template <class ImageWs, class ImageIn, class ImageGrad, class SE,
1959  class BoostGraph>
1960  RES_C t_ScaleSetHierarchyReweighting(const ImageWs &imWs,
1961  const ImageIn &imIn,
1962  const ImageGrad &imGrad,
1963  const BoostGraph &Treein, const SE &nl,
1964  BoostGraph &Tree_out)
1965  {
1966  MORPHEE_ENTER_FUNCTION("t_ScaleSetHierarchyReweighting");
1967 
1968  // SCALE SET HIERARCHY FUNCTION
1969  if ((!imWs.isAllocated())) {
1970  MORPHEE_REGISTER_ERROR("Not allocated");
1971  return RES_NOT_ALLOCATED;
1972  }
1973 
1974  if ((!imIn.isAllocated())) {
1975  MORPHEE_REGISTER_ERROR("Not allocated");
1976  return RES_NOT_ALLOCATED;
1977  }
1978 
1979  if ((!imGrad.isAllocated())) {
1980  MORPHEE_REGISTER_ERROR("Not allocated");
1981  return RES_NOT_ALLOCATED;
1982  }
1983 
1984  // common image iterator
1985  typename ImageWs::const_iterator it, iend;
1986  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
1987  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
1988  offset_t o0;
1989  offset_t o1;
1990 
1991  typename BoostGraph::EdgeIterator ed_it, ed_end;
1992  typename BoostGraph::EdgeIterator ed_it2, ed_end2;
1993  typename BoostGraph::EdgeIterator ed_it3, ed_end3;
1994  typename BoostGraph::EdgeIterator ed_it4, ed_end4;
1995 
1996  typename BoostGraph::VertexIterator v_it, v_end;
1997 
1998  typename BoostGraph::VertexProperty vdata1, vdata2, vdata11, vdata22;
1999  typename BoostGraph::VertexProperty label1, label2;
2000 
2001  bool in1;
2002  int numVert = 0;
2003  int numEdges = 0;
2004  typename BoostGraph::EdgeDescriptor e1, e2, ef;
2005  typename BoostGraph::VertexDescriptor vs, vt;
2006  typename BoostGraph::EdgeProperty tmp, tmp2, tmp3;
2007 
2008  std::vector<double> val_edges;
2009  val_edges.push_back(0.0);
2010 
2011  float lambda = 1.0;
2012 
2013  std::cout << "Compute number of regions" << std::endl;
2014 
2015  for (it = imWs.begin(), iend = imWs.end(); it != iend;
2016  ++it) // for all pixels in imIn create a vertex
2017  {
2018  o0 = it.getOffset();
2019  int val = imWs.pixelFromOffset(o0);
2020 
2021  if (val > numVert) {
2022  numVert = val;
2023  }
2024  }
2025 
2026  // create some temp graphs
2027  Tree_out = morphee::graph::CommonGraph32(numVert);
2028  Tree_out = t_CopyGraph(Treein);
2029  // copy of input tree
2030  BoostGraph Tree_temp = morphee::graph::CommonGraph32(numVert);
2031  BoostGraph Tree_ordered = morphee::graph::CommonGraph32(numVert);
2032  BoostGraph Tree_temp2 = morphee::graph::CommonGraph32(numVert);
2033  BoostGraph Tree_old_label = morphee::graph::CommonGraph32(numVert);
2034 
2035  // G_gradient : contain integral of gradient along boundaries
2036  BoostGraph G_gradient = morphee::graph::CommonGraph32(numVert);
2037  // G_blength : contain length of boundaries
2038  BoostGraph G_blength = morphee::graph::CommonGraph32(numVert);
2039 
2040  std::cout << "1) Compute statistics of each regions : ... " << std::endl;
2041  std::vector<double> mean_values;
2042  std::vector<double> number_of_values;
2043  std::vector<double> quad_error;
2044 
2045  float x_star = 0.0f;
2046  float sum_gradient = 0.0f;
2047  float current_max_value = 0.0f;
2048 
2049  int **histogram; // image histogram
2050  histogram = new int *[numVert];
2051 
2052  float *histogram_region1; // region 1 histogram
2053  histogram_region1 = new float[256];
2054 
2055  float *histogram_region_merged_1; // region 1 histogram
2056  histogram_region_merged_1 = new float[256];
2057 
2058  float *histogram_region_merged_2; // region 1 histogram
2059  histogram_region_merged_2 = new float[256];
2060 
2061  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
2062  histogram_region1[dim_allouee1] = 0;
2063  histogram_region_merged_1[dim_allouee1] = 0;
2064  histogram_region_merged_2[dim_allouee1] = 0;
2065  }
2066 
2067  for (int dim_allouee0 = 0; dim_allouee0 < numVert; ++dim_allouee0) {
2068  histogram[dim_allouee0] = new int[256];
2069  }
2070 
2071  for (int dim_allouee0 = 0; dim_allouee0 < numVert; ++dim_allouee0) {
2072  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
2073  histogram[dim_allouee0][dim_allouee1] = 0;
2074  }
2075  }
2076 
2078  for (int i = 0; i < numVert; i++) {
2079  mean_values.push_back(0);
2080  number_of_values.push_back(0);
2081  quad_error.push_back(0);
2082  }
2083 
2085  for (it = imWs.begin(), iend = imWs.end(); it != iend;
2086  ++it) // for all pixels in imIn create a vertex
2087  {
2088  o1 = it.getOffset();
2089  int val = imWs.pixelFromOffset(o1);
2090  double val_image = imIn.pixelFromOffset(o1);
2091 
2092  mean_values[val - 1] = mean_values[val - 1] + val_image;
2093  number_of_values[val - 1] = number_of_values[val - 1] + 1.0;
2094 
2095  int vald = (int) (val_image);
2096  histogram[val - 1][vald] = histogram[val - 1][vald] + 1;
2097  }
2098 
2100  for (int i = 0; i < numVert; i++) {
2101  mean_values[i] = mean_values[i] / number_of_values[i];
2102  }
2103 
2105  float max_quad_val = 0.0f;
2106  for (it = imWs.begin(), iend = imWs.end(); it != iend;
2107  ++it) // for all pixels in imIn create a vertex and an edge
2108  {
2109  o1 = it.getOffset();
2110  int val = imWs.pixelFromOffset(o1);
2111  double val_image = imIn.pixelFromOffset(o1);
2112 
2113  // Label regions
2114  Tree_out.setVertexData(val - 1, 0);
2115 
2116  // quadratic error
2117  quad_error[val - 1] =
2118  (double) quad_error[val - 1] +
2119  std::pow(std::abs(val_image - (double) mean_values[val - 1]), 2);
2120 
2121  // Gradient integral and regions boundaries length
2122  if (val > 0) {
2123  neighb.setCenter(o1);
2124 
2125  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
2126  const offset_t o2 = nit.getOffset();
2127  int val2 = imWs.pixelFromOffset(o2);
2128 
2129  if (o2 > o1) {
2130  if (val != val2) {
2131  boost::tie(e1, in1) =
2132  boost::edge(val - 1, val2 - 1, G_gradient.getBoostGraph());
2133  boost::tie(e2, in1) =
2134  boost::edge(val - 1, val2 - 1, G_blength.getBoostGraph());
2135 
2136  double val3 = imGrad.pixelFromOffset(o1);
2137  double val4 = imGrad.pixelFromOffset(o2);
2138  double maxi = std::max(val3, val4);
2139  sum_gradient =
2140  sum_gradient + 1.0f / (1.0f + 100.0f * (maxi / 65535.0f) *
2141  (maxi / 65535.0f));
2142 
2143  if (in1 == 0) {
2144  numEdges++;
2145  G_gradient.addEdge(val - 1, val2 - 1,
2146  1.0f / (1.0f + 100.0f * (maxi / 65535.0f) *
2147  (maxi / 65535.0f)));
2148  G_blength.addEdge(val - 1, val2 - 1, 1);
2149  } else {
2150  G_gradient.edgeWeight(e1, &tmp);
2151  G_gradient.setEdgeWeight(
2152  e1, tmp + 1.0f / (1.0f + 100.0f * (maxi / 65535.0f) *
2153  (maxi / 65535.0f)));
2154 
2155  G_blength.edgeWeight(e2, &tmp2);
2156  G_blength.setEdgeWeight(e2, tmp2 + 1);
2157  }
2158  }
2159  }
2160  }
2161  }
2162  }
2163 
2164  std::cout << "1) Compute statistics of each regions : done !"
2165  << std::endl;
2166 
2167  std::cout << "Number of of Tree Edges : " << numEdges << std::endl;
2168 
2169  std::cout << "2) Go through hierarchy in ascendant order ... "
2170  << std::endl;
2171 
2172  // ENSURE THAT ONLY TWO REGIONS CAN BE MERGED AT EACH STEP
2173  // morphee::Morpho_Graph::t_Order_Edges_Weights(Treein, Tree_ordered);
2174 
2175  Tree_ordered = t_CopyGraph(Tree_out);
2176 
2177  boost::tie(ed_it2, ed_end2) = boost::edges(Tree_out.getBoostGraph());
2178 
2179  for (boost::tie(ed_it, ed_end) =
2180  boost::edges(Tree_ordered.getBoostGraph());
2181  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
2182  Tree_ordered.edgeWeight(*ed_it, &tmp);
2183  val_edges.push_back(tmp);
2184  Tree_out.setEdgeWeight(*ed_it2, 0);
2185  }
2186 
2187  BoostGraph Tree_out2 = t_CopyGraph(Tree_out);
2188 
2189  // INIT TREETEMP
2190  Tree_temp = morphee::graph::CommonGraph32(numVert);
2191 
2192  std::vector<typename BoostGraph::EdgeDescriptor> added_edges;
2193  std::vector<typename BoostGraph::EdgeDescriptor> frontiers_edges;
2194  std::vector<typename BoostGraph::EdgeDescriptor> inside_edges;
2195  std::vector<typename BoostGraph::VertexDescriptor> merged_nodes1;
2196  std::vector<typename BoostGraph::VertexDescriptor> merged_nodes2;
2197 
2198  // sort edges weights to explore the hierarchy
2199  std::cout << "sort edges of tree" << std::endl;
2200  std::sort(val_edges.begin(), val_edges.end(), std::greater<double>());
2201 
2202  double last_edge_value = val_edges.back();
2203  double last_analyzed = last_edge_value;
2204  int current_label = numVert - 1;
2205  int number_of_connected_components = numVert;
2206 
2207  while (val_edges.size() > 0 || number_of_connected_components >= 2) {
2208  std::cout << last_edge_value << std::endl;
2209  // BEFORE MERGING
2210  int number_of_old_connected_components;
2211  t_LabelConnectedComponent(Tree_temp, Tree_old_label,
2212  &number_of_old_connected_components);
2213 
2214  // add edge of minimal weight
2215  for (boost::tie(ed_it, ed_end) =
2216  boost::edges(Tree_ordered.getBoostGraph());
2217  ed_it != ed_end; ++ed_it) {
2218  Tree_ordered.edgeWeight(*ed_it, &tmp);
2219 
2220  if (tmp == last_edge_value) { // check if current min
2221 
2222  vs = Tree_ordered.edgeSource(*ed_it);
2223  vt = Tree_ordered.edgeTarget(*ed_it);
2224  boost::tie(e1, in1) =
2225  boost::add_edge(vs, vt, Tree_temp.getBoostGraph());
2226  added_edges.push_back(e1);
2227  }
2228  }
2229 
2230  // AFTER MERGING
2231  t_LabelConnectedComponent(Tree_temp, Tree_temp2,
2232  &number_of_connected_components);
2233  std::cout << "number_of_connected_components = "
2234  << number_of_connected_components << std::endl;
2235 
2236  // go through removed edges and look caracteristics of regions connected
2237  // to it
2238  while (added_edges.size() > 0) {
2239  // local variable for mean values and areas of the merged region
2240  float int_value_1 = 0.0f;
2241  float number_of_bpoints1 = 0.0f;
2242  float mean_value_in1 = 0.0f;
2243  float quad_error_in1 = 0.0f;
2244  float nb_val_in1 = 0.0f;
2245 
2246  // local variable for mean values and areas of the regions before
2247  // merging
2248  int merged_region_1 = 0;
2249  float int_value_merged_region_1 = 0.0f;
2250  float number_of_bpoints_merged_region_1 = 0.0f;
2251  float mean_value_in_merged_region_1 = 0.0f;
2252  float quad_error_in_merged_region_1 = 0.0f;
2253  float nb_val_in_merged_region_1 = 0.0f;
2254 
2255  int merged_region_2 = 0;
2256  float int_value_merged_region_2 = 0.0f;
2257  float number_of_bpoints_merged_region_2 = 0.0f;
2258  float mean_value_in_merged_region_2 = 0.0f;
2259  float quad_error_in_merged_region_2 = 0.0f;
2260  float nb_val_in_merged_region_2 = 0.0f;
2261 
2262  // last added edges
2263  e1 = added_edges.back();
2264  added_edges.pop_back();
2265 
2266  // Get label of the regions : should be the same !!!
2267  Tree_temp2.vertexData(Tree_ordered.edgeSource(e1), &label1);
2268  Tree_temp2.vertexData(Tree_ordered.edgeTarget(e1), &label2);
2269 
2270  // Get old label of the regions : only two regions are merged at each
2271  // step !!
2272  Tree_old_label.vertexData(Tree_ordered.edgeSource(e1), &vdata1);
2273  merged_region_1 = (int) vdata1;
2274 
2275  Tree_old_label.vertexData(Tree_ordered.edgeTarget(e1), &vdata2);
2276  merged_region_2 = (int) vdata2;
2277 
2278  if (label1 != 0) {
2279  boost::tie(ed_it2, ed_end2) =
2280  boost::edges(G_gradient.getBoostGraph());
2281 
2282  for (boost::tie(ed_it, ed_end) =
2283  boost::edges(G_blength.getBoostGraph());
2284  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
2285  vs = G_blength.edgeSource(*ed_it);
2286  vt = G_blength.edgeTarget(*ed_it);
2287 
2288  // new label of the regions
2289  Tree_temp2.vertexData(vs, &vdata1);
2290  Tree_temp2.vertexData(vt, &vdata2);
2291 
2292  // old labels of the regions
2293  Tree_old_label.vertexData(vs, &vdata11);
2294  Tree_old_label.vertexData(vt, &vdata22);
2295 
2296  if ((vdata1 == label1 && vdata2 == label1))
2297  inside_edges.push_back(*ed_it);
2298 
2299  if ((vdata11 == merged_region_1 && vdata22 != merged_region_1 &&
2300  vdata22 != merged_region_2) ||
2301  (vdata22 == merged_region_1 && vdata11 != merged_region_1 &&
2302  vdata11 != merged_region_2)) {
2303  frontiers_edges.push_back(*ed_it);
2304  }
2305 
2306  // compute integral of gradient and length of the merged region
2307  if ((vdata1 == label1 && vdata2 != label1) ||
2308  (vdata2 == label1 && vdata1 != label1)) {
2309  G_gradient.edgeWeight(*ed_it2, &tmp);
2310  G_blength.edgeWeight(*ed_it, &tmp2);
2311  int_value_1 = int_value_1 + (float) tmp;
2312  number_of_bpoints1 = number_of_bpoints1 + (float) tmp2;
2313  // frontiers_edges.push_back( *ed_it );
2314  }
2315 
2316  // compute integral of gradient and length of the merged region
2317  if ((vdata11 == merged_region_1 && vdata22 != merged_region_1) ||
2318  (vdata22 == merged_region_1 && vdata11 != merged_region_1)) {
2319  G_gradient.edgeWeight(*ed_it2, &tmp);
2320  G_blength.edgeWeight(*ed_it, &tmp2);
2321  int_value_merged_region_1 =
2322  int_value_merged_region_1 + (float) tmp;
2323  number_of_bpoints_merged_region_1 =
2324  number_of_bpoints_merged_region_1 + (float) tmp2;
2325  }
2326 
2327  // compute integral of gradient and length of the merged region
2328  if ((vdata11 == merged_region_2 && vdata22 != merged_region_2) ||
2329  (vdata22 == merged_region_2 && vdata11 != merged_region_2)) {
2330  G_gradient.edgeWeight(*ed_it2, &tmp);
2331  G_blength.edgeWeight(*ed_it, &tmp2);
2332  int_value_merged_region_2 =
2333  int_value_merged_region_2 + (float) tmp;
2334  number_of_bpoints_merged_region_2 =
2335  number_of_bpoints_merged_region_2 + (float) tmp2;
2336  }
2337  }
2338 
2339  // LOOK INSIDE REGIONS, COMPUTE MEAN AND QUAD ERROR
2340  for (boost::tie(v_it, v_end) =
2341  boost::vertices(G_blength.getBoostGraph());
2342  v_it != v_end; ++v_it) {
2343  // Get label of the regions
2344  Tree_temp2.vertexData(*v_it, &vdata1);
2345  Tree_old_label.vertexData(*v_it, &vdata11);
2346 
2347  // compute mean and quad error
2348  if (vdata1 == label1) {
2349  // GET STATISTICS OF REGIONS AFTER MERGING
2350  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
2351  histogram_region1[dim_allouee1] =
2352  histogram_region1[dim_allouee1] +
2353  histogram[(int) *v_it][dim_allouee1];
2354  }
2355 
2356  if (vdata11 == merged_region_1) {
2357  merged_nodes1.push_back(*v_it);
2358 
2359  // GET STATISTICS OF REGIONS BEFORE MERGING
2360  for (int dim_allouee1 = 0; dim_allouee1 < 256;
2361  ++dim_allouee1) {
2362  histogram_region_merged_1[dim_allouee1] =
2363  histogram_region_merged_1[dim_allouee1] +
2364  histogram[(int) *v_it][dim_allouee1];
2365  }
2366  }
2367 
2368  if (vdata11 == merged_region_2) {
2369  merged_nodes2.push_back(*v_it);
2370 
2371  // GET STATISTICS OF REGIONS BEFORE MERGING
2372  for (int dim_allouee1 = 0; dim_allouee1 < 256;
2373  ++dim_allouee1) {
2374  histogram_region_merged_2[dim_allouee1] =
2375  histogram_region_merged_2[dim_allouee1] +
2376  histogram[(int) *v_it][dim_allouee1];
2377  }
2378  }
2379  }
2380  }
2381 
2382  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
2383  mean_value_in1 =
2384  mean_value_in1 + (float) dim_allouee1 *
2385  (float) histogram_region1[dim_allouee1];
2386  nb_val_in1 = nb_val_in1 + (float) histogram_region1[dim_allouee1];
2387 
2388  mean_value_in_merged_region_1 =
2389  mean_value_in_merged_region_1 +
2390  (float) dim_allouee1 *
2391  (float) histogram_region_merged_1[dim_allouee1];
2392  nb_val_in_merged_region_1 =
2393  nb_val_in_merged_region_1 +
2394  (float) histogram_region_merged_1[dim_allouee1];
2395 
2396  mean_value_in_merged_region_2 =
2397  mean_value_in_merged_region_2 +
2398  (float) dim_allouee1 *
2399  (float) histogram_region_merged_2[dim_allouee1];
2400  nb_val_in_merged_region_2 =
2401  nb_val_in_merged_region_2 +
2402  (float) histogram_region_merged_2[dim_allouee1];
2403  }
2404 
2405  // mean value of merged region
2406  mean_value_in1 = mean_value_in1 / nb_val_in1;
2407  mean_value_in_merged_region_1 =
2408  mean_value_in_merged_region_1 / nb_val_in_merged_region_1;
2409  mean_value_in_merged_region_2 =
2410  mean_value_in_merged_region_2 / nb_val_in_merged_region_2;
2411 
2412  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
2413  quad_error_in1 =
2414  quad_error_in1 + (float) histogram_region1[dim_allouee1] *
2415  ((float) dim_allouee1 - mean_value_in1) *
2416  ((float) dim_allouee1 - mean_value_in1);
2417  histogram_region1[dim_allouee1] = 0;
2418 
2419  quad_error_in_merged_region_1 =
2420  quad_error_in_merged_region_1 +
2421  (float) histogram_region_merged_1[dim_allouee1] *
2422  ((float) dim_allouee1 - mean_value_in_merged_region_1) *
2423  ((float) dim_allouee1 - mean_value_in_merged_region_1);
2424  histogram_region_merged_1[dim_allouee1] = 0;
2425 
2426  quad_error_in_merged_region_2 =
2427  quad_error_in_merged_region_2 +
2428  (float) histogram_region_merged_2[dim_allouee1] *
2429  ((float) dim_allouee1 - mean_value_in_merged_region_2) *
2430  ((float) dim_allouee1 - mean_value_in_merged_region_2);
2431  histogram_region_merged_2[dim_allouee1] = 0;
2432  }
2433 
2434  // float v_1 = (1.0f/(nb_val_in1-1) ) * quad_error_in1 ;
2435  // float v_m1 = (1.0f/(nb_val_in_merged_region_1-1) ) *
2436  // quad_error_in_merged_region_1 ; float v_m2 =
2437  // (1.0f/(nb_val_in_merged_region_2-1) ) *
2438  // quad_error_in_merged_region_2 ;
2439 
2440  // std::cout<<"mean_value_in1 = "<<mean_value_in1<<std::endl;
2441  // std::cout<<"v_1 = "<<v_1<<std::endl;
2442  //
2443  // std::cout<<"mean_value_in_merged_region_1 =
2444  // "<<mean_value_in_merged_region_1<<std::endl; std::cout<<"v_m1 =
2445  // "<<v_m1<<std::endl;
2446  //
2447  // std::cout<<"mean_value_in_merged_region_2 =
2448  // "<<mean_value_in_merged_region_2<<std::endl; std::cout<<"v_m2 =
2449  // "<<v_m2<<std::endl;
2450 
2451  quad_error_in1 = quad_error_in1 / 100.0f;
2452  quad_error_in_merged_region_1 =
2453  quad_error_in_merged_region_1 / 100.0f;
2454  quad_error_in_merged_region_2 =
2455  quad_error_in_merged_region_2 / 100.0f;
2456 
2457  // COMPUTE AFFINE ENERGY FUNCTION OF THE NEW MERGED REGION
2458  float D1 = quad_error_in1; // quad error ;
2459  float C1 =
2460  int_value_1 +
2461  number_of_bpoints1; // int_value_1 ; /// number_of_bpoints1 ; //
2462  // mean gradient value;
2463 
2464  // COMPUTE AFFINE ENERGY FUNCTION OF REGIONS BEFORE MERGING
2465  float DS1 = quad_error_in_merged_region_1; // quad error ;
2466  float CS1 =
2467  int_value_merged_region_1 +
2468  number_of_bpoints_merged_region_1; // int_value_merged_region_1
2469  // ; ///
2470  // number_of_bpoints_merged_region_1
2471  // ; // mean gradient value;
2472 
2473  float DS2 = quad_error_in_merged_region_2; // quad error ;
2474  float CS2 =
2475  int_value_merged_region_2 +
2476  number_of_bpoints_merged_region_2; // int_value_merged_region_2
2477  // ; ///
2478  // number_of_bpoints_merged_region_2
2479  // ; // mean gradient value;
2480 
2481  // Compute intersection between the two affine enrgies E1 = D1 +
2482  // lambda * C1 and ES1 + ES2 = DS1 + lambda * CS2 + DS2 + lambda *
2483  // CS2 intersection gives the scale of appearance lambda of the
2484  // frontier of the merged region
2485  float valk =
2486  std::max(1000.0f * -(DS1 + DS2 - D1) / (CS1 + CS2 - C1), 0.0f);
2487  // float lambda_star = 10000.0f * sqrt( valk ) ;
2488  float E_star =
2489  100.0f * (D1 + C1 * (-(DS1 + DS2 - D1) / (CS1 + CS2 - C1)));
2490  float lambda_star = 10000.0f * valk;
2491 
2492  // Tree_out.setVertexData(val-1,0);
2493 
2494  /*while( merged_nodes1.size() > 0 ){
2495 
2496  vs = merged_nodes1.back();
2497  merged_nodes1.pop_back();
2498 
2499 
2500  Tree_out2.vertexData(vs,&vdata2);
2501 
2502  if( vdata2 == 0 ){
2503  Tree_out2.setVertexData(vs, E_star ) ;
2504  Tree_out.setVertexData(vs, lambda_star ) ;
2505  }
2506  else{
2507  if( vdata2 > E_star ){
2508  Tree_out2.setVertexData(vs, E_star ) ;
2509  Tree_out.setVertexData(vs, lambda_star ) ;
2510  }
2511  }
2512  }
2513 
2514 
2515  while( merged_nodes2.size() > 0 ){
2516  vs = merged_nodes2.back();
2517  merged_nodes2.pop_back();
2518 
2519 
2520  Tree_out2.vertexData(vs,&vdata2);
2521  if( vdata2 == 0 ){
2522  Tree_out2.setVertexData(vs, E_star ) ;
2523  Tree_out.setVertexData(vs, lambda_star ) ;
2524  }
2525  else{
2526  if( vdata2 > E_star ){
2527  Tree_out2.setVertexData(vs, E_star ) ;
2528  Tree_out.setVertexData(vs, lambda_star ) ;
2529  }
2530  }
2531  }*/
2532 
2533  std::cout << lambda_star << std::endl;
2534 
2535  /*boost::tie(e1, in1) = boost::edge( Tree_ordered.edgeSource(e1) ,
2536  Tree_ordered.edgeTarget(e1) , Tree_out.getBoostGraph());
2537  Tree_out.setEdgeWeight(e1 , std::max( lambda_star , 0.0f ) );
2538 
2539  boost::tie(e1, in1) = boost::edge( Tree_ordered.edgeSource(e1) ,
2540  Tree_ordered.edgeTarget(e1) , Tree_out2.getBoostGraph());
2541  Tree_out2.setEdgeWeight(e1 , std::max( E_star , 0.0f ) );*/
2542 
2543  while (frontiers_edges.size() > 0) {
2544  ef = frontiers_edges.back();
2545  frontiers_edges.pop_back();
2546 
2547  boost::tie(e1, in1) = boost::edge(G_blength.edgeSource(ef),
2548  G_blength.edgeTarget(ef),
2549  Tree_out2.getBoostGraph());
2550 
2551  if (in1) {
2552  Tree_out2.edgeWeight(e1, &tmp);
2553  if (tmp == 0)
2554  Tree_out2.setEdgeWeight(e1, lambda_star);
2555  else
2556  Tree_out2.setEdgeWeight(
2557  e1, std::max((float) lambda_star, (float) tmp));
2558  }
2559  }
2560 
2561  // Go trough merged regions chack if there is higher lambda values,
2562  // in wich case we have to decrease them
2563  while (inside_edges.size() > 0) {
2564  ef = inside_edges.back();
2565  inside_edges.pop_back();
2566 
2567  boost::tie(e1, in1) = boost::edge(G_blength.edgeSource(ef),
2568  G_blength.edgeTarget(ef),
2569  Tree_out2.getBoostGraph());
2570 
2571  if (in1) {
2572  Tree_out2.edgeWeight(e1, &tmp);
2573  if (tmp > lambda_star)
2574  Tree_out2.setEdgeWeight(e1, lambda_star);
2575  }
2576  }
2577 
2578  inside_edges.clear();
2579  frontiers_edges.clear();
2580  merged_nodes1.clear();
2581  merged_nodes2.clear();
2582 
2583  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
2584  histogram_region1[dim_allouee1] = 0;
2585  histogram_region_merged_1[dim_allouee1] = 0;
2586  histogram_region_merged_2[dim_allouee1] = 0;
2587  }
2588 
2589  } // label1 != 0 // do not compute the same region multiple
2590  // times....
2591  } // while( added_edges.size() > 0 ){
2592 
2593  while (last_edge_value == last_analyzed) {
2594  last_edge_value = val_edges.back();
2595  val_edges.pop_back();
2596  }
2597  last_analyzed = last_edge_value;
2598  } // while( val_edges.size() > 0 || number_of_connected_components >= 2 ){
2599 
2600  std::cout << "current_max_value = " << current_max_value << std::endl;
2601 
2602  morphee::Morpho_Graph::t_Order_Edges_Weights(Tree_out2, Tree_out);
2603 
2604  for (boost::tie(ed_it, ed_end) = boost::edges(Tree_out.getBoostGraph());
2605  ed_it != ed_end; ++ed_it) {
2606  Tree_out.edgeWeight(*ed_it, &tmp);
2607  if (tmp > current_max_value)
2608  current_max_value = tmp;
2609  }
2610 
2611  for (boost::tie(ed_it, ed_end) = boost::edges(Tree_out.getBoostGraph());
2612  ed_it != ed_end; ++ed_it) {
2613  Tree_out.edgeWeight(*ed_it, &tmp);
2614  float value_test = 65535.0f * ((float) tmp / current_max_value);
2615  Tree_out.setEdgeWeight(*ed_it, value_test);
2616  }
2617 
2618  // for (boost::tie(v_it, v_end)=boost::vertices(Tree_out.getBoostGraph())
2619  // ; v_it != v_end ; ++v_it)
2620  //{
2621  // Tree_out.vertexData( *v_it, &vdata1);
2622  // if ( vdata1 > current_max_value) current_max_value = vdata1 ;
2623  //}
2624 
2625  // for (boost::tie(v_it, v_end)=boost::vertices(Tree_out.getBoostGraph())
2626  // ; v_it != v_end ; ++v_it)
2627  //{
2628  // Tree_out.vertexData( *v_it, &vdata1);
2629  // float value_test = 65535.0f * ( (float) vdata1 / current_max_value );
2630  // Tree_out.setVertexData(*v_it, value_test );
2631  //}
2632 
2633  return RES_OK;
2634  }
2635 
2636  template <class ImageWs, class ImageIn, class ImageGrad, typename _alpha1,
2637  class SE, class BoostGraph>
2638  RES_C t_MSMinCutInHierarchy(const ImageWs &imWs, const ImageIn &imIn,
2639  const ImageGrad &imGrad, const _alpha1 alpha1,
2640  const BoostGraph &Treein, const SE &nl,
2641  BoostGraph &Tree_out)
2642  {
2643  MORPHEE_ENTER_FUNCTION("t_MSMinCutInHierarchy");
2644 
2645  // SCALE SET HIERARCHY FUNCTION
2646  if ((!imWs.isAllocated())) {
2647  MORPHEE_REGISTER_ERROR("Not allocated");
2648  return RES_NOT_ALLOCATED;
2649  }
2650 
2651  if ((!imIn.isAllocated())) {
2652  MORPHEE_REGISTER_ERROR("Not allocated");
2653  return RES_NOT_ALLOCATED;
2654  }
2655 
2656  if ((!imGrad.isAllocated())) {
2657  MORPHEE_REGISTER_ERROR("Not allocated");
2658  return RES_NOT_ALLOCATED;
2659  }
2660 
2661  // common image iterator
2662  typename ImageWs::const_iterator it, iend;
2663  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
2664  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
2665  offset_t o0;
2666  offset_t o1;
2667 
2668  typename BoostGraph::EdgeIterator ed_it, ed_end;
2669  typename BoostGraph::EdgeIterator ed_it2, ed_end2;
2670  typename BoostGraph::EdgeIterator ed_it3, ed_end3;
2671  typename BoostGraph::EdgeIterator ed_it4, ed_end4;
2672 
2673  typename BoostGraph::VertexIterator v_it, v_end;
2674 
2675  typename BoostGraph::VertexProperty vdata1, vdata2, vdata11, vdata22;
2676  typename BoostGraph::VertexProperty label1, label2;
2677 
2678  bool in1;
2679  int numVert = 0;
2680  int numEdges = 0;
2681  typename BoostGraph::EdgeDescriptor e1, e2;
2682  typename BoostGraph::VertexDescriptor vs, vt;
2683  typename BoostGraph::EdgeProperty tmp, tmp2, tmp3;
2684 
2685  std::vector<double> val_edges;
2686  val_edges.push_back(0.0);
2687 
2688  float lambda = (float) alpha1;
2689 
2690  std::cout << "Compute number of regions" << std::endl;
2691 
2692  for (it = imWs.begin(), iend = imWs.end(); it != iend;
2693  ++it) // for all pixels in imIn create a vertex
2694  {
2695  o0 = it.getOffset();
2696  int val = imWs.pixelFromOffset(o0);
2697 
2698  if (val > numVert) {
2699  numVert = val;
2700  }
2701  }
2702  // BMI
2703  INT32 imsize = imWs.getXSize() * imWs.getYSize() * imWs.getZSize();
2704  F_DOUBLE var_norm_factor =
2705  1. / (static_cast<F_DOUBLE>(imsize) * 256. * 256.);
2706  // END BMI
2707  // create some temp graphs
2708  Tree_out = morphee::graph::CommonGraph32(numVert);
2709  Tree_out = t_CopyGraph(Treein);
2710  // copy of input tree
2711  BoostGraph Tree_temp = morphee::graph::CommonGraph32(numVert);
2712  BoostGraph Tree_ordered = morphee::graph::CommonGraph32(numVert);
2713  BoostGraph Tree_temp2 = morphee::graph::CommonGraph32(numVert);
2714  BoostGraph Tree_old_label = morphee::graph::CommonGraph32(numVert);
2715 
2716  // G_gradient : contain integral of gradient along boundaries
2717  BoostGraph G_gradient = morphee::graph::CommonGraph32(numVert);
2718  // G_blength : contain length of boundaries
2719  BoostGraph G_blength = morphee::graph::CommonGraph32(numVert);
2720 
2721  std::cout << "1) Compute statistics of each regions : ... " << std::endl;
2722  std::vector<double> mean_values;
2723  std::vector<double> number_of_values;
2724  std::vector<double> quad_error;
2725 
2726  float x_star = 0.0f;
2727  float sum_gradient = 0.0f;
2728 
2729  int **histogram; // image histogram
2730  histogram = new int *[numVert];
2731 
2732  float *histogram_region1; // region 1 histogram
2733  histogram_region1 = new float[256];
2734 
2735  float *histogram_region_merged_1; // region 1 histogram
2736  histogram_region_merged_1 = new float[256];
2737 
2738  float *histogram_region_merged_2; // region 1 histogram
2739  histogram_region_merged_2 = new float[256];
2740 
2741  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
2742  histogram_region1[dim_allouee1] = 0;
2743  histogram_region_merged_1[dim_allouee1] = 0;
2744  histogram_region_merged_2[dim_allouee1] = 0;
2745  }
2746 
2747  for (int dim_allouee0 = 0; dim_allouee0 < numVert; ++dim_allouee0) {
2748  histogram[dim_allouee0] = new int[256];
2749  }
2750 
2751  for (int dim_allouee0 = 0; dim_allouee0 < numVert; ++dim_allouee0) {
2752  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
2753  histogram[dim_allouee0][dim_allouee1] = 0;
2754  }
2755  }
2756 
2758  for (int i = 0; i < numVert; i++) {
2759  mean_values.push_back(0);
2760  number_of_values.push_back(0);
2761  quad_error.push_back(0);
2762  }
2763 
2765  for (it = imWs.begin(), iend = imWs.end(); it != iend;
2766  ++it) // for all pixels in imIn create a vertex
2767  {
2768  o1 = it.getOffset();
2769  int val = imWs.pixelFromOffset(o1);
2770  double val_image = imIn.pixelFromOffset(o1);
2771 
2772  mean_values[val - 1] = mean_values[val - 1] + val_image;
2773  number_of_values[val - 1] = number_of_values[val - 1] + 1.0;
2774 
2775  int vald = (int) (val_image);
2776  histogram[val - 1][vald] = histogram[val - 1][vald] + 1;
2777  }
2778 
2780  for (int i = 0; i < numVert; i++) {
2781  mean_values[i] = mean_values[i] / number_of_values[i];
2782  }
2783 
2785  float max_quad_val = 0.0f;
2786  int total_length = 0;
2787  for (it = imWs.begin(), iend = imWs.end(); it != iend;
2788  ++it) // for all pixels in imIn create a vertex and an edge
2789  {
2790  o1 = it.getOffset();
2791  int val = imWs.pixelFromOffset(o1);
2792  double val_image = imIn.pixelFromOffset(o1);
2793 
2794  // Label regions
2795  Tree_out.setVertexData(val - 1, val);
2796 
2797  // quadratic error
2798  quad_error[val - 1] =
2799  (double) quad_error[val - 1] +
2800  std::pow(std::abs(val_image - (double) mean_values[val - 1]), 2);
2801 
2802  // Gradient integral and regions boundaries length
2803  if (val > 0) {
2804  neighb.setCenter(o1);
2805 
2806  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
2807  const offset_t o2 = nit.getOffset();
2808  int val2 = imWs.pixelFromOffset(o2);
2809 
2810  if (o2 > o1) {
2811  if (val != val2) {
2812  boost::tie(e1, in1) =
2813  boost::edge(val - 1, val2 - 1, G_gradient.getBoostGraph());
2814  boost::tie(e2, in1) =
2815  boost::edge(val - 1, val2 - 1, G_blength.getBoostGraph());
2816 
2817  double val3 = imGrad.pixelFromOffset(o1);
2818  double val4 = imGrad.pixelFromOffset(o2);
2819  double maxi = std::max(val3, val4);
2820  sum_gradient =
2821  sum_gradient + 1.0f / (1.0f + 100.0f * (maxi / 65535.0f) *
2822  (maxi / 65535.0f));
2823 
2824  if (in1 == 0) {
2825  numEdges++;
2826  G_gradient.addEdge(val - 1, val2 - 1,
2827  1.0f / (1.0f + 100.0f * (maxi / 65535.0f) *
2828  (maxi / 65535.0f)));
2829  G_blength.addEdge(val - 1, val2 - 1, 1);
2830  total_length += 1;
2831  } else {
2832  G_gradient.edgeWeight(e1, &tmp);
2833  G_gradient.setEdgeWeight(
2834  e1, tmp + 1.0f / (1.0f + 100.0f * (maxi / 65535.0f) *
2835  (maxi / 65535.0f)));
2836 
2837  G_blength.edgeWeight(e2, &tmp2);
2838  G_blength.setEdgeWeight(e2, tmp2 + 1);
2839  total_length += 1;
2840  }
2841  }
2842  }
2843  }
2844  }
2845  }
2846  F_DOUBLE length_norm_factor = 1. / total_length;
2847  std::cout << "length_factor = " << length_norm_factor << "\n";
2848 
2849  std::cout << "1) Compute statistics of each regions : done !"
2850  << std::endl;
2851 
2852  std::cout << "Number of of Tree Edges : " << numEdges << std::endl;
2853 
2854  std::cout << "2) Go through hierarchy in ascendant order ... "
2855  << std::endl;
2856 
2857  // ENSURE THAT ONLY TWO REGIONS CAN BE MERGED AT EACH STEP
2858  morphee::Morpho_Graph::t_Order_Edges_Weights(Treein, Tree_ordered);
2859 
2860  boost::tie(ed_it2, ed_end2) = boost::edges(Tree_out.getBoostGraph());
2861 
2862  for (boost::tie(ed_it, ed_end) =
2863  boost::edges(Tree_ordered.getBoostGraph());
2864  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
2865  Tree_ordered.edgeWeight(*ed_it, &tmp);
2866  val_edges.push_back(tmp);
2867  Tree_out.setEdgeWeight(*ed_it2, 0);
2868  }
2869 
2870  // INIT TREETEMP
2871  Tree_temp = morphee::graph::CommonGraph32(numVert);
2872 
2873  std::vector<typename BoostGraph::EdgeDescriptor> added_edges;
2874  std::vector<typename BoostGraph::VertexDescriptor> merged_nodes1;
2875  std::vector<typename BoostGraph::VertexDescriptor> merged_nodes2;
2876 
2877  // sort edges weights to explore the hierarchy
2878  std::cout << "sort edges of tree" << std::endl;
2879  std::sort(val_edges.begin(), val_edges.end(), std::greater<double>());
2880 
2881  double last_edge_value = val_edges.back();
2882  double last_analyzed = last_edge_value;
2883  int current_label = numVert - 1;
2884  int number_of_connected_components = numVert;
2885 
2886  while (val_edges.size() > 0 || number_of_connected_components >= 2) {
2887  // std::cout<<last_edge_value<<std::endl;
2888  // BEFORE MERGING
2889  int number_of_old_connected_components;
2890  t_LabelConnectedComponent(Tree_temp, Tree_old_label,
2891  &number_of_old_connected_components);
2892 
2893  // add edge of minimal weight
2894  for (boost::tie(ed_it, ed_end) =
2895  boost::edges(Tree_ordered.getBoostGraph());
2896  ed_it != ed_end; ++ed_it) {
2897  Tree_ordered.edgeWeight(*ed_it, &tmp);
2898 
2899  if (tmp == last_edge_value) { // check if current min
2900 
2901  vs = Tree_ordered.edgeSource(*ed_it);
2902  vt = Tree_ordered.edgeTarget(*ed_it);
2903  boost::tie(e1, in1) =
2904  boost::add_edge(vs, vt, Tree_temp.getBoostGraph());
2905  added_edges.push_back(e1);
2906  }
2907  }
2908 
2909  // AFTER MERGING
2910  t_LabelConnectedComponent(Tree_temp, Tree_temp2,
2911  &number_of_connected_components);
2912  // std::cout<<"number_of_connected_components =
2913  //"<<number_of_connected_components<<std::endl;
2914 
2915  // go through removed edges and look caracteristics of regions connected
2916  // to it
2917  while (added_edges.size() > 0) {
2918  // local variable for mean values and areas of the merged region
2919  float int_value_1 = 0.0f;
2920  float number_of_bpoints1 = 0.0f;
2921  float mean_value_in1 = 0.0f;
2922  float quad_error_in1 = 0.0f;
2923  float nb_val_in1 = 0.0f;
2924 
2925  // local variable for mean values and areas of the regions before
2926  // merging
2927  int merged_region_1 = 0;
2928  float int_value_merged_region_1 = 0.0f;
2929  float number_of_bpoints_merged_region_1 = 0.0f;
2930  float mean_value_in_merged_region_1 = 0.0f;
2931  float quad_error_in_merged_region_1 = 0.0f;
2932  float nb_val_in_merged_region_1 = 0.0f;
2933 
2934  int merged_region_2 = 0;
2935  float int_value_merged_region_2 = 0.0f;
2936  float number_of_bpoints_merged_region_2 = 0.0f;
2937  float mean_value_in_merged_region_2 = 0.0f;
2938  float quad_error_in_merged_region_2 = 0.0f;
2939  float nb_val_in_merged_region_2 = 0.0f;
2940 
2941  // last added edges
2942  e1 = added_edges.back();
2943  added_edges.pop_back();
2944 
2945  // Get label of the regions : should be the same !!!
2946  Tree_temp2.vertexData(Tree_ordered.edgeSource(e1), &label1);
2947  Tree_temp2.vertexData(Tree_ordered.edgeTarget(e1), &label2);
2948 
2949  // Get old label of the regions : only two regions are merged at each
2950  // step !!
2951  Tree_old_label.vertexData(Tree_ordered.edgeSource(e1), &vdata1);
2952  merged_region_1 = (int) vdata1;
2953 
2954  Tree_old_label.vertexData(Tree_ordered.edgeTarget(e1), &vdata2);
2955  merged_region_2 = (int) vdata2;
2956 
2957  if (label1 != 0) {
2958  boost::tie(ed_it2, ed_end2) =
2959  boost::edges(G_gradient.getBoostGraph());
2960 
2961  for (boost::tie(ed_it, ed_end) =
2962  boost::edges(G_blength.getBoostGraph());
2963  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
2964  vs = G_blength.edgeSource(*ed_it);
2965  vt = G_blength.edgeTarget(*ed_it);
2966 
2967  // new label of the regions
2968  Tree_temp2.vertexData(vs, &vdata1);
2969  Tree_temp2.vertexData(vt, &vdata2);
2970 
2971  // old labels of the regions
2972  Tree_old_label.vertexData(vs, &vdata11);
2973  Tree_old_label.vertexData(vt, &vdata22);
2974 
2975  // compute integral of gradient and length of the merged region
2976  if ((vdata1 == label1 && vdata2 != label1) ||
2977  (vdata2 == label1 && vdata1 != label1)) {
2978  G_gradient.edgeWeight(*ed_it2, &tmp);
2979  G_blength.edgeWeight(*ed_it, &tmp2);
2980  int_value_1 = int_value_1 + (float) tmp;
2981  number_of_bpoints1 = number_of_bpoints1 + (float) tmp2;
2982  }
2983 
2984  // compute integral of gradient and length of the merged region
2985  if ((vdata11 == merged_region_1 && vdata22 != merged_region_1) ||
2986  (vdata22 == merged_region_1 && vdata11 != merged_region_1)) {
2987  G_gradient.edgeWeight(*ed_it2, &tmp);
2988  G_blength.edgeWeight(*ed_it, &tmp2);
2989  int_value_merged_region_1 =
2990  int_value_merged_region_1 + (float) tmp;
2991  number_of_bpoints_merged_region_1 =
2992  number_of_bpoints_merged_region_1 + (float) tmp2;
2993  }
2994 
2995  // compute integral of gradient and length of the merged region
2996  if ((vdata11 == merged_region_2 && vdata22 != merged_region_2) ||
2997  (vdata22 == merged_region_2 && vdata11 != merged_region_2)) {
2998  G_gradient.edgeWeight(*ed_it2, &tmp);
2999  G_blength.edgeWeight(*ed_it, &tmp2);
3000  int_value_merged_region_2 =
3001  int_value_merged_region_2 + (float) tmp;
3002  number_of_bpoints_merged_region_2 =
3003  number_of_bpoints_merged_region_2 + (float) tmp2;
3004  }
3005  }
3006 
3007  // LOOK INSIDE REGIONS, COMPUTE MEAN AND QUAD ERROR
3008  for (boost::tie(v_it, v_end) =
3009  boost::vertices(G_blength.getBoostGraph());
3010  v_it != v_end; ++v_it) {
3011  // Get label of the regions
3012  Tree_temp2.vertexData(*v_it, &vdata1);
3013  Tree_old_label.vertexData(*v_it, &vdata11);
3014 
3015  // compute mean and quad error
3016  if (vdata1 == label1) {
3017  // GET STATISTICS OF REGIONS AFTER MERGING
3018  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
3019  histogram_region1[dim_allouee1] =
3020  histogram_region1[dim_allouee1] +
3021  histogram[(int) *v_it][dim_allouee1];
3022  }
3023 
3024  if (vdata11 == merged_region_1) {
3025  merged_nodes1.push_back(*v_it);
3026 
3027  // GET STATISTICS OF REGIONS BEFORE MERGING
3028  for (int dim_allouee1 = 0; dim_allouee1 < 256;
3029  ++dim_allouee1) {
3030  histogram_region_merged_1[dim_allouee1] =
3031  histogram_region_merged_1[dim_allouee1] +
3032  histogram[(int) *v_it][dim_allouee1];
3033  }
3034  }
3035 
3036  if (vdata11 == merged_region_2) {
3037  merged_nodes2.push_back(*v_it);
3038 
3039  // GET STATISTICS OF REGIONS BEFORE MERGING
3040  for (int dim_allouee1 = 0; dim_allouee1 < 256;
3041  ++dim_allouee1) {
3042  histogram_region_merged_2[dim_allouee1] =
3043  histogram_region_merged_2[dim_allouee1] +
3044  histogram[(int) *v_it][dim_allouee1];
3045  }
3046  }
3047  }
3048  }
3049 
3050  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
3051  mean_value_in1 =
3052  mean_value_in1 + (float) dim_allouee1 *
3053  (float) histogram_region1[dim_allouee1];
3054  nb_val_in1 = nb_val_in1 + (float) histogram_region1[dim_allouee1];
3055 
3056  mean_value_in_merged_region_1 =
3057  mean_value_in_merged_region_1 +
3058  (float) dim_allouee1 *
3059  (float) histogram_region_merged_1[dim_allouee1];
3060  nb_val_in_merged_region_1 =
3061  nb_val_in_merged_region_1 +
3062  (float) histogram_region_merged_1[dim_allouee1];
3063 
3064  mean_value_in_merged_region_2 =
3065  mean_value_in_merged_region_2 +
3066  (float) dim_allouee1 *
3067  (float) histogram_region_merged_2[dim_allouee1];
3068  nb_val_in_merged_region_2 =
3069  nb_val_in_merged_region_2 +
3070  (float) histogram_region_merged_2[dim_allouee1];
3071  }
3072 
3073  // mean value of merged region
3074  mean_value_in1 = mean_value_in1 / nb_val_in1;
3075  mean_value_in_merged_region_1 =
3076  mean_value_in_merged_region_1 / nb_val_in_merged_region_1;
3077  mean_value_in_merged_region_2 =
3078  mean_value_in_merged_region_2 / nb_val_in_merged_region_2;
3079 
3080  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
3081  quad_error_in1 =
3082  quad_error_in1 + (float) histogram_region1[dim_allouee1] *
3083  ((float) dim_allouee1 - mean_value_in1) *
3084  ((float) dim_allouee1 - mean_value_in1);
3085  histogram_region1[dim_allouee1] = 0;
3086 
3087  quad_error_in_merged_region_1 =
3088  quad_error_in_merged_region_1 +
3089  (float) histogram_region_merged_1[dim_allouee1] *
3090  ((float) dim_allouee1 - mean_value_in_merged_region_1) *
3091  ((float) dim_allouee1 - mean_value_in_merged_region_1);
3092  histogram_region_merged_1[dim_allouee1] = 0;
3093 
3094  quad_error_in_merged_region_2 =
3095  quad_error_in_merged_region_2 +
3096  (float) histogram_region_merged_2[dim_allouee1] *
3097  ((float) dim_allouee1 - mean_value_in_merged_region_2) *
3098  ((float) dim_allouee1 - mean_value_in_merged_region_2);
3099  histogram_region_merged_2[dim_allouee1] = 0;
3100  }
3101 
3102  quad_error_in1 = quad_error_in1 / 100.0f;
3103  quad_error_in_merged_region_1 =
3104  quad_error_in_merged_region_1 / 100.0f;
3105  quad_error_in_merged_region_2 =
3106  quad_error_in_merged_region_2 / 100.0f;
3107 
3108  // COMPUTE AFFINE ENERGY FUNCTION OF THE NEW MERGED REGION
3109  float D1 = quad_error_in1; // quad error ;
3110  float C1 = number_of_bpoints1 +
3111  int_value_1; // int_value_1 ; /// number_of_bpoints1 ; //
3112  // mean gradient value;
3113  float E1 = D1 + lambda * C1;
3114 
3115  // COMPUTE AFFINE ENERGY FUNCTION OF REGIONS BEFORE MERGING
3116  float DS1 = quad_error_in_merged_region_1; // quad error ;
3117  float CS1 =
3118  number_of_bpoints_merged_region_1 +
3119  int_value_merged_region_1; // int_value_merged_region_1 ; ///
3120  // number_of_bpoints_merged_region_1
3121  // ; // mean gradient value;
3122  float ES1 = DS1 + lambda * CS1;
3123 
3124  float DS2 = quad_error_in_merged_region_2; // quad error ;
3125  float CS2 =
3126  number_of_bpoints_merged_region_2 +
3127  int_value_merged_region_2; // int_value_merged_region_2 ; ///
3128  // number_of_bpoints_merged_region_2
3129  // ; // mean gradient value;
3130  float ES2 = DS2 + lambda * CS2;
3131 
3132  // BMI Try to normalize
3133  float beta = 0.0005;
3134 
3135  D1 = quad_error_in1 * var_norm_factor; // quad error ;
3136  C1 = (number_of_bpoints1 + int_value_1) *
3137  length_norm_factor; // int_value_1 ; /// number_of_bpoints1 ;
3138  // // mean gradient value;
3139  E1 = D1 - lambda;
3140  E1 = D1 + lambda * C1;
3141 
3142  DS1 =
3143  quad_error_in_merged_region_1 * var_norm_factor; // quad error ;
3144  CS1 = (number_of_bpoints_merged_region_1 +
3145  int_value_merged_region_1) *
3146  length_norm_factor; // int_value_merged_region_1 ; ///
3147  // number_of_bpoints_merged_region_1 ; //
3148  // mean gradient value;
3149  ES1 = DS1 + lambda * CS1;
3150 
3151  DS2 =
3152  quad_error_in_merged_region_2 * var_norm_factor; // quad error ;
3153  CS2 = (number_of_bpoints_merged_region_2 +
3154  int_value_merged_region_2) *
3155  length_norm_factor; // int_value_merged_region_2 ; ///
3156  // number_of_bpoints_merged_region_2 ; //
3157  // mean gradient value;
3158  ES2 = DS2 + lambda * CS2;
3159  // BMI std::cout<<"D1 = "<<D1<<"; DS1 = "<<DS1<<"; DS2 =
3160  // "<<DS2<<"; sum = "<<DS1+DS2<<std::endl;
3161 
3162  // END BMI
3163 
3164  // Cut nodes of merged regions if merging increases the energy
3165  if (E1 < ES1 + ES2) {
3166  // std::cout<<"D1 = "<<D1<<std::endl;
3167  // std::cout<<"C1 = "<<C1<<std::endl;
3168  // std::cout<<"mean_value_in1 = " << mean_value_in1 <<std::endl;
3169 
3170  // std::cout<<"DS1 = "<<DS1<<std::endl;
3171  // std::cout<<"CS1 = "<<CS1<<std::endl;
3172  // std::cout<<"mean_value_in_merged_region_1 = " <<
3173  // mean_value_in_merged_region_1 <<std::endl;
3174  //
3175  // std::cout<<"DS2 = "<<DS2<<std::endl;
3176  // std::cout<<"CS2 = "<<CS2<<std::endl;
3177  // std::cout<<"mean_value_in_merged_region_2 = " <<
3178  // mean_value_in_merged_region_2 <<std::endl;
3179 
3180  // std::cout<< " merged_nodes1.size() = " << merged_nodes1.size()
3181  // <<std::endl; std::cout<< " merged_nodes2.size() = " <<
3182  // merged_nodes2.size() <<std::endl;
3183 
3184  while (merged_nodes1.size() > 0) {
3185  vs = merged_nodes1.back();
3186  merged_nodes1.pop_back();
3187  Tree_out.vertexData(vs, &vdata1);
3188  Tree_out.setVertexData(vs, current_label);
3189  }
3190 
3191  while (merged_nodes2.size() > 0) {
3192  vs = merged_nodes2.back();
3193  merged_nodes2.pop_back();
3194  Tree_out.vertexData(vs, &vdata1);
3195  Tree_out.setVertexData(vs, current_label);
3196  }
3197 
3198  current_label++;
3199 
3200  boost::tie(e1, in1) = boost::edge(Tree_ordered.edgeSource(e1),
3201  Tree_ordered.edgeTarget(e1),
3202  Tree_out.getBoostGraph());
3203  Tree_out.setEdgeWeight(e1, E1 - (ES1 + ES2));
3204  }
3205 
3206  merged_nodes1.clear();
3207  merged_nodes2.clear();
3208 
3209  for (int dim_allouee1 = 0; dim_allouee1 < 256; ++dim_allouee1) {
3210  histogram_region1[dim_allouee1] = 0;
3211  histogram_region_merged_1[dim_allouee1] = 0;
3212  histogram_region_merged_2[dim_allouee1] = 0;
3213  }
3214 
3215  } // label1 != 0 // do not compute the same region multiple
3216  // times....
3217  } // WHILE( added_edges.size() > 0 ){
3218 
3219  while (last_edge_value == last_analyzed) {
3220  last_edge_value = val_edges.back();
3221  val_edges.pop_back();
3222  }
3223  last_analyzed = last_edge_value;
3224  } // while( val_edges.size() > 0 || number_of_connected_components >= 2 ){
3225 
3226  return RES_OK;
3227  } // END t_MSMinCutInHierarchy
3228 
3229  template <class ImageIn, class ImageGrad, class SE, class BoostGraph>
3230  RES_C t_AverageLinkageTree_minimean(const ImageIn &imIn,
3231  const ImageGrad &imGrad, const SE &nl,
3232  BoostGraph &Tout)
3233  {
3234  MORPHEE_ENTER_FUNCTION("t_AverageLinkageTree");
3235 
3236  if ((!imIn.isAllocated())) {
3237  MORPHEE_REGISTER_ERROR("Not allocated");
3238  return RES_NOT_ALLOCATED;
3239  }
3240 
3241  if ((!imGrad.isAllocated())) {
3242  MORPHEE_REGISTER_ERROR("Not allocated");
3243  return RES_NOT_ALLOCATED;
3244  }
3245 
3246  // common image iterator
3247  typename ImageIn::const_iterator it, iend;
3248  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
3249  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
3250  offset_t o0;
3251  offset_t o1;
3252 
3253  typename BoostGraph::EdgeIterator ed_it, ed_end;
3254  typename BoostGraph::EdgeIterator ed_it2, ed_end2;
3255  typename BoostGraph::EdgeIterator ed_it3, ed_end3;
3256 
3257  typename BoostGraph::VertexProperty vdata1, vdata2;
3258  typename BoostGraph::VertexDescriptor v1_remove, v2_remove;
3259  typename BoostGraph::VertexProperty label1, label2;
3260 
3261  bool in1;
3262  int numVert = 0;
3263  int numEdges = 0;
3264  typename BoostGraph::EdgeDescriptor e1, e2, e3;
3265  typename BoostGraph::EdgeProperty tmp, tmp2, tmp3, tmp4;
3266 
3267  std::cout << "build Region Adjacency Graph" << std::endl;
3268 
3269  for (it = imIn.begin(), iend = imIn.end(); it != iend;
3270  ++it) // for all pixels in imIn create a vertex
3271  {
3272  o0 = it.getOffset();
3273  int val = imIn.pixelFromOffset(o0);
3274 
3275  if (val > numVert) {
3276  numVert = val;
3277  }
3278  }
3279 
3280  std::cout << "build Region Adjacency Graph Vertices" << std::endl;
3281  std::cout << "number of Vertices:" << numVert << std::endl;
3282 
3283  Tout = morphee::graph::CommonGraph32(numVert);
3284  BoostGraph Tout_label = morphee::graph::CommonGraph32(numVert);
3285  BoostGraph Tout_current = morphee::graph::CommonGraph32(numVert);
3286  BoostGraph Tout_current_temp = morphee::graph::CommonGraph32(numVert);
3287  BoostGraph Tout_current_mini = morphee::graph::CommonGraph32(numVert);
3288 
3289  BoostGraph Ttemp = morphee::graph::CommonGraph32(numVert);
3290  BoostGraph Ttemp_2 = morphee::graph::CommonGraph32(numVert);
3291  BoostGraph Ttemp_3 = morphee::graph::CommonGraph32(numVert);
3292 
3293  int number_of_edges = 0;
3294 
3295  std::cout << "build Region Adjacency Graph Edges" << std::endl;
3296 
3297  for (it = imIn.begin(), iend = imIn.end(); it != iend;
3298  ++it) // for all pixels in imIn create a vertex and an edge
3299  {
3300  o1 = it.getOffset();
3301  int val = imIn.pixelFromOffset(o1);
3302 
3303  if (val > 0) {
3304  neighb.setCenter(o1);
3305 
3306  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
3307  const offset_t o2 = nit.getOffset();
3308  int val2 = imIn.pixelFromOffset(o2);
3309 
3310  if (o2 > o1) {
3311  if (val != val2) {
3312  boost::tie(e1, in1) =
3313  boost::edge(val - 1, val2 - 1, Ttemp.getBoostGraph());
3314  boost::tie(e2, in1) =
3315  boost::edge(val - 1, val2 - 1, Ttemp_2.getBoostGraph());
3316  boost::tie(e3, in1) =
3317  boost::edge(val - 1, val2 - 1, Ttemp_3.getBoostGraph());
3318 
3319  double val3 = imGrad.pixelFromOffset(o1);
3320  double val4 = imGrad.pixelFromOffset(o2);
3321  double mini = std::max(val3, val4);
3322 
3323  if (in1 == 0) {
3324  Ttemp.addEdge(val - 1, val2 - 1, mini);
3325  Ttemp_2.addEdge(val - 1, val2 - 1, 1);
3326  Ttemp_3.addEdge(val - 1, val2 - 1, mini);
3327 
3328  number_of_edges = number_of_edges + 1;
3329  } else {
3330  Ttemp.edgeWeight(e1, &tmp);
3331  Ttemp.setEdgeWeight(e1, tmp + mini);
3332 
3333  Ttemp_2.edgeWeight(e2, &tmp2);
3334  Ttemp_2.setEdgeWeight(e2, tmp2 + 1);
3335 
3336  Ttemp_3.edgeWeight(e3, &tmp3);
3337  if (mini < tmp3)
3338  Ttemp_3.setEdgeWeight(e3, mini);
3339  }
3340  }
3341  }
3342  }
3343  }
3344  }
3345 
3346  std::cout << "Done" << std::endl;
3347 
3348  std::vector<double> val_edges;
3349  int current_index = 1;
3350 
3351  int num_connected_component;
3352  t_LabelConnectedComponent(Tout, Tout_label, &num_connected_component);
3353 
3354  Tout_current = morphee::graph::CommonGraph32(num_connected_component);
3355  Tout_current_temp =
3356  morphee::graph::CommonGraph32(num_connected_component);
3357  Tout_current_mini =
3358  morphee::graph::CommonGraph32(num_connected_component);
3359 
3360  std::cout << "num_connected_component : " << num_connected_component
3361  << std::endl;
3362  std::cout << "Tout.numEdges() :" << Tout.numEdges() << std::endl;
3363 
3364  std::cout << "construct region adjacency graph of connected components"
3365  << std::endl;
3366 
3367  boost::tie(ed_it2, ed_end2) = boost::edges(Ttemp_2.getBoostGraph());
3368  boost::tie(ed_it3, ed_end3) = boost::edges(Ttemp_3.getBoostGraph());
3369 
3370  for (boost::tie(ed_it, ed_end) = boost::edges(Ttemp.getBoostGraph());
3371  ed_it != ed_end, ed_it2 != ed_end2, ed_it3 != ed_end3;
3372  ++ed_it, ++ed_it2, ++ed_it3) {
3373  Tout_label.vertexData(Ttemp.edgeSource(*ed_it), &vdata1);
3374  Tout_label.vertexData(Ttemp.edgeTarget(*ed_it), &vdata2);
3375 
3376  if (vdata1 != vdata2) {
3377  boost::tie(e1, in1) = boost::edge((int) vdata1 - 1, (int) vdata2 - 1,
3378  Tout_current.getBoostGraph());
3379  boost::tie(e2, in1) = boost::edge((int) vdata1 - 1, (int) vdata2 - 1,
3380  Tout_current_temp.getBoostGraph());
3381  boost::tie(e3, in1) = boost::edge((int) vdata1 - 1, (int) vdata2 - 1,
3382  Tout_current_mini.getBoostGraph());
3383 
3384  Ttemp.edgeWeight(*ed_it, &tmp);
3385  Ttemp_2.edgeWeight(*ed_it2, &tmp2);
3386  Ttemp_3.edgeWeight(*ed_it3, &tmp4);
3387 
3388  if (in1 == 0) {
3389  Tout_current.addEdge((int) vdata1 - 1, (int) vdata2 - 1,
3390  ((double) tmp));
3391  Tout_current_temp.addEdge((int) vdata1 - 1, (int) vdata2 - 1,
3392  ((double) tmp2));
3393  Tout_current_mini.addEdge((int) vdata1 - 1, (int) vdata2 - 1,
3394  ((double) tmp3));
3395  } else {
3396  Tout_current.edgeWeight(e1, &tmp3);
3397  Tout_current.setEdgeWeight(e1, (double) tmp3 + ((double) tmp));
3398 
3399  Tout_current_temp.edgeWeight(e2, &tmp3);
3400  Tout_current_temp.setEdgeWeight(e2,
3401  (double) tmp3 + ((double) tmp2));
3402 
3403  Tout_current_mini.edgeWeight(e3, &tmp3);
3404  if (tmp4 < tmp3)
3405  Tout_current_temp.setEdgeWeight(e3, tmp4);
3406  }
3407  }
3408  }
3409 
3410  std::cout << "get edges values and sort them" << std::endl;
3411  // get edges values and sort them
3412 
3413  double min_edge_value = 10000000000000.0f;
3414  double minimum_value = 10000000000000.0f;
3415 
3416  boost::tie(ed_it2, ed_end2) =
3417  boost::edges(Tout_current_temp.getBoostGraph());
3418  boost::tie(ed_it3, ed_end3) =
3419  boost::edges(Tout_current_mini.getBoostGraph());
3420 
3421  for (boost::tie(ed_it, ed_end) =
3422  boost::edges(Tout_current.getBoostGraph());
3423  ed_it != ed_end, ed_it2 != ed_end2, ed_it3 != ed_end3;
3424  ++ed_it, ++ed_it2, ++ed_it3) {
3425  Tout_current.edgeWeight(*ed_it, &tmp);
3426  Tout_current_temp.edgeWeight(*ed_it2, &tmp2);
3427  Tout_current_mini.edgeWeight(*ed_it3, &tmp3);
3428 
3429  if (sqrt(((double) tmp3) * ((double) tmp / (double) tmp2)) <
3430  min_edge_value) {
3431  min_edge_value =
3432  sqrt(((double) tmp3) * ((double) tmp / (double) tmp2));
3433  v1_remove = Tout_current.edgeSource(*ed_it);
3434  v2_remove = Tout_current.edgeTarget(*ed_it);
3435  }
3436  }
3437 
3438  std::cout << "label trees" << std::endl;
3439  // label trees
3440  while (num_connected_component > 1) {
3441  std::cout << num_connected_component << std::endl;
3442 
3443  bool added_edge = false;
3444 
3445  while (added_edge == false) {
3446  boost::tie(ed_it2, ed_end2) = boost::edges(Ttemp_2.getBoostGraph());
3447 
3448  for (boost::tie(ed_it, ed_end) = boost::edges(Ttemp.getBoostGraph());
3449  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
3450  Tout_label.vertexData(Ttemp.edgeSource(*ed_it), &vdata1);
3451  Tout_label.vertexData(Ttemp.edgeTarget(*ed_it), &vdata2);
3452 
3453  if (((vdata1 - 1) == v1_remove && (vdata2 - 1) == v2_remove) ||
3454  ((vdata2 - 1) == v1_remove && (vdata1 - 1) == v2_remove)) {
3455  added_edge = true;
3456  Tout.addEdge(Ttemp.edgeSource(*ed_it), Ttemp.edgeTarget(*ed_it),
3457  min_edge_value);
3458  current_index = current_index + 1;
3459  }
3460 
3461  if (added_edge == true)
3462  break;
3463  }
3464  }
3465 
3466  // clear edges and update edges values
3467  t_LabelConnectedComponent(Tout, Tout_label, &num_connected_component);
3468 
3469  Tout_current = morphee::graph::CommonGraph32(num_connected_component);
3470  Tout_current_temp =
3471  morphee::graph::CommonGraph32(num_connected_component);
3472  Tout_current_mini =
3473  morphee::graph::CommonGraph32(num_connected_component);
3474 
3475  // construct region adjacency graph of connected components
3476  boost::tie(ed_it2, ed_end2) = boost::edges(Ttemp_2.getBoostGraph());
3477  boost::tie(ed_it3, ed_end3) = boost::edges(Ttemp_3.getBoostGraph());
3478 
3479  for (boost::tie(ed_it, ed_end) = boost::edges(Ttemp.getBoostGraph());
3480  ed_it != ed_end, ed_it2 != ed_end2, ed_it3 != ed_end3;
3481  ++ed_it, ++ed_it2, ++ed_it3) {
3482  Tout_label.vertexData(Ttemp.edgeSource(*ed_it), &vdata1);
3483  Tout_label.vertexData(Ttemp.edgeTarget(*ed_it), &vdata2);
3484 
3485  if (vdata1 != vdata2) {
3486  boost::tie(e1, in1) =
3487  boost::edge((int) vdata1 - 1, (int) vdata2 - 1,
3488  Tout_current.getBoostGraph());
3489  boost::tie(e2, in1) =
3490  boost::edge((int) vdata1 - 1, (int) vdata2 - 1,
3491  Tout_current_temp.getBoostGraph());
3492  boost::tie(e3, in1) =
3493  boost::edge((int) vdata1 - 1, (int) vdata2 - 1,
3494  Tout_current_mini.getBoostGraph());
3495 
3496  Ttemp.edgeWeight(*ed_it, &tmp);
3497  Ttemp_2.edgeWeight(*ed_it2, &tmp2);
3498  Ttemp_3.edgeWeight(*ed_it3, &tmp4);
3499 
3500  if (in1 == 0) {
3501  Tout_current.addEdge((int) vdata1 - 1, (int) vdata2 - 1,
3502  ((double) tmp));
3503  Tout_current_temp.addEdge((int) vdata1 - 1, (int) vdata2 - 1,
3504  ((double) tmp2));
3505  Tout_current_mini.addEdge((int) vdata1 - 1, (int) vdata2 - 1,
3506  ((double) tmp3));
3507  } else {
3508  Tout_current.edgeWeight(e1, &tmp3);
3509  Tout_current.setEdgeWeight(e1, (double) tmp3 + ((double) tmp));
3510 
3511  Tout_current_temp.edgeWeight(e2, &tmp3);
3512  Tout_current_temp.setEdgeWeight(e2,
3513  (double) tmp3 + ((double) tmp2));
3514 
3515  Tout_current_mini.edgeWeight(e3, &tmp3);
3516  if (tmp4 < tmp3)
3517  Tout_current_temp.setEdgeWeight(e3, tmp4);
3518  }
3519  }
3520  }
3521 
3522  min_edge_value = 10000000000000.0f;
3523  boost::tie(ed_it2, ed_end2) =
3524  boost::edges(Tout_current_temp.getBoostGraph());
3525  boost::tie(ed_it3, ed_end3) =
3526  boost::edges(Tout_current_mini.getBoostGraph());
3527 
3528  for (boost::tie(ed_it, ed_end) =
3529  boost::edges(Tout_current.getBoostGraph());
3530  ed_it != ed_end, ed_it2 != ed_end2, ed_it3 != ed_end3;
3531  ++ed_it, ++ed_it2, ++ed_it3) {
3532  Tout_current.edgeWeight(*ed_it, &tmp);
3533  Tout_current_temp.edgeWeight(*ed_it2, &tmp2);
3534  Tout_current_mini.edgeWeight(*ed_it3, &tmp3);
3535 
3536  if (sqrt(((double) tmp3) * ((double) tmp / (double) tmp2)) <
3537  min_edge_value) {
3538  min_edge_value =
3539  sqrt(((double) tmp3) * ((double) tmp / (double) tmp2));
3540  v1_remove = Tout_current.edgeSource(*ed_it);
3541  v2_remove = Tout_current.edgeTarget(*ed_it);
3542  }
3543  }
3544  }
3545 
3546  return RES_OK;
3547  }
3548 
3549  template <class ImageIn, class ImageGrad, class SE, class BoostGraph>
3550  RES_C t_AverageLinkageTree(const ImageIn &imIn, const ImageGrad &imGrad,
3551  const SE &nl, BoostGraph &Tout)
3552  {
3553  MORPHEE_ENTER_FUNCTION("t_AverageLinkageTree");
3554 
3555  if ((!imIn.isAllocated())) {
3556  MORPHEE_REGISTER_ERROR("Not allocated");
3557  return RES_NOT_ALLOCATED;
3558  }
3559 
3560  if ((!imGrad.isAllocated())) {
3561  MORPHEE_REGISTER_ERROR("Not allocated");
3562  return RES_NOT_ALLOCATED;
3563  }
3564 
3565  // common image iterator
3566  typename ImageIn::const_iterator it, iend;
3567  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
3568  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
3569  offset_t o0;
3570  offset_t o1;
3571 
3572  typename BoostGraph::EdgeIterator ed_it, ed_end;
3573  typename BoostGraph::EdgeIterator ed_it2, ed_end2;
3574 
3575  typename BoostGraph::VertexProperty vdata1, vdata2;
3576  typename BoostGraph::VertexDescriptor v1_remove, v2_remove;
3577  typename BoostGraph::VertexProperty label1, label2;
3578 
3579  bool in1;
3580  int numVert = 0;
3581  int numEdges = 0;
3582  typename BoostGraph::EdgeDescriptor e1, e2;
3583  typename BoostGraph::EdgeProperty tmp, tmp2, tmp3;
3584 
3585  std::cout << "build Region Adjacency Graph" << std::endl;
3586 
3587  for (it = imIn.begin(), iend = imIn.end(); it != iend;
3588  ++it) // for all pixels in imIn create a vertex
3589  {
3590  o0 = it.getOffset();
3591  int val = imIn.pixelFromOffset(o0);
3592 
3593  if (val > numVert) {
3594  numVert = val;
3595  }
3596  }
3597 
3598  std::cout << "build Region Adjacency Graph Vertices" << std::endl;
3599  std::cout << "number of Vertices:" << numVert << std::endl;
3600 
3601  Tout = morphee::graph::CommonGraph32(numVert);
3602  BoostGraph Tout_label = morphee::graph::CommonGraph32(numVert);
3603  BoostGraph Tout_current = morphee::graph::CommonGraph32(numVert);
3604  BoostGraph Tout_current_temp = morphee::graph::CommonGraph32(numVert);
3605 
3606  BoostGraph Ttemp = morphee::graph::CommonGraph32(numVert);
3607  BoostGraph Ttemp_2 = morphee::graph::CommonGraph32(numVert);
3608 
3609  int number_of_edges = 0;
3610 
3611  std::cout << "build Region Adjacency Graph Edges" << std::endl;
3612 
3613  for (it = imIn.begin(), iend = imIn.end(); it != iend;
3614  ++it) // for all pixels in imIn create a vertex and an edge
3615  {
3616  o1 = it.getOffset();
3617  int val = imIn.pixelFromOffset(o1);
3618 
3619  if (val > 0) {
3620  neighb.setCenter(o1);
3621 
3622  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
3623  const offset_t o2 = nit.getOffset();
3624  int val2 = imIn.pixelFromOffset(o2);
3625 
3626  if (o2 > o1) {
3627  if (val != val2) {
3628  boost::tie(e1, in1) =
3629  boost::edge(val - 1, val2 - 1, Ttemp.getBoostGraph());
3630  boost::tie(e2, in1) =
3631  boost::edge(val - 1, val2 - 1, Ttemp_2.getBoostGraph());
3632 
3633  double val3 = imGrad.pixelFromOffset(o1);
3634  double val4 = imGrad.pixelFromOffset(o2);
3635  double mini = std::max(val3, val4);
3636 
3637  if (in1 == 0) {
3638  Ttemp.addEdge(val - 1, val2 - 1, mini);
3639  Ttemp_2.addEdge(val - 1, val2 - 1, 1);
3640  number_of_edges = number_of_edges + 1;
3641  } else {
3642  Ttemp.edgeWeight(e1, &tmp);
3643  Ttemp.setEdgeWeight(e1, tmp + mini);
3644 
3645  Ttemp_2.edgeWeight(e2, &tmp2);
3646  Ttemp_2.setEdgeWeight(e2, tmp2 + 1);
3647  }
3648  }
3649  }
3650  }
3651  }
3652  }
3653 
3654  std::cout << "Done" << std::endl;
3655 
3656  std::vector<double> val_edges;
3657  int current_index = 1;
3658  int num_connected_component;
3659  t_LabelConnectedComponent(Tout, Tout_label, &num_connected_component);
3660 
3661  Tout_current = morphee::graph::CommonGraph32(num_connected_component);
3662  Tout_current_temp =
3663  morphee::graph::CommonGraph32(num_connected_component);
3664 
3665  std::cout << "num_connected_component : " << num_connected_component
3666  << std::endl;
3667  std::cout << "Tout.numEdges() :" << Tout.numEdges() << std::endl;
3668 
3669  std::cout << "construct region adjacency graph of connected components"
3670  << std::endl;
3671 
3672  boost::tie(ed_it2, ed_end2) = boost::edges(Ttemp_2.getBoostGraph());
3673 
3674  for (boost::tie(ed_it, ed_end) = boost::edges(Ttemp.getBoostGraph());
3675  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
3676  Tout_label.vertexData(Ttemp.edgeSource(*ed_it), &vdata1);
3677  Tout_label.vertexData(Ttemp.edgeTarget(*ed_it), &vdata2);
3678 
3679  if (vdata1 != vdata2) {
3680  boost::tie(e1, in1) = boost::edge((int) vdata1 - 1, (int) vdata2 - 1,
3681  Tout_current.getBoostGraph());
3682  boost::tie(e2, in1) = boost::edge((int) vdata1 - 1, (int) vdata2 - 1,
3683  Tout_current_temp.getBoostGraph());
3684 
3685  Ttemp.edgeWeight(*ed_it, &tmp);
3686  Ttemp_2.edgeWeight(*ed_it2, &tmp2);
3687 
3688  if (in1 == 0) {
3689  Tout_current.addEdge((int) vdata1 - 1, (int) vdata2 - 1,
3690  ((double) tmp));
3691  Tout_current_temp.addEdge((int) vdata1 - 1, (int) vdata2 - 1,
3692  ((double) tmp2));
3693  } else {
3694  Tout_current.edgeWeight(e1, &tmp3);
3695  Tout_current.setEdgeWeight(e1, (double) tmp3 + ((double) tmp));
3696 
3697  Tout_current_temp.edgeWeight(e2, &tmp3);
3698  Tout_current_temp.setEdgeWeight(e2,
3699  (double) tmp3 + ((double) tmp2));
3700  }
3701  }
3702  }
3703 
3704  std::cout << "get edges values and sort them" << std::endl;
3705  // get edges values and sort them
3706 
3707  double min_edge_value = 10000000000000.0f;
3708  double minimum_value = 10000000000000.0f;
3709 
3710  boost::tie(ed_it2, ed_end2) =
3711  boost::edges(Tout_current_temp.getBoostGraph());
3712  for (boost::tie(ed_it, ed_end) =
3713  boost::edges(Tout_current.getBoostGraph());
3714  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
3715  Tout_current.edgeWeight(*ed_it, &tmp);
3716  Tout_current_temp.edgeWeight(*ed_it2, &tmp2);
3717 
3718  if (((double) tmp / (double) tmp2) < min_edge_value) {
3719  min_edge_value = (double) tmp / (double) tmp2;
3720  v1_remove = Tout_current.edgeSource(*ed_it);
3721  v2_remove = Tout_current.edgeTarget(*ed_it);
3722  }
3723  }
3724 
3725  std::cout << "label trees" << std::endl;
3726  // label trees
3727  while (num_connected_component > 1) { // TOTO
3728 
3729  std::cout << num_connected_component << std::endl;
3730 
3731  bool added_edge = false;
3732 
3733  while (added_edge == false) {
3734  boost::tie(ed_it2, ed_end2) = boost::edges(Ttemp_2.getBoostGraph());
3735 
3736  for (boost::tie(ed_it, ed_end) = boost::edges(Ttemp.getBoostGraph());
3737  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
3738  Tout_label.vertexData(Ttemp.edgeSource(*ed_it), &vdata1);
3739  Tout_label.vertexData(Ttemp.edgeTarget(*ed_it), &vdata2);
3740 
3741  if (((vdata1 - 1) == v1_remove && (vdata2 - 1) == v2_remove) ||
3742  ((vdata2 - 1) == v1_remove && (vdata1 - 1) == v2_remove)) {
3743  added_edge = true;
3744  std::cout << "ADDED_EDGE" << vdata1 << "," << vdata2 << std::endl;
3745 
3746  Tout.addEdge(Ttemp.edgeSource(*ed_it), Ttemp.edgeTarget(*ed_it),
3747  min_edge_value);
3748  current_index = current_index + 1;
3749  }
3750 
3751  if (added_edge == true)
3752  break;
3753  }
3754  }
3755 
3756  // clear edges and update edges values
3757  t_LabelConnectedComponent(Tout, Tout_label, &num_connected_component);
3758  std::cout << "after clear edges" << num_connected_component
3759  << std::endl;
3760 
3761  Tout_current = morphee::graph::CommonGraph32(num_connected_component);
3762  Tout_current_temp =
3763  morphee::graph::CommonGraph32(num_connected_component);
3764 
3765  // construct region adjacency graph of connected components
3766  boost::tie(ed_it2, ed_end2) = boost::edges(Ttemp_2.getBoostGraph());
3767  for (boost::tie(ed_it, ed_end) = boost::edges(Ttemp.getBoostGraph());
3768  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
3769  Tout_label.vertexData(Ttemp.edgeSource(*ed_it), &vdata1);
3770  Tout_label.vertexData(Ttemp.edgeTarget(*ed_it), &vdata2);
3771 
3772  if (vdata1 != vdata2) {
3773  boost::tie(e1, in1) =
3774  boost::edge((int) vdata1 - 1, (int) vdata2 - 1,
3775  Tout_current.getBoostGraph());
3776  boost::tie(e2, in1) =
3777  boost::edge((int) vdata1 - 1, (int) vdata2 - 1,
3778  Tout_current_temp.getBoostGraph());
3779 
3780  Ttemp.edgeWeight(*ed_it, &tmp);
3781  Ttemp_2.edgeWeight(*ed_it2, &tmp2);
3782 
3783  if (in1 == 0) {
3784  Tout_current.addEdge((int) vdata1 - 1, (int) vdata2 - 1,
3785  ((double) tmp));
3786  Tout_current_temp.addEdge((int) vdata1 - 1, (int) vdata2 - 1,
3787  ((double) tmp2));
3788  } else {
3789  Tout_current.edgeWeight(e1, &tmp3);
3790  Tout_current.setEdgeWeight(e1, (double) tmp3 + ((double) tmp));
3791 
3792  Tout_current_temp.edgeWeight(e2, &tmp3);
3793  Tout_current_temp.setEdgeWeight(e2,
3794  (double) tmp3 + ((double) tmp2));
3795  }
3796  }
3797  }
3798 
3799  min_edge_value = 10000000000000.0f;
3800  boost::tie(ed_it2, ed_end2) =
3801  boost::edges(Tout_current_temp.getBoostGraph());
3802 
3803  for (boost::tie(ed_it, ed_end) =
3804  boost::edges(Tout_current.getBoostGraph());
3805  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
3806  Tout_current.edgeWeight(*ed_it, &tmp);
3807  Tout_current_temp.edgeWeight(*ed_it2, &tmp2);
3808 
3809  if (((double) tmp / (double) tmp2) < min_edge_value) {
3810  min_edge_value = (double) tmp / (double) tmp2;
3811  v1_remove = Tout_current.edgeSource(*ed_it);
3812  v2_remove = Tout_current.edgeTarget(*ed_it);
3813  }
3814  }
3815 
3816  } // END while ( num_connected_component > 1)
3817 
3818  return RES_OK;
3819  }
3820 
3821  template <class ImageIn, class BoostGraph>
3822  RES_C t_Centrality_Edges_Weighting(const ImageIn &imIn, std::vector<int> p,
3823  int vRoot, BoostGraph &Tout)
3824  {
3825  MORPHEE_ENTER_FUNCTION("t_Centrality_Edges_Weighting");
3826 
3827  typename BoostGraph::VertexIterator v_it, v_end;
3828  typename BoostGraph::VertexIterator v_it2, v_end2;
3829 
3830  typename BoostGraph::VertexProperty vdata1, vdata2;
3831  typename BoostGraph::VertexDescriptor v1_remove, v2_remove, current_node;
3832  typename BoostGraph::VertexProperty label1, label2;
3833 
3834  typename BoostGraph::EdgeIterator ed_it, ed_end;
3835  typename BoostGraph::EdgeIterator ed_it2, ed_end2;
3836 
3837  typename BoostGraph::EdgeDescriptor e1, e2;
3838  typename BoostGraph::EdgeProperty tmp, tmp2, tmp3;
3839 
3840  // common image iterator
3841  typename ImageIn::const_iterator it, iend;
3842  offset_t o0, current_offset;
3843  offset_t o1;
3844  bool in1;
3845 
3846  ImageIn imOut = imIn.getSame();
3847 
3848  // SCAN IMAGE TO FIND THE PIXELS LABELS
3849  for (it = imIn.begin(), iend = imIn.end(); it != iend;
3850  ++it) // for all pixels in imIn create a vertex and an edge
3851  {
3852  current_offset = it.getOffset();
3853  ;
3854  imOut.setPixel(current_offset, 0);
3855  }
3856 
3857  // SCAN IMAGE TO FIND THE PIXELS LABELS
3858  for (it = imIn.begin(), iend = imIn.end(); it != iend;
3859  ++it) // for all pixels in imIn create a vertex and an edge
3860  {
3861  current_offset = it.getOffset();
3862  ;
3863 
3864  // IF PIXELS IS MARKED
3865  int marker = imIn.pixelFromOffset(current_offset);
3866  int pixout = imOut.pixelFromOffset(current_offset);
3867 
3868  if (p[current_offset] != vRoot && p[current_offset] > 0)
3869  imOut.setPixel(p[current_offset], pixout + 1);
3870  }
3871 
3872  // SCAN IMAGE TO FIND THE PIXELS LABELS
3873  for (it = imIn.begin(), iend = imIn.end(); it != iend;
3874  ++it) // for all pixels in imIn create a vertex and an edge
3875  {
3876  current_offset = it.getOffset();
3877  ;
3878 
3879  // IF PIXELS IS MARKED
3880  int pixout = imOut.pixelFromOffset(current_offset);
3881  int marker = imIn.pixelFromOffset(current_offset);
3882 
3883  if (pixout == 0) {
3884  while (current_offset > 0 && current_offset != vRoot && marker == 0) {
3885  boost::tie(e1, in1) = boost::edge(current_offset, p[current_offset],
3886  Tout.getBoostGraph());
3887 
3888  if (in1 == 0) {
3889  Tout.addEdge(current_offset, p[current_offset], 1);
3890  } else {
3891  Tout.edgeWeight(e1, &tmp);
3892  Tout.setEdgeWeight(e1, tmp + 1);
3893  }
3894  }
3895  }
3896  }
3897 
3898  return RES_OK;
3899  }
3900 
3901  template <class ImageWs, class ImageIn, class ImageGrad, class SE,
3902  class BoostGraph>
3903  RES_C t_AverageLinkageTree_MS(const ImageWs &imWs, const ImageIn &imIn,
3904  const ImageGrad &imGrad, const SE &nl,
3905  BoostGraph &Tout)
3906  {
3907  MORPHEE_ENTER_FUNCTION("t_AverageLinkageTree_MS");
3908 
3910  if ((!imWs.isAllocated())) {
3911  MORPHEE_REGISTER_ERROR("Not allocated");
3912  return RES_NOT_ALLOCATED;
3913  }
3914 
3916  if ((!imIn.isAllocated())) {
3917  MORPHEE_REGISTER_ERROR("Not allocated");
3918  return RES_NOT_ALLOCATED;
3919  }
3920 
3922  if ((!imGrad.isAllocated())) {
3923  MORPHEE_REGISTER_ERROR("Not allocated");
3924  return RES_NOT_ALLOCATED;
3925  }
3926 
3927  typename BoostGraph::VertexIterator v_it, v_end;
3928  typename BoostGraph::VertexIterator v_it2, v_end2;
3929 
3930  typename BoostGraph::VertexProperty vdata1, vdata2;
3931  typename BoostGraph::VertexDescriptor v1_remove, v2_remove, current_node;
3932  typename BoostGraph::VertexProperty label1, label2;
3933 
3934  typename BoostGraph::EdgeIterator ed_it, ed_end;
3935  typename BoostGraph::EdgeIterator ed_it2, ed_end2;
3936  typename BoostGraph::EdgeDescriptor et1, et2;
3937  typename BoostGraph::EdgeProperty tmp, tmp2, tmp3;
3938 
3939  // common image iterator
3940  typename ImageIn::const_iterator it, iend;
3941  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
3942  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
3943  offset_t o0;
3944  offset_t o1;
3945 
3946  std::queue<int> temp_q;
3947 
3948  //----------------------------------------------------------------
3949  // Needed for spanning tree computation
3950  //----------------------------------------------------------------
3951  typedef boost::adjacency_list<
3952  boost::vecS, boost::vecS, boost::undirectedS,
3953  boost::property<boost::vertex_distance_t, double>,
3954  boost::property<boost::edge_capacity_t, double>>
3955  Graph_d;
3956 
3957  Graph_d g;
3958 
3959  boost::property_map<Graph_d, boost::edge_capacity_t>::type weightmap =
3960  boost::get(boost::edge_capacity, g);
3961 
3962  bool in1;
3963  Graph_d::edge_descriptor e1, e2, e3, e4;
3964  Graph_d::vertex_descriptor vRoot;
3965  int numVert = 0;
3966 
3967  //----------------------------------------------------------------
3968  //----------------------------------------------------------------
3969 
3970  std::cout << "build graph vertices" << std::endl;
3971 
3972  for (it = imIn.begin(), iend = imIn.end(); it != iend;
3973  ++it) // for all pixels in imIn create a vertex
3974  {
3975  o0 = it.getOffset();
3976  boost::add_vertex(g);
3977  numVert++;
3978  }
3979 
3980  BoostGraph T_temp = morphee::graph::CommonGraph32(numVert);
3981 
3982  vRoot = boost::add_vertex(g);
3983 
3984  std::cout << "number of vertices: " << numVert << std::endl;
3985 
3986  std::cout << "build graph edges" << std::endl;
3987 
3988  for (it = imIn.begin(), iend = imIn.end(); it != iend;
3989  ++it) // for all pixels in imIn create a vertex and an edge
3990  {
3991  o1 = it.getOffset();
3992  double val = imGrad.pixelFromOffset(o1);
3993  int marker = imWs.pixelFromOffset(o1);
3994 
3995  if (marker > 0) {
3996  boost::tie(e4, in1) = boost::add_edge(vRoot, o1, g);
3997  weightmap[e4] = 0.1;
3998  }
3999 
4000  neighb.setCenter(o1);
4001 
4002  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
4003  const offset_t o2 = nit.getOffset();
4004  if (o2 <= o1)
4005  continue;
4006  if (o2 > o1) {
4007  double val2 = imGrad.pixelFromOffset(o2);
4008  double cost = std::max(val, val2);
4009  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
4010  weightmap[e4] = cost;
4011  }
4012  }
4013  }
4014 
4015  std::cout << "Compute Minimum Spanning Forest" << std::endl;
4016 
4017  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
4018  boost::num_vertices(g));
4019  boost::property_map<Graph_d, boost::vertex_distance_t>::type distancemap =
4020  boost::get(boost::vertex_distance, g);
4021  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap2 =
4022  boost::get(boost::vertex_index, g);
4023 
4024  dijkstra_shortest_paths(g, vRoot, &p[0], distancemap, weightmap,
4025  indexmap2, std::less<double>(),
4026  boost::detail::maximum<double>(),
4027  (std::numeric_limits<double>::max)(), 0,
4028  boost::default_dijkstra_visitor());
4029 
4030  std::vector<int> p_int;
4031 
4032  for (int i = 0; i < numVert; i++) {
4033  p_int[i] = (int) p[i];
4034  }
4035 
4036  t_Centrality_Edges_Weighting(imWs, p_int, (int) vRoot, Tout);
4037 
4038  return RES_OK;
4039  }
4040 
4041  template <class ImageIn, class ImageGrad, class SE, class BoostGraph>
4042  RES_C t_NeighborhoodGraphFromMosaic_WithMinValue(const ImageIn &imIn,
4043  const ImageGrad &imGrad,
4044  const SE &nl,
4045  BoostGraph &Gout)
4046  {
4047  MORPHEE_ENTER_FUNCTION("t_NeighborhoodGraphFromMosaic_WithMinValue");
4048 
4049  if ((!imIn.isAllocated())) {
4050  MORPHEE_REGISTER_ERROR("Not allocated");
4051  return RES_NOT_ALLOCATED;
4052  }
4053 
4054  if ((!imGrad.isAllocated())) {
4055  MORPHEE_REGISTER_ERROR("Not allocated");
4056  return RES_NOT_ALLOCATED;
4057  }
4058 
4059  // common image iterator
4060  typename ImageIn::const_iterator it, iend;
4061  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
4062  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
4063  offset_t o0;
4064  offset_t o1;
4065 
4066  typename BoostGraph::EdgeIterator ed_it, ed_end;
4067  typename BoostGraph::EdgeIterator ed_it2, ed_end2;
4068 
4069  bool in1;
4070  int numVert = 0;
4071  int numEdges = 0;
4072  typename BoostGraph::EdgeDescriptor e1, e2;
4073  typename BoostGraph::EdgeProperty tmp, tmp2;
4074 
4075  std::cout << "build Region Adjacency Graph" << std::endl;
4076 
4077  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4078  ++it) // for all pixels in imIn create a vertex
4079  {
4080  o0 = it.getOffset();
4081  int val = imIn.pixelFromOffset(o0);
4082 
4083  if (val > numVert) {
4084  numVert = val;
4085  }
4086  }
4087 
4088  std::cout << "build Region Adjacency Graph Vertices" << std::endl;
4089  std::cout << "number of Vertices:" << numVert << std::endl;
4090 
4091  Gout = morphee::graph::CommonGraph32(numVert);
4092  BoostGraph Gtemp = morphee::graph::CommonGraph32(numVert);
4093 
4094  std::cout << "build Region Adjacency Graph Edges" << std::endl;
4095 
4096  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4097  ++it) // for all pixels in imIn create a vertex and an edge
4098  {
4099  o1 = it.getOffset();
4100  int val = imIn.pixelFromOffset(o1);
4101 
4102  if (val > 0) {
4103  neighb.setCenter(o1);
4104 
4105  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
4106  const offset_t o2 = nit.getOffset();
4107  int val2 = imIn.pixelFromOffset(o2);
4108 
4109  if (o2 > o1) {
4110  if (val != val2) {
4111  boost::tie(e1, in1) =
4112  boost::edge(val - 1, val2 - 1, Gout.getBoostGraph());
4113  boost::tie(e2, in1) =
4114  boost::edge(val - 1, val2 - 1, Gtemp.getBoostGraph());
4115 
4116  double val3 = imGrad.pixelFromOffset(o1);
4117  double val4 = imGrad.pixelFromOffset(o2);
4118  double mini = std::max(val3, val4);
4119 
4120  if (in1 == 0) {
4121  Gout.addEdge(val - 1, val2 - 1, mini);
4122  Gtemp.addEdge(val - 1, val2 - 1, 1);
4123  } else {
4124  Gout.edgeWeight(e1, &tmp);
4125  Gout.setEdgeWeight(e1, tmp + mini);
4126 
4127  Gtemp.edgeWeight(e2, &tmp2);
4128  Gtemp.setEdgeWeight(e2, tmp2 + 1);
4129  }
4130  }
4131  }
4132  }
4133  }
4134  }
4135 
4136  boost::tie(ed_it2, ed_end2) = boost::edges(Gtemp.getBoostGraph());
4137  // Weights the graph Gout with mean gradient value along boundary
4138  for (boost::tie(ed_it, ed_end) = boost::edges(Gout.getBoostGraph());
4139  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
4140  Gout.edgeWeight(*ed_it, &tmp);
4141  Gtemp.edgeWeight(*ed_it2, &tmp2);
4142 
4143  Gout.setEdgeWeight(*ed_it,
4144  ((double) tmp) / ((double) tmp2)); // sum gradient
4145  }
4146 
4147  return RES_OK;
4148  }
4149 
4150  template <class ImageIn, class ImageGrad, class ImageVal, typename _alpha,
4151  class SE, class BoostGraph>
4152  RES_C t_NeighborhoodGraphFromMosaic_WithMeanGradientValue_AndQuadError(
4153  const ImageIn &imIn, const ImageGrad &imGrad, const ImageVal &imVal,
4154  const _alpha alpha, const SE &nl, BoostGraph &Gout)
4155  {
4156  MORPHEE_ENTER_FUNCTION(
4157  "t_NeighborhoodGraphFromMosaic_WithMeanGradientValue_AndQuadError");
4158 
4159  if ((!imIn.isAllocated())) {
4160  MORPHEE_REGISTER_ERROR("Not allocated");
4161  return RES_NOT_ALLOCATED;
4162  }
4163 
4164  if ((!imGrad.isAllocated())) {
4165  MORPHEE_REGISTER_ERROR("Not allocated");
4166  return RES_NOT_ALLOCATED;
4167  }
4168 
4169  if ((!imVal.isAllocated())) {
4170  MORPHEE_REGISTER_ERROR("Not allocated");
4171  return RES_NOT_ALLOCATED;
4172  }
4173 
4174  // common image iterator
4175  typename ImageIn::const_iterator it, iend;
4176  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
4177  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
4178  offset_t o0;
4179  offset_t o1;
4180 
4181  typename BoostGraph::EdgeIterator ed_it, ed_end;
4182  typename BoostGraph::VertexIterator v_it, v_end;
4183  typename BoostGraph::EdgeIterator ed_it2, ed_end2;
4184 
4185  bool in1;
4186  int numVert = 0;
4187  int numEdges = 0;
4188  typename BoostGraph::EdgeDescriptor e1, e2;
4189  typename BoostGraph::EdgeProperty tmp, tmp2;
4190  typename BoostGraph::VertexProperty quad1, quad2;
4191 
4192  std::cout << "build Region Adjacency Graph" << std::endl;
4193 
4194  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4195  ++it) // for all pixels in imIn create a vertex
4196  {
4197  o0 = it.getOffset();
4198  int val = imIn.pixelFromOffset(o0);
4199 
4200  if (val > numVert) {
4201  numVert = val;
4202  }
4203  }
4204 
4205  std::vector<double> mean_values;
4206  std::vector<double> number_of_values;
4207  std::vector<double> quad_error;
4208 
4209  for (int i = 0; i < numVert; i++) {
4210  mean_values.push_back(0);
4211  number_of_values.push_back(0);
4212  quad_error.push_back(0);
4213  }
4214 
4215  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4216  ++it) // for all pixels in imIn create a vertex
4217  {
4218  o1 = it.getOffset();
4219  int val = imIn.pixelFromOffset(o1);
4220  double val_image = imVal.pixelFromOffset(o1);
4221  mean_values[val - 1] = mean_values[val - 1] + val_image;
4222  number_of_values[val - 1] = number_of_values[val - 1] + 1.0;
4223  }
4224 
4225  for (int i = 0; i < numVert; i++) {
4226  mean_values[i] = mean_values[i] / number_of_values[i];
4227  }
4228 
4229  std::cout << "build Region Adjacency Graph Vertices" << std::endl;
4230  std::cout << "number of Vertices:" << numVert << std::endl;
4231 
4232  Gout = morphee::graph::CommonGraph32(numVert);
4233  BoostGraph Gtemp = morphee::graph::CommonGraph32(numVert);
4234 
4235  std::cout << "build Region Adjacency Graph Edges" << std::endl;
4236 
4237  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4238  ++it) // for all pixels in imIn create a vertex and an edge
4239  {
4240  o1 = it.getOffset();
4241  int val = imIn.pixelFromOffset(o1);
4242  double val_image = imVal.pixelFromOffset(o1);
4243 
4244  quad_error[val - 1] =
4245  (double) quad_error[val - 1] +
4246  std::pow(std::abs(val_image - (double) mean_values[val - 1]), 2);
4247 
4248  if (val > 0) {
4249  neighb.setCenter(o1);
4250 
4251  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
4252  const offset_t o2 = nit.getOffset();
4253  int val2 = imIn.pixelFromOffset(o2);
4254 
4255  if (o2 > o1) {
4256  if (val != val2) {
4257  boost::tie(e1, in1) =
4258  boost::edge(val - 1, val2 - 1, Gout.getBoostGraph());
4259  boost::tie(e2, in1) =
4260  boost::edge(val - 1, val2 - 1, Gtemp.getBoostGraph());
4261 
4262  double val3 = imGrad.pixelFromOffset(o1);
4263  double val4 = imGrad.pixelFromOffset(o2);
4264  double maxi = std::max(val3, val4);
4265 
4266  if (in1 == 0) {
4267  numEdges++;
4268  Gout.addEdge(val - 1, val2 - 1, maxi);
4269  Gtemp.addEdge(val - 1, val2 - 1, 1);
4270  } else {
4271  Gout.edgeWeight(e1, &tmp);
4272  Gout.setEdgeWeight(e1, (double) tmp + maxi);
4273 
4274  Gtemp.edgeWeight(e2, &tmp2);
4275  Gtemp.setEdgeWeight(e2, (double) tmp2 + 1);
4276  }
4277  }
4278  }
4279  }
4280  }
4281  }
4282 
4283  std::cout << "number of Edges : " << numEdges << std::endl;
4284 
4285  int current_vertex = 0;
4286  double max_value = 0;
4287 
4288  for (boost::tie(v_it, v_end) = boost::vertices(Gout.getBoostGraph());
4289  v_it != v_end; ++v_it) {
4290  // Gout.setVertexData(*v_it, number_of_values[current_vertex] +
4291  // quad_error[current_vertex] );
4292 
4293  if (max_value < quad_error[current_vertex])
4294  max_value = quad_error[current_vertex];
4295 
4296  Gout.setVertexData(*v_it, mean_values[current_vertex]);
4297  current_vertex = current_vertex + 1;
4298  // std::cout<< mean_values[current_vertex] <<std::endl;
4299  }
4300 
4301  boost::tie(ed_it2, ed_end2) = boost::edges(Gtemp.getBoostGraph());
4302 
4303  for (boost::tie(ed_it, ed_end) = boost::edges(Gout.getBoostGraph());
4304  ed_it != ed_end, ed_it2 != ed_end2; ++ed_it, ++ed_it2) {
4305  Gout.edgeWeight(*ed_it, &tmp);
4306  Gtemp.edgeWeight(*ed_it2, &tmp2);
4307 
4308  Gout.vertexData(Gout.edgeSource(*ed_it), &quad1);
4309  Gout.vertexData(Gout.edgeTarget(*ed_it), &quad2);
4310 
4311  double area_1 = number_of_values[(int) Gout.edgeSource(*ed_it)] +
4312  quad_error[(int) Gout.edgeSource(*ed_it)];
4313  double area_2 = number_of_values[(int) Gout.edgeTarget(*ed_it)] +
4314  quad_error[(int) Gout.edgeTarget(*ed_it)];
4315 
4316  double cost =
4317  (((double) tmp) / ((double) tmp2)); // * std::pow( std::min( quad1 ,
4318  // quad2 ) , (double) alpha ) ;
4319  // double cost = ( tmp ) * std::pow( std::min( quad1 , quad2 ) ,
4320  // (double) alpha ) ; double cost = std::abs( ( (double) quad1 -
4321  // (double) quad2) ) * std::pow( std::min( area_1, area_2 ) , (double)
4322  // alpha ) ; double cost = ( ((double) tmp) /( (double) tmp2) ) *
4323  // std::pow( std::min( area_1, area_2 ) , (double) alpha ) ;
4324 
4325  Gout.setEdgeWeight(*ed_it, cost);
4326  }
4327 
4328  current_vertex = 0;
4329  for (boost::tie(v_it, v_end) = boost::vertices(Gout.getBoostGraph());
4330  v_it != v_end; ++v_it) {
4331  Gout.setVertexData(*v_it, (double) number_of_values[current_vertex] +
4332  (double) quad_error[current_vertex]);
4333  current_vertex = current_vertex + 1;
4334  }
4335 
4336  return RES_OK;
4337  }
4338 
4339  // template<class BoostGraph>
4340  // const BoostGraph t_DendogramFromTree(const BoostGraph &TreeIn)
4341  // {
4342  // MORPHEE_ENTER_FUNCTION("t_DendogramFromTree");
4343 
4344  // typedef typename BoostGraph::EdgeIterator EdgeIterator;
4345  // typedef typename BoostGraph::VertexIterator VertexIterator;
4346  // typedef typename BoostGraph::EdgeProperty EdgeProperty;
4347 
4348  // typename BoostGraph::VertexDescriptor vs,vt;
4349  // std::vector<double> val_edges;
4350  // EdgeIterator ed_it, ed_end;
4351  // VertexIterator v_it, v_end;
4352  // EdgeProperty tmp;
4353 
4354  // BoostGraph Tree_temp(TreeIn.numVertices());
4355  // BoostGraph Tree_label(TreeIn.numVertices());
4356  // BoostGraph Tree_contract(TreeIn.numVertices());
4357  // BoostGraph Dendogram(TreeIn.numVertices());
4358 
4359  // // order edges weights to ensure unicity of each weight
4360  // morphee::Morpho_Graph::t_Order_Edges_Weights(TreeIn, Tree_temp);
4361 
4362  // typename BoostGraph::VertexProperty vdata1;
4363 
4364  // for (boost::tie(ed_it, ed_end)=boost::edges(Tree_temp.getBoostGraph()) ;
4365  // ed_it != ed_end ; ++ed_it )
4366  // {
4367  // Tree_temp.edgeWeight(*ed_it,&tmp); // PASS VALUE
4368  // val_edges.push_back( tmp );
4369  // }
4370 
4371  // // sort edges weights to explore the hierarchy
4372  // std::cout<<"sort edges values"<<std::endl;
4373  // std::sort(val_edges.begin(), val_edges.end(),std::less<double>());
4374 
4375  // // clear edges and update edges values
4376  // int num_connected_component;
4377  // t_LabelConnectedComponent(Tree_contract,Tree_label,&num_connected_component);
4378  // std::cout<<"numer of leaves: "<<num_connected_component<<std::endl;
4379 
4380  // while ( num_connected_component > 1 ){
4381 
4382  // double last_edge_value = val_edges.back();
4383  // val_edges.pop_back();
4384  // std::cout<<"last_edge_value: "<<last_edge_value<<std::endl;
4385 
4386  // // add edges in Tree_contract
4387  // for (boost::tie(ed_it, ed_end)=boost::edges(Tree_temp.getBoostGraph())
4388  // ; ed_it != ed_end; ++ed_it)
4389  // {
4390  // Tree_temp.edgeWeight(*ed_it,&tmp);
4391 
4392  // if(tmp == last_edge_value){ // check is current max weight
4393  // vs = Tree_temp.edgeSource(*ed_it) ;
4394  // vt = Tree_temp.edgeTarget(*ed_it) ;
4395  // Tree_contract.addEdge(vs,vt,1);;
4396  // }
4397  // }
4398 
4399  // t_LabelConnectedComponent(Tree_contract,Tree_label,&num_connected_component);
4400  // std::cout<<"number of leaves: "<<num_connected_component<<std::endl;
4401 
4402  // int* histogram_nb_nodes = new int[num_connected_component+1];
4403 
4404  // for (int i=0;i<num_connected_component+1;i++)
4405  // {
4406  // histogram_nb_nodes[i]=0;
4407  // }
4408 
4409  // for (boost::tie(v_it, v_end)=boost::vertices(Tree_temp.getBoostGraph())
4410  // ; v_it != v_end; ++v_it)
4411  // {
4412  // Tree_label.vertexData( *v_it , &vdata1);
4413  // histogram_nb_nodes[(int) vdata1] = histogram_nb_nodes[(int) vdata1] +
4414  // 1 ;
4415  // }
4416 
4417  // int number_of_nodes_to_add = 0 ;
4418 
4419  // for (int i=0;i<num_connected_component+1;i++)
4420  // {
4421  // if( histogram_nb_nodes[i] > 1 ) number_of_nodes_to_add++;
4422  // }
4423 
4424  // std::cout<<"number of nodes to add:
4425  // "<<number_of_nodes_to_add<<std::endl;
4426 
4427  // }
4428 
4429  // return GCopy;
4430  // }
4431 
4432  template <class ImageIn, class ImageGradx, class ImageGrady,
4433  class ImageMarker, class SE, class ImageOut>
4434  RES_C t_geoCutsParametric(const ImageIn &imIn, const ImageGradx &imGradx,
4435  const ImageGrady &imGrady,
4436  const ImageMarker &imMarker, const SE &nl,
4437  ImageOut &imOut)
4438  {
4439  MORPHEE_ENTER_FUNCTION("t_geoCutsParametric");
4440 
4441  std::cout << "Enter function t_geoCutsParametric" << std::endl;
4442 
4443  if ((!imOut.isAllocated())) {
4444  MORPHEE_REGISTER_ERROR("Not allocated");
4445  return RES_NOT_ALLOCATED;
4446  }
4447 
4448  if ((!imIn.isAllocated())) {
4449  MORPHEE_REGISTER_ERROR("Not allocated");
4450  return RES_NOT_ALLOCATED;
4451  }
4452 
4453  if ((!imGradx.isAllocated())) {
4454  MORPHEE_REGISTER_ERROR("Not allocated");
4455  return RES_NOT_ALLOCATED;
4456  }
4457 
4458  if ((!imGrady.isAllocated())) {
4459  MORPHEE_REGISTER_ERROR("Not allocated");
4460  return RES_NOT_ALLOCATED;
4461  }
4462 
4463  if ((!imMarker.isAllocated())) {
4464  MORPHEE_REGISTER_ERROR("Not allocated");
4465  return RES_NOT_ALLOCATED;
4466  }
4467 
4468  // common image iterator
4469  typename ImageIn::const_iterator it, iend;
4470  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
4471  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
4472  offset_t o0;
4473  offset_t o1;
4474 
4475  // needed for max flow: capacit map, rev_capacity map, etc.
4476  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
4477  boost::directedS>
4478  Traits;
4479  typedef boost::adjacency_list<
4480  boost::vecS, boost::vecS, boost::directedS,
4481  boost::property<boost::vertex_name_t, std::string>,
4482  boost::property<
4483  boost::edge_capacity_t, float,
4484  boost::property<boost::edge_residual_capacity_t, float,
4485  boost::property<boost::edge_reverse_t,
4486  Traits::edge_descriptor>>>>
4487  Graph_d;
4488 
4489  Graph_d g;
4490 
4491  double sigma = 1.0;
4492 
4493  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
4494  boost::get(boost::edge_capacity, g);
4495 
4496  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
4497  get(boost::edge_reverse, g);
4498 
4499  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
4500  residual_capacity = get(boost::edge_residual_capacity, g);
4501 
4502  bool in1;
4503  Graph_d::edge_descriptor e1, e2, e3, e4;
4504  Graph_d::vertex_descriptor vSource, vSink;
4505 
4506  int numVert = 0;
4507  int numEdges = 0;
4508 
4509  std::cout << "build graph vertices" << std::endl;
4510  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4511  ++it) // for all pixels in imIn create a vertex
4512  {
4513  o0 = it.getOffset();
4514  boost::add_vertex(g);
4515  numVert++;
4516  }
4517 
4518  vSource = boost::add_vertex(g);
4519  vSink = boost::add_vertex(g);
4520  numVert += 2;
4521 
4522  std::cout << "build graph edges" << std::endl;
4523  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4524  ++it) // for all pixels in imIn create a vertex and an edge
4525  {
4526  o1 = it.getOffset();
4527 
4528  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
4529  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
4530  rev[e4] = e3;
4531  rev[e3] = e4;
4532  numEdges++;
4533 
4534  boost::tie(e3, in1) = boost::add_edge(o1, vSink, g);
4535  boost::tie(e4, in1) = boost::add_edge(vSink, o1, g);
4536  rev[e3] = e4;
4537  rev[e4] = e3;
4538  numEdges++;
4539 
4540  neighb.setCenter(o1);
4541 
4542  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
4543  const offset_t o2 = nit.getOffset();
4544  if (o2 <= o1)
4545  continue;
4546  if (o2 > o1) {
4547  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
4548  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
4549  rev[e4] = e3;
4550  rev[e3] = e4;
4551  numEdges++;
4552  }
4553  }
4554  }
4555 
4556  std::cout << "graph is built" << std::endl;
4557 
4558  std::cout << "number of vertices: " << numVert << std::endl;
4559  std::cout << "number of edges: " << numEdges << std::endl;
4560 
4561  std::cout << "weight edges" << std::endl;
4562 
4563  double value_object = 0.7;
4564  double value_background = 0.0;
4565  float lambda = 1.0;
4566 
4567  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
4568  boost::get(boost::vertex_index, g);
4569  std::vector<boost::default_color_type> color(boost::num_vertices(g));
4570 
4571  int iter;
4572 
4573  for (lambda = 0.25, iter = 0; lambda <= 0.75, iter <= 500;
4574  lambda = lambda + 0.001, iter++) {
4575  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4576  ++it) // for all pixels in imIn create a vertex and an edge
4577  {
4578  o1 = it.getOffset();
4579 
4580  // float val = (1.0/255.0) * (float) imIn.pixelFromOffset(o1);
4581  float val = (float) imMarker.pixelFromOffset(o1);
4582 
4583  // unary potential
4584  if (val >= 0.0f) {
4585  boost::tie(e4, in1) = boost::edge(vSource, o1, g);
4586  boost::tie(e3, in1) = boost::edge(o1, vSource, g);
4587  // capacity[e4] = (value_object-val)*(value_object-val);
4588  // capacity[e3] = (value_object-val)*(value_object-val);
4589  capacity[e4] = val;
4590  capacity[e3] = val;
4591  } else {
4592  boost::tie(e3, in1) = boost::edge(o1, vSink, g);
4593  boost::tie(e4, in1) = boost::edge(vSink, o1, g);
4594  // capacity[e3] = (value_background-val)*(value_background-val);
4595  // capacity[e4] = (value_background-val)*(value_background-val);
4596  capacity[e3] = abs(val);
4597  capacity[e4] = abs(val);
4598  }
4599 
4600  neighb.setCenter(o1);
4601 
4602  // binary potential
4603  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
4604  const offset_t o2 = nit.getOffset();
4605  if (o2 <= o1)
4606  continue;
4607  if (o2 > o1) {
4608  float val2 = (1.0 / 255.0) * (float) imIn.pixelFromOffset(o2);
4609  float cost =
4610  lambda / ((1.0 / 255.0) + (val - val2) + (val - val2));
4611  boost::tie(e4, in1) = boost::edge(o1, o2, g);
4612  boost::tie(e3, in1) = boost::edge(o2, o1, g);
4613  capacity[e4] = cost;
4614  capacity[e3] = cost;
4615  }
4616  }
4617  }
4618 
4619  std::cout << "Compute Max flow" << std::endl;
4620 #if BOOST_VERSION >= 104700
4621  double flow =
4622  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
4623  &color[0], indexmap, vSource, vSink);
4624 #else
4625  double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
4626  &color[0], indexmap, vSource, vSink);
4627 #endif
4628  std::cout << "c The total flow:" << std::endl;
4629  std::cout << "s " << flow << std::endl << std::endl;
4630 
4631  if (iter == 0) {
4632  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4633  ++it) // for all pixels in imIn create a vertex and an edge
4634  {
4635  o1 = it.getOffset();
4636  if (color[o1] == color[vSource])
4637  imOut.setPixel(o1, 0);
4638  if (color[o1] == 1)
4639  imOut.setPixel(o1, 0);
4640  if (color[o1] == color[vSink])
4641  imOut.setPixel(o1, 100.0 * (lambda + 0.1));
4642  }
4643  } else {
4644  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4645  ++it) // for all pixels in imIn create a vertex and an edge
4646  {
4647  o1 = it.getOffset();
4648 
4649  int oldval = imOut.pixelFromOffset(o1);
4650  int oldval2 =
4651  std::min((double) 100.0 * (lambda + 0.1), (double) oldval);
4652  int oldval3 = 100.0 * (lambda + 0.1);
4653 
4654  if (color[o1] == color[vSink] && oldval > 0)
4655  imOut.setPixel(o1, (int) oldval2);
4656 
4657  else if (color[o1] == color[vSink] && oldval == 0)
4658  imOut.setPixel(o1, (int) oldval3);
4659  }
4660  }
4661  }
4662 
4663  return RES_OK;
4664  }
4665 
4666  template <class ImageIn, class ImageMarker, class ImageMarker2, class SE,
4667  class ImageOut>
4668  RES_C t_geoCutsBoundary_Constrained_MinSurfaces(
4669  const ImageIn &imIn, const ImageMarker &imMarker,
4670  const ImageMarker2 &imMarker2, const SE &nl, ImageOut &imOut)
4671  {
4672  MORPHEE_ENTER_FUNCTION("t_geoCutsBoundary_Constrained_MinSurfaces");
4673 
4674  std::cout << "Enter function Geo-Cuts " << std::endl;
4675 
4676  if ((!imOut.isAllocated())) {
4677  MORPHEE_REGISTER_ERROR("Not allocated");
4678  return RES_NOT_ALLOCATED;
4679  }
4680 
4681  if ((!imIn.isAllocated())) {
4682  MORPHEE_REGISTER_ERROR("Not allocated");
4683  return RES_NOT_ALLOCATED;
4684  }
4685 
4686  if ((!imMarker.isAllocated())) {
4687  MORPHEE_REGISTER_ERROR("Not allocated");
4688  return RES_NOT_ALLOCATED;
4689  }
4690 
4691  if ((!imMarker2.isAllocated())) {
4692  MORPHEE_REGISTER_ERROR("Not allocated");
4693  return RES_NOT_ALLOCATED;
4694  }
4695 
4696  // common image iterator
4697  typename ImageIn::const_iterator it, iend;
4698  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
4699  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
4700  offset_t o0;
4701  offset_t o1;
4702 
4703  // needed for max flow: capacit map, rev_capacity map, etc.
4704  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
4705  boost::directedS>
4706  Traits;
4707  typedef boost::adjacency_list<
4708  boost::listS, boost::vecS, boost::directedS,
4709  boost::property<boost::vertex_name_t, std::string>,
4710  boost::property<
4711  boost::edge_capacity_t, double,
4712  boost::property<boost::edge_residual_capacity_t, double,
4713  boost::property<boost::edge_reverse_t,
4714  Traits::edge_descriptor>>>>
4715  Graph_d;
4716 
4717  Graph_d g;
4718 
4719  double sigma = 1.0;
4720 
4721  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
4722  boost::get(boost::edge_capacity, g);
4723 
4724  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
4725  get(boost::edge_reverse, g);
4726 
4727  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
4728  residual_capacity = get(boost::edge_residual_capacity, g);
4729 
4730  bool in1;
4731  Graph_d::edge_descriptor e1, e2, e3, e4;
4732  Graph_d::vertex_descriptor vSource, vSink;
4733  int numVert = 0;
4734  int numEdges = 0;
4735 
4736  std::cout << "build graph vertices" << std::endl;
4737  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4738  ++it) // for all pixels in imIn create a vertex
4739  {
4740  o0 = it.getOffset();
4741  boost::add_vertex(g);
4742  numVert++;
4743  }
4744 
4745  std::cout << "number of vertices: " << numVert << std::endl;
4746 
4747  vSource = boost::add_vertex(g);
4748  vSink = boost::add_vertex(g);
4749  int source_sink_found = 0;
4750 
4751  std::cout << "build graph edges" << std::endl;
4752  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4753  ++it) // for all pixels in imIn create a vertex and an edge
4754  {
4755  o1 = it.getOffset();
4756  double val = imIn.pixelFromOffset(o1);
4757  int marker = imMarker.pixelFromOffset(o1);
4758 
4759  int valright = 0;
4760  int valleft = 0;
4761  int valup = 0;
4762  int valdown = 0;
4763 
4764  // if(marker==128){
4765  // std::cout<<"here 1"<<std::endl;
4766  // boost::tie(e4, in1) = boost::add_edge(vSource,o1,g);
4767  // boost::tie(e3, in1) = boost::add_edge(o1,vSource,g);
4768  // capacity[e4] = (std::numeric_limits<double>::max)();
4769  // capacity[e3] = (std::numeric_limits<double>::max)();
4770  // rev[e4] = e3;
4771  // rev[e3] = e4;
4772  //}
4773  // else if(marker==255){
4774  // std::cout<<"here 2"<<std::endl;
4775  // boost::tie(e4, in1) = boost::add_edge(o1,vSink, g);
4776  // boost::tie(e3, in1) = boost::add_edge(vSink,o1, g);
4777  // capacity[e4] = (std::numeric_limits<double>::max)();
4778  // capacity[e3] = (std::numeric_limits<double>::max)();
4779  // rev[e4] = e3;
4780  // rev[e3] = e4;
4781  //}
4782 
4783  neighb.setCenter(o1);
4784 
4785  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
4786  const offset_t o2 = nit.getOffset();
4787  int marker2 = imMarker.pixelFromOffset(o2);
4788 
4789  if (marker == 255 && marker2 == 128) {
4790  boost::tie(e4, in1) = boost::add_edge(vSource, o2, g);
4791  boost::tie(e3, in1) = boost::add_edge(o2, vSource, g);
4792  capacity[e4] = (std::numeric_limits<double>::max)();
4793  capacity[e3] = (std::numeric_limits<double>::max)();
4794  rev[e4] = e3;
4795  rev[e3] = e4;
4796  numEdges++;
4797 
4798  boost::tie(e4, in1) = boost::add_edge(vSink, o1, g);
4799  boost::tie(e3, in1) = boost::add_edge(o1, vSink, g);
4800  capacity[e4] = (std::numeric_limits<double>::max)();
4801  capacity[e3] = (std::numeric_limits<double>::max)();
4802  rev[e4] = e3;
4803  rev[e3] = e4;
4804  numEdges++;
4805  }
4806 
4807  if (o2 <= o1)
4808  continue;
4809 
4810  if (o2 > o1 && (marker == 0 || marker2 == 0 || marker == marker2)) {
4811  numEdges++;
4812  double val2 = imIn.pixelFromOffset(o2);
4813  double maxi = std::abs(val2 - val);
4814  double cost = 256 / (1 + std::pow(maxi, 2));
4815  // double cost = 1.0 ;
4816  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
4817  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
4818  capacity[e4] = cost;
4819  capacity[e3] = cost;
4820  rev[e4] = e3;
4821  rev[e3] = e4;
4822  }
4823  }
4824  }
4825 
4826  std::cout << "number of Edges : " << numEdges << std::endl;
4827 
4828  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
4829  boost::get(boost::vertex_index, g);
4830  std::vector<boost::default_color_type> color(boost::num_vertices(g));
4831 
4832  std::cout << "Compute Max flow " << std::endl;
4833 
4834  double flow2 =
4835  kolmogorov_max_flow_min_cost(g, capacity, residual_capacity, rev,
4836  &color[0], indexmap, vSink, vSource);
4837  std::cout << "c The total flow found :" << std::endl;
4838  std::cout << "s " << flow2 << std::endl << std::endl;
4839 
4840  for (it = imIn.begin(), iend = imIn.end(); it != iend;
4841  ++it) // for all pixels in imIn create a vertex and an edge
4842  {
4843  o1 = it.getOffset();
4844  if (color[o1] == color[vSource])
4845  imOut.setPixel(o1, 2);
4846  else if (color[o1] == color[vSink])
4847  imOut.setPixel(o1, 3);
4848  else
4849  imOut.setPixel(o1, 4);
4850  }
4851 
4852  return RES_OK;
4853  }
4854 
4855  template <class ImageIn, class ImageVal, class BoostGraph,
4856  typename _nbmarkers, class SE, class ImageOut>
4857  RES_C t_geoCutsStochastic_Watershed_Graph(const ImageIn &imIn,
4858  const ImageVal &imVal,
4859  BoostGraph &Gin,
4860  const _nbmarkers nbmarkers,
4861  const SE &nl, ImageOut &imOut)
4862  {
4863  MORPHEE_ENTER_FUNCTION("t_geoCutsStochastic_Watershed_Graph");
4864 
4865  std::cout << "Enter function Geo-Cuts Stochastic Watershed graph"
4866  << std::endl;
4867 
4868  if ((!imOut.isAllocated())) {
4869  std::cout << "imOut Not allocated" << std::endl;
4870  MORPHEE_REGISTER_ERROR("Not allocated");
4871  return RES_NOT_ALLOCATED;
4872  }
4873 
4874  if ((!imIn.isAllocated())) {
4875  std::cout << "imIn Not allocated" << std::endl;
4876  MORPHEE_REGISTER_ERROR("Not allocated");
4877  return RES_NOT_ALLOCATED;
4878  }
4879 
4880  if ((!imVal.isAllocated())) {
4881  std::cout << "imVal Not allocated" << std::endl;
4882  MORPHEE_REGISTER_ERROR("Not allocated");
4883  return RES_NOT_ALLOCATED;
4884  }
4885 
4886  double markers = (double) nbmarkers;
4887 
4888  int size = imIn.getXSize() * imIn.getYSize() * imIn.getZSize();
4889  std::cout << size << std::endl;
4890 
4891  typename ImageOut::const_iterator it, iend;
4892  typename ImageIn::const_iterator it2, iend2;
4893  morphee::selement::Neighborhood<SE, ImageOut> neighb(imOut, nl);
4894  typename morphee::selement::Neighborhood<SE, ImageOut>::iterator nit,
4895  nend;
4896  offset_t o0, o1;
4897 
4898  typedef typename BoostGraph::EdgeIterator EdgeIterator;
4899  typedef typename BoostGraph::VertexIterator VertexIterator;
4900  typedef typename BoostGraph::EdgeDescriptor EdgeDescriptor;
4901  typedef typename BoostGraph::VertexDescriptor VertexDescriptor;
4902  typename morphee::graph::CommonGraph32::EdgeProperty tmp;
4903  typename morphee::graph::CommonGraph32::VertexProperty vdata1;
4904  typename morphee::graph::CommonGraph32::VertexProperty label1, label2;
4905  EdgeIterator ed_it, ed_end, ed_it2, ed_end2;
4906  VertexIterator v_it, v_end;
4907  EdgeDescriptor last_edge, e1, e2;
4908 
4909  bool in1;
4910 
4911  std::vector<double> val_edges;
4912  val_edges.push_back(0.0);
4913  double last_edge_value = 0.0;
4914 
4915  std::vector<EdgeDescriptor> removed_edges;
4916 
4917  morphee::graph::CommonGraph32 G(0);
4918  morphee::graph::CommonGraph32 G2(0);
4919  morphee::graph::CommonGraph32 Tree(0);
4920 
4921  std::cout << " Get NeighborhoodGraph " << std::endl;
4922  morphee::morphoBase::t_NeighborhoodGraphFromMosaic(imIn, nl, G);
4923 
4924  std::cout << "Copy Minimum Spanning Tree" << std::endl;
4925  Tree = t_CopyGraph(Gin);
4926 
4927  std::cout << "Done" << std::endl;
4928 
4929  // const morphee::graph::CommonGraph32 t_CopyGraph(const
4930  // morphee::graph::CommonGraph32 &);
4931 
4932  morphee::graph::t_ProjectMarkersOnGraph(imVal, imIn, Tree);
4933  typename morphee::graph::CommonGraph32 Tree_temp = t_CopyGraph(Tree);
4934  typename morphee::graph::CommonGraph32 Tree_out = t_CopyGraph(Tree);
4935  typename morphee::graph::CommonGraph32 Tree2 = t_CopyGraph(Tree_temp);
4936 
4937  double volume = 0.0;
4938  for (boost::tie(v_it, v_end) = boost::vertices(G.getBoostGraph());
4939  v_it != v_end; ++v_it) {
4940  Tree.vertexData(*v_it, &vdata1);
4941  volume = volume + (double) vdata1;
4942  }
4943 
4944  for (boost::tie(ed_it, ed_end) = boost::edges(G.getBoostGraph());
4945  ed_it != ed_end; ++ed_it) {
4946  G.setEdgeWeight(*ed_it, 0);
4947  }
4948 
4949  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
4950  ed_it != ed_end; ++ed_it) {
4951  Tree.edgeWeight(*ed_it, &tmp);
4952 
4953  val_edges.push_back(tmp);
4954  last_edge_value = (double) tmp;
4955  }
4956 
4957  std::cout << "sort" << std::endl;
4958  // std::sort(val_edges.begin(), val_edges.end());
4959  std::sort(val_edges.begin(), val_edges.end(), std::less<double>());
4960 
4961  last_edge_value = val_edges.back();
4962  float max_value = last_edge_value;
4963  double last_analyzed = last_edge_value;
4964 
4965  while (val_edges.size() > 1) {
4966  // std::cout<<val_edges.size()<<std::endl;
4967  // std::cout<<last_edge_value<<std::endl;
4968 
4969  // remove edge of maximal weight
4970  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
4971  ed_it != ed_end; ++ed_it) {
4972  // std::cout<<"look"<<std::endl;
4973  Tree.edgeWeight(*ed_it, &tmp);
4974 
4975  if (tmp == last_edge_value) {
4976  boost::tie(e1, in1) =
4977  boost::edge(Tree.edgeSource(*ed_it), Tree.edgeTarget(*ed_it),
4978  Tree_temp.getBoostGraph());
4979  removed_edges.push_back(e1);
4980  Tree_temp.removeEdge(Tree.edgeSource(*ed_it),
4981  Tree.edgeTarget(*ed_it));
4982  }
4983  }
4984 
4985  // RES_C t_LabelConnectedComponent(const morphee::graph::CommonGraph32&,
4986  // morphee::graph::CommonGraph32&);
4987 
4988  t_LabelConnectedComponent(Tree_temp, Tree2);
4989 
4990  while (removed_edges.size() > 0) {
4991  e1 = removed_edges.back();
4992  removed_edges.pop_back();
4993 
4994  Tree2.vertexData(Tree.edgeSource(e1), &label1);
4995  Tree2.vertexData(Tree.edgeTarget(e1), &label2);
4996 
4997  Tree.edgeWeight(e1, &tmp);
4998 
4999  double S1 = 0;
5000  double S2 = 0;
5001  double quad1 = 0;
5002  double quad2 = 0;
5003 
5004  for (boost::tie(v_it, v_end) = boost::vertices(Tree2.getBoostGraph());
5005  v_it != v_end; ++v_it) {
5006  Tree2.vertexData(*v_it, &vdata1);
5007  if (vdata1 == label1) {
5008  Tree.vertexData(*v_it, &vdata1);
5009  S1 = S1 + (double) vdata1;
5010  } else if (vdata1 == label2) {
5011  Tree.vertexData(*v_it, &vdata1);
5012  S2 = S2 + (double) vdata1;
5013  }
5014  }
5015 
5016  /*double k = markers*((S1+S2)/(double) volume);
5017  double probability = 1 - std::pow( ( S1/(S1+S2) ) , k ) - std::pow( (
5018  S2/(S1+S2) ) , k ) ; */
5019 
5020  double probability =
5021  1.0 - std::pow(1.0 - S1 / ((double) volume), markers) -
5022  std::pow(1.0 - S2 / ((double) volume), markers) +
5023  std::pow(1.0 - (S1 + S2) / ((double) volume), markers);
5024 
5025  // double probability = 1.0 - 2 * std::pow( 1.0 - std::min(S1,S2) /(
5026  // (double) volume) , markers ) + std::pow( 1.0 - 2 *
5027  // std::min(S1,S2)/((double) volume) , markers );
5028 
5029  if (probability > 0.0) {
5030  RES_C res = Tree_out.edgeFromVertices(Tree.edgeSource(e1),
5031  Tree.edgeTarget(e1), &e2);
5032  Tree_out.setEdgeWeight(e2, 65535.0 * probability);
5033  } else {
5034  RES_C res = Tree_out.edgeFromVertices(Tree.edgeSource(e1),
5035  Tree.edgeTarget(e1), &e2);
5036  Tree_out.setEdgeWeight(e2, 0.0);
5037  }
5038  }
5039 
5040  while (last_edge_value == last_analyzed) {
5041  last_edge_value = val_edges.back();
5042  val_edges.pop_back();
5043  }
5044  last_analyzed = last_edge_value;
5045  }
5046 
5047  std::cout << "project on graphs" << std::endl;
5048  Tree2 = t_CopyGraph(Tree_out);
5049  Tree_temp = t_CopyGraph(Tree_out);
5050 
5051  int lio = 0;
5052 
5053  for (boost::tie(ed_it, ed_end) = boost::edges(Tree_out.getBoostGraph());
5054  ed_it != ed_end; ++ed_it) {
5055  Tree_out.edgeWeight(*ed_it, &tmp);
5056  double value = (double) tmp;
5057 
5058  if (value > 0.0) {
5059  Tree_temp.removeEdge(Tree_out.edgeSource(*ed_it),
5060  Tree_out.edgeTarget(*ed_it));
5061 
5062  // RES_C t_LabelConnectedComponent(const
5063  // morphee::graph::CommonGraph32&, morphee::graph::CommonGraph32&);
5064  t_LabelConnectedComponent(Tree_temp, Tree2);
5065 
5066  Tree_temp.addEdge(Tree_out.edgeSource(*ed_it),
5067  Tree_out.edgeTarget(*ed_it), tmp);
5068 
5069  for (boost::tie(ed_it2, ed_end2) = boost::edges(G.getBoostGraph());
5070  ed_it2 != ed_end2; ++ed_it2) {
5071  Tree2.vertexData(G.edgeSource(*ed_it2), &label1);
5072  Tree2.vertexData(G.edgeTarget(*ed_it2), &label2);
5073 
5074  if (label1 != label2) {
5075  G.edgeWeight(*ed_it2, &tmp);
5076  G.setEdgeWeight(*ed_it2, std::max((double) tmp, value));
5077  }
5078  }
5079  }
5080  std::cout << lio << " / " << Tree_out.numEdges() << std::endl;
5081  lio = lio + 1;
5082  }
5083 
5084  Gin = morphee::graph::MinimumSpanningTreeFromGraph(G);
5085 
5086  std::cout << "project on image the pdf" << std::endl;
5087 
5088  for (it = imOut.begin(), iend = imOut.end(); it != iend;
5089  ++it) // for all pixels in imIn create a vertex
5090  {
5091  o0 = it.getOffset();
5092  imOut.setPixel(o0, 0);
5093  }
5094 
5095  std::cout << "init done" << std::endl;
5096 
5097  for (it = imOut.begin(), iend = imOut.end(); it != iend;
5098  ++it) // for all pixels in imIn create a vertex
5099  {
5100  o0 = it.getOffset();
5101  int val1 = imIn.pixelFromOffset(o0);
5102  double valout1 = imOut.pixelFromOffset(o0);
5103 
5104  neighb.setCenter(o0);
5105 
5106  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
5107  o1 = nit.getOffset();
5108 
5109  if (o1 > o0) {
5110  int val2 = imIn.pixelFromOffset(o1);
5111  double valout2 = imOut.pixelFromOffset(o1);
5112 
5113  if (val2 != val1) {
5114  RES_C res = G.edgeFromVertices(val1 - 1, val2 - 1, &e1);
5115  if (res == RES_OK) {
5116  G.edgeWeight(e1, &tmp);
5117  if (tmp > 0) {
5118  imOut.setPixel(o0, std::max(valout1, (double) tmp));
5119  imOut.setPixel(o1, std::max(valout2, (double) tmp));
5120  }
5121  } else {
5122  RES_C res = G.edgeFromVertices(val2 - 1, val1 - 1, &e1);
5123  if (res == RES_OK) {
5124  G.edgeWeight(e1, &tmp);
5125  if (tmp > 0) {
5126  imOut.setPixel(o0, std::max(valout1, (double) tmp));
5127  imOut.setPixel(o1, std::max(valout2, (double) tmp));
5128  }
5129  }
5130  }
5131  }
5132  }
5133  }
5134  }
5135 
5136  return RES_OK;
5137  }
5138 
5139  template <class ImageIn, class ImageVal, class BoostGraph,
5140  typename _nbmarkers, class SE, class ImageOut>
5141  RES_C t_geoCutsStochastic_Watershed_Graph_NP(const ImageIn &imIn,
5142  const ImageVal &imVal,
5143  BoostGraph &Gin,
5144  const _nbmarkers nbmarkers,
5145  const SE &nl, ImageOut &imOut)
5146  {
5147  MORPHEE_ENTER_FUNCTION("t_geoCutsStochastic_Watershed_Graph_NP");
5148 
5149  std::cout
5150  << "Enter function Geo-Cuts Stochastic Watershed graph non ponctual"
5151  << std::endl;
5152 
5153  if ((!imOut.isAllocated())) {
5154  std::cout << "imOut Not allocated" << std::endl;
5155  MORPHEE_REGISTER_ERROR("Not allocated");
5156  return RES_NOT_ALLOCATED;
5157  }
5158 
5159  if ((!imIn.isAllocated())) {
5160  std::cout << "imIn Not allocated" << std::endl;
5161  MORPHEE_REGISTER_ERROR("Not allocated");
5162  return RES_NOT_ALLOCATED;
5163  }
5164 
5165  if ((!imVal.isAllocated())) {
5166  std::cout << "imVal Not allocated" << std::endl;
5167  MORPHEE_REGISTER_ERROR("Not allocated");
5168  return RES_NOT_ALLOCATED;
5169  }
5170 
5171  double markers = (double) nbmarkers;
5172 
5173  int size = imIn.getXSize() * imIn.getYSize() * imIn.getZSize();
5174  std::cout << size << std::endl;
5175 
5176  typename ImageOut::const_iterator it, iend;
5177  typename ImageIn::const_iterator it2, iend2;
5178  morphee::selement::Neighborhood<SE, ImageOut> neighb(imOut, nl);
5179  typename morphee::selement::Neighborhood<SE, ImageOut>::iterator nit,
5180  nend;
5181  offset_t o0, o1;
5182 
5183  typedef typename BoostGraph::EdgeIterator EdgeIterator;
5184  typedef typename BoostGraph::VertexIterator VertexIterator;
5185  typedef typename BoostGraph::EdgeDescriptor EdgeDescriptor;
5186  typedef typename BoostGraph::VertexDescriptor VertexDescriptor;
5187  typename morphee::graph::CommonGraph32::EdgeProperty tmp;
5188  typename morphee::graph::CommonGraph32::VertexProperty vdata1;
5189  typename morphee::graph::CommonGraph32::VertexProperty label1, label2;
5190  EdgeIterator ed_it, ed_end, ed_it2, ed_end2;
5191  VertexIterator v_it, v_end;
5192  EdgeDescriptor last_edge, e1, e2;
5193 
5194  bool in1;
5195 
5196  std::vector<double> val_edges;
5197  val_edges.push_back(0.0);
5198  double last_edge_value = 0.0;
5199 
5200  std::vector<EdgeDescriptor> removed_edges;
5201 
5202  morphee::graph::CommonGraph32 G(0);
5203  morphee::graph::CommonGraph32 G2(0);
5204  morphee::graph::CommonGraph32 Tree(0);
5205 
5206  std::cout << " Get NeighborhoodGraph " << std::endl;
5207  morphee::morphoBase::t_NeighborhoodGraphFromMosaic(imIn, nl, G);
5208 
5209  std::cout << "Copy Minimum Spanning Tree" << std::endl;
5210  Tree = t_CopyGraph(Gin);
5211 
5212  std::cout << "Done" << std::endl;
5213 
5214  // const morphee::graph::CommonGraph32 t_CopyGraph(const
5215  // morphee::graph::CommonGraph32 &);
5216 
5217  morphee::graph::t_ProjectMarkersOnGraph(imVal, imIn, Tree);
5218  morphee::graph::CommonGraph32 Tree_temp = t_CopyGraph(Tree);
5219  morphee::graph::CommonGraph32 Tree_out = t_CopyGraph(Tree);
5220  morphee::graph::CommonGraph32 Tree2 = t_CopyGraph(Tree_temp);
5221 
5222  double volume = 0.0;
5223  for (boost::tie(v_it, v_end) = boost::vertices(G.getBoostGraph());
5224  v_it != v_end; ++v_it) {
5225  Tree.vertexData(*v_it, &vdata1);
5226  volume = volume + (double) vdata1;
5227  }
5228 
5229  for (boost::tie(ed_it, ed_end) = boost::edges(G.getBoostGraph());
5230  ed_it != ed_end; ++ed_it) {
5231  G.setEdgeWeight(*ed_it, 0);
5232  }
5233 
5234  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
5235  ed_it != ed_end; ++ed_it) {
5236  Tree.edgeWeight(*ed_it, &tmp);
5237 
5238  val_edges.push_back(tmp);
5239  last_edge_value = (double) tmp;
5240  }
5241 
5242  std::cout << "sort" << std::endl;
5243  // std::sort(val_edges.begin(), val_edges.end());
5244  std::sort(val_edges.begin(), val_edges.end(), std::less<double>());
5245 
5246  last_edge_value = val_edges.back();
5247  float max_value = last_edge_value;
5248  double last_analyzed = last_edge_value;
5249 
5250  while (val_edges.size() > 1) {
5251  // std::cout<<val_edges.size()<<std::endl;
5252  // std::cout<<last_edge_value<<std::endl;
5253 
5254  // remove edge of maximal weight
5255  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
5256  ed_it != ed_end; ++ed_it) {
5257  // std::cout<<"look"<<std::endl;
5258  Tree.edgeWeight(*ed_it, &tmp);
5259 
5260  if (tmp == last_edge_value) {
5261  boost::tie(e1, in1) =
5262  boost::edge(Tree.edgeSource(*ed_it), Tree.edgeTarget(*ed_it),
5263  Tree_temp.getBoostGraph());
5264  removed_edges.push_back(e1);
5265  Tree_temp.removeEdge(Tree.edgeSource(*ed_it),
5266  Tree.edgeTarget(*ed_it));
5267  }
5268  }
5269 
5270  // RES_C t_LabelConnectedComponent(const morphee::graph::CommonGraph32&,
5271  // morphee::graph::CommonGraph32&);
5272  t_LabelConnectedComponent(Tree_temp, Tree2);
5273 
5274  while (removed_edges.size() > 0) {
5275  e1 = removed_edges.back();
5276  removed_edges.pop_back();
5277 
5278  Tree2.vertexData(Tree.edgeSource(e1), &label1);
5279  Tree2.vertexData(Tree.edgeTarget(e1), &label2);
5280 
5281  Tree.edgeWeight(e1, &tmp);
5282 
5283  double S1 = 0;
5284  double S2 = 0;
5285  double quad1 = 0;
5286  double quad2 = 0;
5287 
5288  for (boost::tie(v_it, v_end) = boost::vertices(Tree2.getBoostGraph());
5289  v_it != v_end; ++v_it) {
5290  Tree2.vertexData(*v_it, &vdata1);
5291  if (vdata1 == label1) {
5292  Tree.vertexData(*v_it, &vdata1);
5293  S1 = S1 + (double) vdata1;
5294  } else if (vdata1 == label2) {
5295  Tree.vertexData(*v_it, &vdata1);
5296  S2 = S2 + (double) vdata1;
5297  }
5298  }
5299 
5300  /*double k = markers*((S1+S2)/(double) volume);
5301  double probability = 1 - std::pow( ( S1/(S1+S2) ) , k ) - std::pow( (
5302  S2/(S1+S2) ) , k ) ; */
5303 
5304  double probability =
5305  1.0 - std::pow(1.0 - S1 / ((double) volume), markers) -
5306  std::pow(1.0 - S2 / ((double) volume), markers) +
5307  std::pow(1.0 - (S1 + S2) / ((double) volume), markers);
5308 
5309  // double probability = 1.0 - 2 * std::pow( 1.0 - std::min(S1,S2) /(
5310  // (double) volume) , markers ) + std::pow( 1.0 - 2 *
5311  // std::min(S1,S2)/((double) volume) , markers );
5312 
5313  if (probability > 0.0) {
5314  RES_C res = Tree_out.edgeFromVertices(Tree.edgeSource(e1),
5315  Tree.edgeTarget(e1), &e2);
5316  Tree_out.setEdgeWeight(e2, 65535.0 * probability);
5317  } else {
5318  RES_C res = Tree_out.edgeFromVertices(Tree.edgeSource(e1),
5319  Tree.edgeTarget(e1), &e2);
5320  Tree_out.setEdgeWeight(e2, 0.0);
5321  }
5322  }
5323 
5324  while (last_edge_value == last_analyzed) {
5325  last_edge_value = val_edges.back();
5326  val_edges.pop_back();
5327  }
5328  last_analyzed = last_edge_value;
5329  }
5330 
5331  std::cout << "project on graphs" << std::endl;
5332  // const morphee::graph::CommonGraph32 t_CopyGraph(const
5333  // morphee::graph::CommonGraph32 &);
5334  Tree2 = t_CopyGraph(Tree_out);
5335  Tree_temp = t_CopyGraph(Tree_out);
5336 
5337  int lio = 0;
5338 
5339  for (boost::tie(ed_it, ed_end) = boost::edges(Tree_out.getBoostGraph());
5340  ed_it != ed_end; ++ed_it) {
5341  Tree_out.edgeWeight(*ed_it, &tmp);
5342  double value = (double) tmp;
5343 
5344  if (value > 0.0) {
5345  Tree_temp.removeEdge(Tree_out.edgeSource(*ed_it),
5346  Tree_out.edgeTarget(*ed_it));
5347 
5348  // RES_C t_LabelConnectedComponent(const
5349  // morphee::graph::CommonGraph32&, morphee::graph::CommonGraph32&);
5350  t_LabelConnectedComponent(Tree_temp, Tree2);
5351 
5352  Tree_temp.addEdge(Tree_out.edgeSource(*ed_it),
5353  Tree_out.edgeTarget(*ed_it), tmp);
5354 
5355  for (boost::tie(ed_it2, ed_end2) = boost::edges(G.getBoostGraph());
5356  ed_it2 != ed_end2; ++ed_it2) {
5357  Tree2.vertexData(G.edgeSource(*ed_it2), &label1);
5358  Tree2.vertexData(G.edgeTarget(*ed_it2), &label2);
5359 
5360  if (label1 != label2) {
5361  G.edgeWeight(*ed_it2, &tmp);
5362  G.setEdgeWeight(*ed_it2, std::max((double) tmp, value));
5363  }
5364  }
5365  }
5366  std::cout << lio << " / " << Tree_out.numEdges() << std::endl;
5367  lio = lio + 1;
5368  }
5369 
5370  Gin = morphee::graph::MinimumSpanningTreeFromGraph(G);
5371 
5372  std::cout << "project on image the pdf" << std::endl;
5373 
5374  for (it = imOut.begin(), iend = imOut.end(); it != iend;
5375  ++it) // for all pixels in imIn create a vertex
5376  {
5377  o0 = it.getOffset();
5378  imOut.setPixel(o0, 0);
5379  }
5380 
5381  std::cout << "init done" << std::endl;
5382 
5383  for (it = imOut.begin(), iend = imOut.end(); it != iend;
5384  ++it) // for all pixels in imIn create a vertex
5385  {
5386  o0 = it.getOffset();
5387  int val1 = imIn.pixelFromOffset(o0);
5388  double valout1 = imOut.pixelFromOffset(o0);
5389 
5390  neighb.setCenter(o0);
5391 
5392  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
5393  o1 = nit.getOffset();
5394 
5395  if (o1 > o0) {
5396  int val2 = imIn.pixelFromOffset(o1);
5397  double valout2 = imOut.pixelFromOffset(o1);
5398 
5399  if (val2 != val1) {
5400  RES_C res = G.edgeFromVertices(val1 - 1, val2 - 1, &e1);
5401  if (res == RES_OK) {
5402  G.edgeWeight(e1, &tmp);
5403  if (tmp > 0) {
5404  imOut.setPixel(o0, std::max(valout1, (double) tmp));
5405  imOut.setPixel(o1, std::max(valout2, (double) tmp));
5406  }
5407  } else {
5408  RES_C res = G.edgeFromVertices(val2 - 1, val1 - 1, &e1);
5409  if (res == RES_OK) {
5410  G.edgeWeight(e1, &tmp);
5411  if (tmp > 0) {
5412  imOut.setPixel(o0, std::max(valout1, (double) tmp));
5413  imOut.setPixel(o1, std::max(valout2, (double) tmp));
5414  }
5415  }
5416  }
5417  }
5418  }
5419  }
5420  }
5421 
5422  return RES_OK;
5423  }
5424 
5425  template <class BoostGraph>
5426  RES_C t_UpdateSpanningTreeFromForest(const BoostGraph &ForestIn,
5427  const BoostGraph &TIn,
5428  BoostGraph &Tout)
5429  {
5430  MORPHEE_ENTER_FUNCTION("t_UpdateSpanningTreeFromForest");
5431 
5432  std::cout << "Enter function t_UpdateSpanningTreeFromForest "
5433  << std::endl;
5434 
5435  typedef typename BoostGraph::EdgeIterator EdgeIterator;
5436  typedef typename BoostGraph::VertexIterator VertexIterator;
5437  typedef typename BoostGraph::EdgeDescriptor EdgeDescriptor;
5438  typedef typename BoostGraph::VertexDescriptor VertexDescriptor;
5439  typename BoostGraph::EdgeProperty tmp;
5440  EdgeIterator ed_it, ed_end, ed_it2, ed_end2;
5441  VertexIterator v_it, v_end;
5442  EdgeDescriptor last_edge, e1, e2;
5443 
5444  bool in1;
5445 
5446  Tout = t_CopyGraph(TIn);
5447 
5448  for (boost::tie(ed_it, ed_end) = boost::edges(ForestIn.getBoostGraph());
5449  ed_it != ed_end; ++ed_it) {
5450  ForestIn.edgeWeight(*ed_it, &tmp);
5451  boost::tie(e1, in1) =
5452  boost::edge(ForestIn.edgeSource(*ed_it),
5453  ForestIn.edgeTarget(*ed_it), Tout.getBoostGraph());
5454  Tout.setEdgeWeight(e1, 0);
5455  }
5456 
5457  return RES_OK;
5458  }
5459 
5460  template <class ImageIn, class BoostGraph, class SE, class ImageOut>
5461  RES_C t_GetUltrametricContourMap(const ImageIn &imIn,
5462  const BoostGraph &Tree, const SE &nl,
5463  ImageOut &imOut)
5464  {
5465  MORPHEE_ENTER_FUNCTION("t_GetUltrametricContourMap");
5466 
5467  std::cout << "Enter t_GetUltrametricContourMap " << std::endl;
5468 
5469  if ((!imOut.isAllocated())) {
5470  MORPHEE_REGISTER_ERROR("Not allocated");
5471  return RES_NOT_ALLOCATED;
5472  }
5473 
5474  if ((!imIn.isAllocated())) {
5475  MORPHEE_REGISTER_ERROR("Not allocated");
5476  return RES_NOT_ALLOCATED;
5477  }
5478 
5479  int size = imIn.getXSize() * imIn.getYSize() * imIn.getZSize();
5480  // std::cout<<size<<std::endl;
5481 
5482  typename BoostGraph::VertexProperty label1, label2;
5483  typedef typename BoostGraph::EdgeProperty EdgeProperty;
5484  typedef typename BoostGraph::EdgeDescriptor EdgeDescriptor;
5485  typedef typename BoostGraph::VertexDescriptor VertexDescriptor;
5486  EdgeDescriptor e1;
5487  EdgeProperty tmp;
5488 
5489  typedef typename BoostGraph::EdgeIterator EdgeIterator;
5490  EdgeIterator ed_it, ed_end, ed_it2, ed_end2;
5491 
5492  std::cout << "project on image the graph" << std::endl;
5493 
5494  typename ImageOut::const_iterator it, iend;
5495  morphee::selement::Neighborhood<SE, ImageOut> neighb(imOut, nl);
5496  typename morphee::selement::Neighborhood<SE, ImageOut>::iterator nit,
5497  nend;
5498  offset_t o0, o1;
5499 
5500  for (it = imOut.begin(), iend = imOut.end(); it != iend;
5501  ++it) // for all pixels in imIn create a vertex
5502  {
5503  o0 = it.getOffset();
5504  imOut.setPixel(o0, 0);
5505  }
5506 
5507  std::cout << "project on graphs" << std::endl;
5508  BoostGraph G, Tree2, Tree_temp;
5509 
5510  Tree2 = t_CopyGraph(Tree);
5511  Tree_temp = t_CopyGraph(Tree);
5512 
5513  std::cout << "t_NeighborhoodGraphFromMosaic" << std::endl;
5514  morphee::morphoBase::t_NeighborhoodGraphFromMosaic(imIn, nl, G);
5515 
5516  for (boost::tie(ed_it, ed_end) = boost::edges(G.getBoostGraph());
5517  ed_it != ed_end; ++ed_it) {
5518  G.setEdgeWeight(*ed_it, 0);
5519  }
5520 
5521  std::cout << "iterate..." << std::endl;
5522 
5523  int lio = 0;
5524 
5525  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
5526  ed_it != ed_end; ++ed_it) {
5527  Tree.edgeWeight(*ed_it, &tmp);
5528  double value = (double) tmp;
5529 
5530  if (value > 0.0) {
5531  // v1 = BoostGraph::VertexDescriptor( Tree.edgeSource(*ed_it)) ;
5532  // v2 = BoostGraph::VertexDescriptor( Tree.edgeTarget(*ed_it)) ;
5533 
5534  Tree_temp.removeEdge(
5535  typename BoostGraph::VertexDescriptor(Tree.edgeSource(*ed_it)),
5536  typename BoostGraph::VertexDescriptor(Tree.edgeTarget(*ed_it)));
5537 
5538  t_LabelConnectedComponent(Tree_temp, Tree2);
5539 
5540  Tree_temp.addEdge(
5541  typename BoostGraph::VertexDescriptor(Tree.edgeSource(*ed_it)),
5542  typename BoostGraph::VertexDescriptor(Tree.edgeTarget(*ed_it)),
5543  tmp);
5544 
5545  for (boost::tie(ed_it2, ed_end2) = boost::edges(G.getBoostGraph());
5546  ed_it2 != ed_end2; ++ed_it2) {
5547  Tree2.vertexData(
5548  typename BoostGraph::VertexDescriptor(G.edgeSource(*ed_it2)),
5549  &label1);
5550  Tree2.vertexData(
5551  typename BoostGraph::VertexDescriptor(G.edgeTarget(*ed_it2)),
5552  &label2);
5553 
5554  if (label1 != label2) {
5555  G.edgeWeight(*ed_it2, &tmp);
5556  G.setEdgeWeight(*ed_it2, std::max((double) tmp, value));
5557  // G.setEdgeWeight(*ed_it2,(double)tmp+value);
5558  }
5559  }
5560  }
5561  std::cout << lio << " / " << Tree.numEdges() << std::endl;
5562  lio = lio + 1;
5563  }
5564 
5565  std::cout << "project on image " << std::endl;
5566  for (it = imOut.begin(), iend = imOut.end(); it != iend;
5567  ++it) // for all pixels in imIn create a vertex
5568  {
5569  o0 = it.getOffset();
5570 
5571  int val1 = imIn.pixelFromOffset(o0);
5572 
5573  double valout1 = imOut.pixelFromOffset(o0);
5574 
5575  neighb.setCenter(o0);
5576 
5577  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
5578  o1 = nit.getOffset();
5579 
5580  if (o1 > o0) {
5581  int val2 = imIn.pixelFromOffset(o1);
5582 
5583  double valout2 = imOut.pixelFromOffset(o1);
5584 
5585  if (val2 != val1) {
5586  RES_C res = G.edgeFromVertices(val1 - 1, val2 - 1, &e1);
5587 
5588  if (res == RES_OK) {
5589  G.edgeWeight(e1, &tmp);
5590 
5591  if (tmp > 0) {
5592  imOut.setPixel(
5593  o0, std::max(valout2, std::max(valout1, (double) tmp)));
5594  // imOut.setPixel( o1 , std::max( valout2, (double) tmp));
5595  }
5596  }
5597 
5598  else {
5599  RES_C res = G.edgeFromVertices(val2 - 1, val1 - 1, &e1);
5600  if (res == RES_OK) {
5601  G.edgeWeight(e1, &tmp);
5602  if (tmp > 0) {
5603  imOut.setPixel(
5604  o0, std::max(valout2, std::max(valout1, (double) tmp)));
5605  // imOut.setPixel( o1 , std::max( valout2, (double) tmp));
5606  }
5607  }
5608  }
5609  }
5610  }
5611  }
5612  }
5613 
5614  return RES_OK;
5615  }
5616 
5617  template <class ImageIn, class BoostGraph, class SE, class ImageOut>
5618  RES_C t_GetScaleSetUltrametricContourMap(const ImageIn &imIn,
5619  const BoostGraph &Tree,
5620  const SE &nl, ImageOut &imOut)
5621  {
5622  MORPHEE_ENTER_FUNCTION("t_GetScaleSetUltrametricContourMap");
5623 
5624  std::cout << "Enter t_GetScaleSetUltrametricContourMap " << std::endl;
5625 
5626  if ((!imOut.isAllocated())) {
5627  MORPHEE_REGISTER_ERROR("Not allocated");
5628  return RES_NOT_ALLOCATED;
5629  }
5630 
5631  if ((!imIn.isAllocated())) {
5632  MORPHEE_REGISTER_ERROR("Not allocated");
5633  return RES_NOT_ALLOCATED;
5634  }
5635 
5636  int size = imIn.getXSize() * imIn.getYSize() * imIn.getZSize();
5637  // std::cout<<size<<std::endl;
5638 
5639  typename BoostGraph::VertexProperty label1, label2, vdata1, vdata2;
5640  typedef typename BoostGraph::EdgeProperty EdgeProperty;
5641  typedef typename BoostGraph::EdgeDescriptor EdgeDescriptor;
5642  typedef typename BoostGraph::VertexDescriptor VertexDescriptor;
5643  EdgeDescriptor e1;
5644  EdgeProperty tmp;
5645  VertexDescriptor vs, vt;
5646  bool in1;
5647 
5648  typedef typename BoostGraph::EdgeIterator EdgeIterator;
5649  EdgeIterator ed_it, ed_end, ed_it2, ed_end2;
5650 
5651  std::cout << "project on image the graph" << std::endl;
5652 
5653  typename ImageIn::const_iterator it2, iend2;
5654 
5655  typename ImageOut::const_iterator it, iend;
5656  morphee::selement::Neighborhood<SE, ImageOut> neighb(imOut, nl);
5657  typename morphee::selement::Neighborhood<SE, ImageOut>::iterator nit,
5658  nend;
5659  offset_t o0, o1;
5660 
5661  for (it = imOut.begin(), iend = imOut.end(); it != iend;
5662  ++it) // for all pixels in imIn create a vertex
5663  {
5664  o0 = it.getOffset();
5665  imOut.setPixel(o0, 0);
5666  }
5667 
5668  std::cout << "project on graphs" << std::endl;
5669  BoostGraph G;
5670 
5671  std::cout << "t_NeighborhoodGraphFromMosaic" << std::endl;
5672  morphee::morphoBase::t_NeighborhoodGraphFromMosaic(imIn, nl, G);
5673 
5674  for (boost::tie(ed_it, ed_end) = boost::edges(G.getBoostGraph());
5675  ed_it != ed_end; ++ed_it) {
5676  G.setEdgeWeight(*ed_it, 0);
5677  }
5678 
5679  std::vector<double> val_edges;
5680 
5681  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
5682  ed_it != ed_end; ++ed_it) {
5683  Tree.edgeWeight(*ed_it, &tmp);
5684  val_edges.push_back(tmp);
5685  }
5686 
5687  int numVert = 0;
5688 
5689  for (it2 = imIn.begin(), iend2 = imIn.end(); it2 != iend2;
5690  ++it2) // for all pixels in imIn create a vertex
5691  {
5692  o0 = it2.getOffset();
5693  int val = imIn.pixelFromOffset(o0);
5694 
5695  if (val > numVert) {
5696  numVert = val;
5697  }
5698  }
5699 
5700  std::cout << "nb of regions = " << numVert << std::endl;
5701 
5702  // INIT TREETEMP
5703  BoostGraph Tree_label = morphee::graph::CommonGraph32(numVert);
5704  BoostGraph Tree_temp = morphee::graph::CommonGraph32(numVert);
5705 
5706  std::cout << "sort edges of tree" << std::endl;
5707  std::sort(val_edges.begin(), val_edges.end(), std::greater<double>());
5708 
5709  double last_edge_value = val_edges.back();
5710  double last_analyzed = last_edge_value;
5711  val_edges.pop_back();
5712 
5713  std::cout << "iterate..." << std::endl;
5714  int lio = 0;
5715 
5716  while (val_edges.size() > 0) {
5717  // add edge of minimal weight
5718  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
5719  ed_it != ed_end; ++ed_it) {
5720  Tree.edgeWeight(*ed_it, &tmp);
5721 
5722  if (tmp == last_edge_value) { // check if current min
5723 
5724  vs = Tree.edgeSource(*ed_it);
5725  vt = Tree.edgeTarget(*ed_it);
5726  boost::tie(e1, in1) =
5727  boost::add_edge(vs, vt, Tree_temp.getBoostGraph());
5728  }
5729  }
5730 
5731  // AFTER MERGING
5732  int number_of_connected_components;
5733  t_LabelConnectedComponent(Tree_temp, Tree_label,
5734  &number_of_connected_components);
5735  std::cout << "number_of_connected_components = "
5736  << number_of_connected_components << std::endl;
5737 
5738  for (boost::tie(ed_it, ed_end) = boost::edges(G.getBoostGraph());
5739  ed_it != ed_end; ++ed_it) {
5740  vs = G.edgeSource(*ed_it);
5741  vt = G.edgeTarget(*ed_it);
5742 
5743  // new label of the regions
5744  Tree_label.vertexData(vs, &vdata1);
5745  Tree_label.vertexData(vt, &vdata2);
5746 
5747  G.edgeWeight(*ed_it, &tmp);
5748 
5749  if (vdata1 != vdata2) {
5750  G.setEdgeWeight(*ed_it,
5751  std::max((float) tmp, (float) last_edge_value));
5752  }
5753  }
5754 
5755  while (last_edge_value == last_analyzed) {
5756  last_edge_value = val_edges.back();
5757  val_edges.pop_back();
5758  }
5759  last_analyzed = last_edge_value;
5760  }
5761 
5762  std::cout << "project on image " << std::endl;
5763  for (it = imOut.begin(), iend = imOut.end(); it != iend;
5764  ++it) // for all pixels in imIn create a vertex
5765  {
5766  o0 = it.getOffset();
5767 
5768  int val1 = imIn.pixelFromOffset(o0);
5769 
5770  double valout1 = imOut.pixelFromOffset(o0);
5771 
5772  neighb.setCenter(o0);
5773 
5774  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
5775  o1 = nit.getOffset();
5776 
5777  if (o1 > o0) {
5778  int val2 = imIn.pixelFromOffset(o1);
5779 
5780  double valout2 = imOut.pixelFromOffset(o1);
5781 
5782  if (val2 != val1) {
5783  RES_C res = G.edgeFromVertices(val1 - 1, val2 - 1, &e1);
5784 
5785  if (res == RES_OK) {
5786  G.edgeWeight(e1, &tmp);
5787 
5788  if (tmp > 0) {
5789  imOut.setPixel(
5790  o0, std::max(valout2, std::max(valout1, (double) tmp)));
5791  // imOut.setPixel( o1 , std::max( valout2, (double) tmp));
5792  }
5793  }
5794 
5795  else {
5796  RES_C res = G.edgeFromVertices(val2 - 1, val1 - 1, &e1);
5797  if (res == RES_OK) {
5798  G.edgeWeight(e1, &tmp);
5799  if (tmp > 0) {
5800  imOut.setPixel(
5801  o0, std::max(valout2, std::max(valout1, (double) tmp)));
5802  // imOut.setPixel( o1 , std::max( valout2, (double) tmp));
5803  }
5804  }
5805  }
5806  }
5807  }
5808  }
5809  }
5810 
5811  return RES_OK;
5812  }
5813 
5814  template <class ImageIn, class ImageIn2, class ImageVal,
5815  typename _nbmarkers, typename _alpha, class SE, class ImageOut>
5816  RES_C t_geoCutsStochastic_Watershed_Variance(const ImageIn &imIn,
5817  const ImageIn2 &imVal,
5818  const ImageVal &imGrad,
5819  const _nbmarkers nbmarkers,
5820  const _alpha alpha,
5821  const SE &nl, ImageOut &imOut)
5822  {
5823  MORPHEE_ENTER_FUNCTION("t_geoCutsStochastic_Watershed");
5824 
5825  std::cout << "Enter function Geo-Cuts Stochastic Watershed" << std::endl;
5826 
5827  if ((!imOut.isAllocated())) {
5828  MORPHEE_REGISTER_ERROR("Not allocated");
5829  return RES_NOT_ALLOCATED;
5830  }
5831 
5832  if ((!imIn.isAllocated())) {
5833  MORPHEE_REGISTER_ERROR("Not allocated");
5834  return RES_NOT_ALLOCATED;
5835  }
5836 
5837  if ((!imVal.isAllocated())) {
5838  MORPHEE_REGISTER_ERROR("Not allocated");
5839  return RES_NOT_ALLOCATED;
5840  }
5841 
5842  if ((!imGrad.isAllocated())) {
5843  MORPHEE_REGISTER_ERROR("Not allocated");
5844  return RES_NOT_ALLOCATED;
5845  }
5846 
5847  double markers = (double) nbmarkers;
5848 
5849  int size = imIn.getXSize() * imIn.getYSize() * imIn.getZSize();
5850  // std::cout<<size<<std::endl;
5851 
5852  typedef typename morphee::graph::CommonGraph32::_boostGraph BoostGraph;
5853  typedef
5854  typename boost::graph_traits<BoostGraph>::edge_iterator EdgeIterator;
5855  typedef typename boost::graph_traits<BoostGraph>::vertex_iterator
5856  VertexIterator;
5857  typedef typename boost::graph_traits<BoostGraph>::edge_descriptor
5858  EdgeDescriptor;
5859  typedef typename boost::graph_traits<BoostGraph>::vertex_descriptor
5860  VertexDescriptor;
5861  typename morphee::graph::CommonGraph32::EdgeProperty tmp;
5862  typename morphee::graph::CommonGraph32::VertexProperty vdata1;
5863  typename morphee::graph::CommonGraph32::VertexProperty label1, label2,
5864  label21, label22;
5865  EdgeIterator ed_it, ed_end, ed_it2, ed_end2;
5866  VertexIterator v_it, v_end;
5867  EdgeDescriptor last_edge, e1, e2;
5868 
5869  bool in1;
5870 
5871  std::vector<double> val_edges;
5872  val_edges.push_back(0.0);
5873  double last_edge_value = 0.0;
5874 
5875  std::vector<EdgeDescriptor> removed_edges;
5876 
5877  morphee::graph::CommonGraph32 G(0);
5878  morphee::graph::CommonGraph32 G2(0);
5879  morphee::graph::CommonGraph32 Tree(0);
5880 
5881  // morphee::morphoBase::t_NeighborhoodGraphFromMosaic_WithPass(imIn,imGrad,nl,G);
5882  // morphee::graphalgo::t_NeighborhoodGraphFromMosaic_WithMeanGradientValue(imIn,imGrad,nl,G);
5883  morphee::graphalgo::
5884  t_NeighborhoodGraphFromMosaic_WithMeanGradientValue_AndQuadError(
5885  imIn, imGrad, imVal, alpha, nl, G);
5886 
5887  Tree = morphee::graph::MinimumSpanningTreeFromGraph(G);
5888 
5889  ImageIn ImTempSurfaces = imIn.getSame();
5890  // Image<UINT8>ImTempSurfaces = imIn.t_getSame<UINT8>();
5891  morphee::morphoBase::t_ImLabelFlatZonesWithArea(imIn, nl, ImTempSurfaces);
5892  // morphee::morphoBase::t_ImLabelFlatZonesWithVolume(imIn,imVal,nl,ImTempSurfaces);
5893 
5894  // const morphee::graph::CommonGraph32 t_CopyGraph(const
5895  // morphee::graph::CommonGraph32 &);
5896  morphee::graph::CommonGraph32 Tree_temp = t_CopyGraph(Tree);
5897  morphee::graph::CommonGraph32 Tree_out = t_CopyGraph(Tree);
5898  morphee::graph::CommonGraph32 Tree2 = t_CopyGraph(Tree_temp);
5899 
5900  morphee::graph::t_ProjectMarkersOnGraph(ImTempSurfaces, imIn, Tree);
5901 
5902  double volume = 0.0;
5903  for (boost::tie(v_it, v_end) = boost::vertices(Tree.getBoostGraph());
5904  v_it != v_end; ++v_it) {
5905  Tree.vertexData(*v_it, &vdata1);
5906  volume = volume + (double) vdata1;
5907  }
5908 
5909  for (boost::tie(ed_it, ed_end) = boost::edges(G.getBoostGraph());
5910  ed_it != ed_end; ++ed_it) {
5911  G.setEdgeWeight(*ed_it, 0);
5912  }
5913 
5914  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
5915  ed_it != ed_end; ++ed_it) {
5916  Tree.edgeWeight(*ed_it, &tmp);
5917  // if( (double) tmp > last_edge_value) {
5918 
5919  val_edges.push_back(tmp);
5920  last_edge_value = (double) tmp;
5921 
5922  //}
5923  }
5924 
5925  std::cout << "sort" << std::endl;
5926  // std::sort(val_edges.begin(), val_edges.end());
5927  std::sort(val_edges.begin(), val_edges.end(), std::less<int>());
5928 
5929  last_edge_value = val_edges.back();
5930  double last_analyzed = last_edge_value;
5931 
5932  while (val_edges.size() > 1) {
5933  // std::cout<<val_edges.size()<<std::endl;
5934  // std::cout<<last_edge_value<<std::endl;
5935 
5936  // remove edge of maximal weight
5937  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
5938  ed_it != ed_end; ++ed_it) {
5939  // std::cout<<"look"<<std::endl;
5940  Tree.edgeWeight(*ed_it, &tmp);
5941 
5942  if (tmp == last_edge_value) {
5943  boost::tie(e1, in1) =
5944  boost::edge(Tree.edgeSource(*ed_it), Tree.edgeTarget(*ed_it),
5945  Tree_temp.getBoostGraph());
5946  removed_edges.push_back(e1);
5947  Tree_temp.removeEdge(
5948  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
5949  Tree.edgeSource(*ed_it)),
5950  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
5951  Tree.edgeTarget(*ed_it)));
5952  }
5953  }
5954 
5955  // RES_C t_LabelConnectedComponent(const morphee::graph::CommonGraph32&,
5956  // morphee::graph::CommonGraph32&);
5957  t_LabelConnectedComponent(Tree_temp, Tree2);
5958 
5959  while (removed_edges.size() > 0) {
5960  e1 = removed_edges.back();
5961  removed_edges.pop_back();
5962 
5963  Tree2.vertexData(
5964  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
5965  Tree.edgeSource(e1)),
5966  &label1);
5967  Tree2.vertexData(
5968  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
5969  Tree.edgeTarget(e1)),
5970  &label2);
5971 
5972  double S1 = 0;
5973  double S2 = 0;
5974  double perimeter_1 = 0;
5975  double perimeter_2 = 0;
5976 
5977  for (boost::tie(v_it, v_end) = boost::vertices(Tree2.getBoostGraph());
5978  v_it != v_end; ++v_it) {
5979  Tree2.vertexData(*v_it, &vdata1);
5980  if (vdata1 == label1) {
5981  Tree.vertexData(*v_it, &vdata1);
5982  S1 = S1 + (double) vdata1;
5983  } else if (vdata1 == label2) {
5984  Tree.vertexData(*v_it, &vdata1);
5985  S2 = S2 + (double) vdata1;
5986  }
5987  }
5988 
5989  for (boost::tie(ed_it2, ed_end2) = boost::edges(G.getBoostGraph());
5990  ed_it2 != ed_end2; ++ed_it2) {
5991  Tree2.vertexData(
5992  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
5993  Tree.edgeSource(*ed_it2)),
5994  &label21);
5995  Tree2.vertexData(
5996  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
5997  Tree.edgeTarget(*ed_it2)),
5998  &label22);
5999 
6000  if ((label21 == label1 && label22 != label1) ||
6001  (label21 != label1 && label22 == label1)) {
6002  perimeter_1 = perimeter_1 + 1.0;
6003  }
6004  if ((label21 != label2 && label22 == label2) ||
6005  (label21 == label2 && label22 != label2)) {
6006  perimeter_2 = perimeter_2 + 1.0;
6007  }
6008  }
6009 
6010  // double pie = 3.14159265358979323846;
6011  // double C1 = perimeter_1*perimeter_1 / (4 * pie * S1);
6012  // double C2 = perimeter_2*perimeter_2 / (4 * pie * S2);
6013  // double probability2 = ( std::pow( C1 , markers ) + std::pow( C2 ,
6014  // markers ) );
6015 
6016  // double k = markers*((S1+S2)/(double) volume);
6017  // double probability = 1 - std::pow( ( S1/(S1+S2) ) , k ) - std::pow(
6018  // ( S2/(S1+S2) ) , k ) ; double probability = 1 - std::pow( 1 -
6019  // S1/((double) volume) , markers ) - std::pow( 1- S2/((double)
6020  // volume) , markers ) + std::pow( 1- (S1+S2)/((double) volume) ,
6021  // markers );
6022  double probability =
6023  (1 - std::pow(1 - S1 / ((double) volume), markers) -
6024  std::pow(1 - S2 / ((double) volume), markers) +
6025  std::pow(1 - (S1 + S2) / ((double) volume), markers));
6026 
6027  // std::cout<<"probability :" <<probability<<std::endl;
6028 
6029  if (probability > 0.0) {
6030  RES_C res = Tree_out.edgeFromVertices(
6031  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6032  Tree.edgeSource(e1)),
6033  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6034  Tree.edgeTarget(e1)),
6035  &e2);
6036  Tree_out.setEdgeWeight(e2, 255.0 * probability);
6037  } else {
6038  RES_C res = Tree_out.edgeFromVertices(
6039  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6040  Tree.edgeSource(e1)),
6041  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6042  Tree.edgeTarget(e1)),
6043  &e2);
6044  Tree_out.setEdgeWeight(e2, 0.0);
6045  }
6046  }
6047 
6048  while (last_edge_value == last_analyzed) {
6049  last_edge_value = val_edges.back();
6050  val_edges.pop_back();
6051  }
6052  last_analyzed = last_edge_value;
6053  }
6054 
6055  std::cout << "project on graphs" << std::endl;
6056 
6057  // const morphee::graph::CommonGraph32 t_CopyGraph(const
6058  // morphee::graph::CommonGraph32 &);
6059  Tree2 = t_CopyGraph(Tree_out);
6060  Tree_temp = t_CopyGraph(Tree_out);
6061 
6062  for (boost::tie(ed_it, ed_end) = boost::edges(Tree_out.getBoostGraph());
6063  ed_it != ed_end; ++ed_it) {
6064  Tree_out.edgeWeight(*ed_it, &tmp);
6065  double value = (double) tmp;
6066 
6067  if (value > 0.0) {
6068  Tree_temp.removeEdge(
6069  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6070  Tree_out.edgeSource(*ed_it)),
6071  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6072  Tree_out.edgeTarget(*ed_it)));
6073 
6074  // RES_C t_LabelConnectedComponent(const
6075  // morphee::graph::CommonGraph32&, morphee::graph::CommonGraph32&);
6076  t_LabelConnectedComponent(Tree_temp, Tree2);
6077 
6078  Tree_temp.addEdge(
6079  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6080  Tree_out.edgeSource(*ed_it)),
6081  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6082  Tree_out.edgeTarget(*ed_it)),
6083  tmp);
6084 
6085  for (boost::tie(ed_it2, ed_end2) = boost::edges(G.getBoostGraph());
6086  ed_it2 != ed_end2; ++ed_it2) {
6087  Tree2.vertexData(
6088  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6089  G.edgeSource(*ed_it2)),
6090  &label1);
6091  Tree2.vertexData(
6092  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6093  G.edgeTarget(*ed_it2)),
6094  &label2);
6095 
6096  if (label1 != label2) {
6097  G.edgeWeight(*ed_it2, &tmp);
6098  G.setEdgeWeight(*ed_it2, std::max((double) tmp, value));
6099  // G.setEdgeWeight(*ed_it2,(double) tmp + value);
6100  }
6101  }
6102  }
6103  }
6104 
6105  std::cout << "project on image the pdf" << std::endl;
6106 
6107  typename ImageOut::const_iterator it, iend;
6108  morphee::selement::Neighborhood<SE, ImageOut> neighb(imOut, nl);
6109  typename morphee::selement::Neighborhood<SE, ImageOut>::iterator nit,
6110  nend;
6111  offset_t o0, o1;
6112 
6113  for (it = imOut.begin(), iend = imOut.end(); it != iend;
6114  ++it) // for all pixels in imIn create a vertex
6115  {
6116  o0 = it.getOffset();
6117  imOut.setPixel(o0, 0);
6118  }
6119 
6120  for (it = imOut.begin(), iend = imOut.end(); it != iend;
6121  ++it) // for all pixels in imIn create a vertex
6122  {
6123  o0 = it.getOffset();
6124  int val1 = imIn.pixelFromOffset(o0);
6125  double valout1 = imOut.pixelFromOffset(o0);
6126 
6127  neighb.setCenter(o0);
6128 
6129  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
6130  o1 = nit.getOffset();
6131 
6132  if (o1 > o0) {
6133  int val2 = imIn.pixelFromOffset(o1);
6134  double valout2 = imOut.pixelFromOffset(o1);
6135 
6136  if (val2 != val1) {
6137  RES_C res = G.edgeFromVertices(val1 - 1, val2 - 1, &e1);
6138  if (res == RES_OK) {
6139  G.edgeWeight(e1, &tmp);
6140  if (tmp > 0) {
6141  imOut.setPixel(o0, std::max(valout1, (double) tmp));
6142  imOut.setPixel(o1, std::max(valout2, (double) tmp));
6143  }
6144  } else {
6145  RES_C res = G.edgeFromVertices(val2 - 1, val1 - 1, &e1);
6146  if (res == RES_OK) {
6147  G.edgeWeight(e1, &tmp);
6148  if (tmp > 0) {
6149  imOut.setPixel(o0, std::max(valout1, (double) tmp));
6150  imOut.setPixel(o1, std::max(valout2, (double) tmp));
6151  }
6152  }
6153  }
6154  }
6155  }
6156  }
6157  }
6158 
6159  return RES_OK;
6160  }
6161 
6162  // ##################################################
6163  // END FROM STAWIASKI JAN 2012
6164  // ##################################################
6165 
6166  template <class BoostGraph>
6167  const BoostGraph t_CopyGraph(const BoostGraph &graphIn)
6168  {
6169  MORPHEE_ENTER_FUNCTION("t_CopyGraph");
6170 
6171  typedef typename BoostGraph::EdgeIterator EdgeIterator;
6172  typedef typename BoostGraph::VertexIterator VertexIterator;
6173 
6174  EdgeIterator ed_it, ed_end;
6175  VertexIterator v_it, v_end;
6176 
6177  BoostGraph GCopy(graphIn.numVertices());
6178  typename BoostGraph::EdgeProperty tmp;
6179  typename BoostGraph::VertexProperty vdata1;
6180 
6181  for (boost::tie(ed_it, ed_end) = boost::edges(graphIn.getBoostGraph());
6182  ed_it != ed_end; ++ed_it) {
6183  graphIn.edgeWeight(*ed_it,
6184  &tmp); // shouldn't ever happen, but who knows ?
6185  GCopy.addEdge(
6186  typename BoostGraph::VertexDescriptor(graphIn.edgeSource(*ed_it)),
6187  typename BoostGraph::VertexDescriptor(graphIn.edgeTarget(*ed_it)),
6188  tmp);
6189  }
6190  // copying the properties of each vertex
6191  for (boost::tie(v_it, v_end) = boost::vertices(graphIn.getBoostGraph());
6192  v_it != v_end; ++v_it) {
6193  graphIn.vertexData(*v_it, &vdata1);
6194  GCopy.setVertexData(*v_it, vdata1);
6195  }
6196 
6197  return GCopy;
6198  }
6199 
6200  template <class Graph>
6201  RES_C t_LabelConnectedComponent(const Graph &GIn, Graph &Gout)
6202  {
6203  MORPHEE_ENTER_FUNCTION("t_LabelConnectedComponent");
6204 
6205  typedef typename Graph::VertexDescriptor VertexDescriptor;
6206  typedef typename Graph::_boostGraph BoostGraph;
6207  typedef
6208  typename boost::graph_traits<BoostGraph>::edge_iterator EdgeIterator;
6209  typedef typename boost::graph_traits<BoostGraph>::vertex_iterator
6210  VertexIterator;
6211  typedef typename boost::graph_traits<BoostGraph>::edge_descriptor
6212  edge_descriptor;
6213 
6214  EdgeIterator ed_it, ed_end;
6215  VertexIterator u_iter, u_end;
6216 
6217  Gout = t_CopyGraph(GIn);
6218 
6219  std::vector<int> component(boost::num_vertices(GIn.getBoostGraph()));
6220  int num = connected_components(GIn.getBoostGraph(), &component[0]);
6221 
6222  // SCAN IMAGE TO FIND THE PIXELS LABELS
6223  for (boost::tie(u_iter, u_end) = boost::vertices(GIn.getBoostGraph());
6224  u_iter != u_end; ++u_iter) {
6225  Gout.setVertexData(*u_iter, component[*u_iter] + 1);
6226  }
6227 
6228  return RES_OK;
6229  }
6230 
6231  // BEGIN FROM stawiaski JAN 2012
6232  template <class Graph>
6233  RES_C t_LabelConnectedComponent(const Graph &GIn, Graph &Gout, int *num)
6234  {
6235  MORPHEE_ENTER_FUNCTION("t_LabelConnectedComponent");
6236 
6237  typedef typename Graph::VertexDescriptor VertexDescriptor;
6238  typedef typename Graph::_boostGraph BoostGraph;
6239  typedef
6240  typename boost::graph_traits<BoostGraph>::edge_iterator EdgeIterator;
6241  typedef typename boost::graph_traits<BoostGraph>::vertex_iterator
6242  VertexIterator;
6243  typedef typename boost::graph_traits<BoostGraph>::edge_descriptor
6244  edge_descriptor;
6245 
6246  EdgeIterator ed_it, ed_end;
6247  VertexIterator u_iter, u_end;
6248 
6249  Gout = t_CopyGraph(GIn);
6250 
6251  std::vector<int> component(boost::num_vertices(GIn.getBoostGraph()));
6252  *num = connected_components(GIn.getBoostGraph(), &component[0]);
6253 
6254  // SCAN IMAGE TO FIND THE PIXELS LABELS
6255  for (boost::tie(u_iter, u_end) = boost::vertices(GIn.getBoostGraph());
6256  u_iter != u_end; ++u_iter) {
6257  Gout.setVertexData(*u_iter, component[*u_iter] + 1);
6258  }
6259 
6260  return RES_OK;
6261  }
6262  // END FROM stawiaski JAN 2012
6263 
6264  template <class ImageIn, class ImageGradx, class ImageGrady,
6265  class ImageMarker, class SE, class ImageOut>
6266  RES_C t_geoCuts(const ImageIn &imIn, const ImageGradx &imGradx,
6267  const ImageGrady &imGrady, const ImageMarker &imMarker,
6268  const SE &nl, ImageOut &imOut)
6269  {
6270  MORPHEE_ENTER_FUNCTION("t_GeoCuts");
6271 
6272  std::cout << "Enter function Geo-Cuts" << std::endl;
6273 
6274  if ((!imOut.isAllocated())) {
6275  MORPHEE_REGISTER_ERROR("Not allocated");
6276  return RES_NOT_ALLOCATED;
6277  }
6278 
6279  if ((!imIn.isAllocated())) {
6280  MORPHEE_REGISTER_ERROR("Not allocated");
6281  return RES_NOT_ALLOCATED;
6282  }
6283 
6284  if ((!imGradx.isAllocated())) {
6285  MORPHEE_REGISTER_ERROR("Not allocated");
6286  return RES_NOT_ALLOCATED;
6287  }
6288 
6289  if ((!imGrady.isAllocated())) {
6290  MORPHEE_REGISTER_ERROR("Not allocated");
6291  return RES_NOT_ALLOCATED;
6292  }
6293 
6294  if ((!imMarker.isAllocated())) {
6295  MORPHEE_REGISTER_ERROR("Not allocated");
6296  return RES_NOT_ALLOCATED;
6297  }
6298 
6299  // common image iterator
6300  typename ImageIn::const_iterator it, iend;
6301  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
6302  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
6303  offset_t o0;
6304  offset_t o1;
6305 
6306  // needed for max flow: capacit map, rev_capacity map, etc.
6307  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
6308  boost::directedS>
6309  Traits;
6310  typedef boost::adjacency_list<
6311  boost::listS, boost::vecS, boost::directedS,
6312  boost::property<boost::vertex_name_t, std::string>,
6313  boost::property<
6314  boost::edge_capacity_t, double,
6315  boost::property<boost::edge_residual_capacity_t, double,
6316  boost::property<boost::edge_reverse_t,
6317  Traits::edge_descriptor>>>>
6318  Graph_d;
6319 
6320  Graph_d g;
6321 
6322  double sigma = 1.0;
6323 
6324  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
6325  boost::get(boost::edge_capacity, g);
6326 
6327  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
6328  get(boost::edge_reverse, g);
6329 
6330  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
6331  residual_capacity = get(boost::edge_residual_capacity, g);
6332 
6333  bool in1;
6334  Graph_d::edge_descriptor e1, e2, e3, e4;
6335  Graph_d::vertex_descriptor vSource, vSink;
6336  int numVert = 0;
6337 
6338  std::cout << "build graph vertices" << std::endl;
6339  for (it = imIn.begin(), iend = imIn.end(); it != iend;
6340  ++it) // for all pixels in imIn create a vertex
6341  {
6342  o0 = it.getOffset();
6343  boost::add_vertex(g);
6344  numVert++;
6345  }
6346 
6347  std::cout << "number of vertices: " << numVert << std::endl;
6348 
6349  vSource = boost::add_vertex(g);
6350  vSink = boost::add_vertex(g);
6351 
6352  std::cout << "build graph edges" << std::endl;
6353  for (it = imIn.begin(), iend = imIn.end(); it != iend;
6354  ++it) // for all pixels in imIn create a vertex and an edge
6355  {
6356  o1 = it.getOffset();
6357  double val = imIn.pixelFromOffset(o1);
6358  int marker = imMarker.pixelFromOffset(o1);
6359 
6360  int valright = 0;
6361  int valleft = 0;
6362  int valup = 0;
6363  int valdown = 0;
6364 
6365  if (marker == 2) {
6366  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
6367  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
6368  capacity[e4] = (std::numeric_limits<double>::max)();
6369  capacity[e3] = (std::numeric_limits<double>::max)();
6370  rev[e4] = e3;
6371  rev[e3] = e4;
6372  } else if (marker == 3) {
6373  boost::tie(e3, in1) = boost::add_edge(o1, vSink, g);
6374  boost::tie(e4, in1) = boost::add_edge(vSink, o1, g);
6375  capacity[e3] = (std::numeric_limits<double>::max)();
6376  capacity[e4] = (std::numeric_limits<double>::max)();
6377  rev[e3] = e4;
6378  rev[e4] = e3;
6379  }
6380 
6381  neighb.setCenter(o1);
6382 
6383  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
6384  const offset_t o2 = nit.getOffset();
6385  if (o2 <= o1)
6386  continue;
6387  if (o2 > o1) {
6388  double val2 = imIn.pixelFromOffset(o2);
6389  double cost = 1000 / (1 + 1.5 * (val - val2) * (val - val2));
6390  // double cost = std::exp(-((val-val2)*(val-val2))/(1.0));
6391  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
6392  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
6393  capacity[e4] = cost;
6394  capacity[e3] = cost;
6395  rev[e4] = e3;
6396  rev[e3] = e4;
6397  }
6398  }
6399 
6400  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
6401  const offset_t o2 = nit.getOffset();
6402  if (o2 == o1)
6403  continue;
6404  else if (o2 == o1 - 1)
6405  valleft = (int) (imGradx.pixelFromOffset(o2));
6406  else if (o2 == o1 + 1)
6407  valright = (int) (imGradx.pixelFromOffset(o2));
6408  else if (o2 > o1 + 1)
6409  valdown = (int) (imGrady.pixelFromOffset(o2));
6410  else if (o2 < o1 - 1)
6411  valup = (int) (imGrady.pixelFromOffset(o2));
6412  }
6413 
6414  // std::cout<<" "<<valleft<<" "<<valright<<" "<<valdown<<"
6415  // "<<valup<<std::endl;
6416  double divergence = 10 * ((valleft - valright) + (valup - valdown));
6417 
6418  if (divergence < 0 && marker == 0) {
6419  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
6420  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
6421  capacity[e4] = std::abs(divergence);
6422  capacity[e3] = std::abs(divergence);
6423  rev[e4] = e3;
6424  rev[e3] = e4;
6425  } else if (divergence > 0 && marker == 0) {
6426  boost::tie(e4, in1) = boost::add_edge(o1, vSink, g);
6427  boost::tie(e3, in1) = boost::add_edge(vSink, o1, g);
6428  capacity[e4] = divergence;
6429  capacity[e3] = divergence;
6430  rev[e4] = e3;
6431  rev[e3] = e4;
6432  }
6433  }
6434 
6435  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
6436  boost::get(boost::vertex_index, g);
6437  std::vector<boost::default_color_type> color(boost::num_vertices(g));
6438 
6439  std::cout << "Compute Max flow" << std::endl;
6440 #if BOOST_VERSION >= 104700
6441  double flow =
6442  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
6443  &color[0], indexmap, vSource, vSink);
6444 #else
6445  double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
6446  &color[0], indexmap, vSource, vSink);
6447 #endif
6448 
6449  std::cout << "c The total flow:" << std::endl;
6450  std::cout << "s " << flow << std::endl << std::endl;
6451 
6452  for (it = imIn.begin(), iend = imIn.end(); it != iend;
6453  ++it) // for all pixels in imIn create a vertex and an edge
6454  {
6455  o1 = it.getOffset();
6456  if (color[o1] == color[vSource])
6457  imOut.setPixel(o1, 2);
6458  if (color[o1] == 1)
6459  imOut.setPixel(o1, 4);
6460  if (color[o1] == color[vSink])
6461  imOut.setPixel(o1, 3);
6462  }
6463 
6464  return RES_OK;
6465  }
6466 
6467  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
6468  RES_C t_geoCutsMinSurfaces(const ImageIn &imIn,
6469  const ImageMarker &imMarker, const SE &nl,
6470  ImageOut &imOut)
6471  {
6472  MORPHEE_ENTER_FUNCTION("t_geoCutsMinSurfaces");
6473 
6474  std::cout << "Enter function Geo-Cuts " << std::endl;
6475 
6476  if ((!imOut.isAllocated())) {
6477  MORPHEE_REGISTER_ERROR("Not allocated");
6478  return RES_NOT_ALLOCATED;
6479  }
6480 
6481  if ((!imIn.isAllocated())) {
6482  MORPHEE_REGISTER_ERROR("Not allocated");
6483  return RES_NOT_ALLOCATED;
6484  }
6485 
6486  if ((!imMarker.isAllocated())) {
6487  MORPHEE_REGISTER_ERROR("Not allocated");
6488  return RES_NOT_ALLOCATED;
6489  }
6490 
6491  // common image iterator
6492  typename ImageIn::const_iterator it, iend;
6493  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
6494  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
6495  offset_t o0;
6496  offset_t o1;
6497 
6498  // needed for max flow: capacit map, rev_capacity map, etc.
6499  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
6500  boost::directedS>
6501  Traits;
6502  typedef boost::adjacency_list<
6503  boost::listS, boost::vecS, boost::directedS,
6504  boost::property<boost::vertex_name_t, std::string>,
6505  boost::property<
6506  boost::edge_capacity_t, double,
6507  boost::property<boost::edge_residual_capacity_t, double,
6508  boost::property<boost::edge_reverse_t,
6509  Traits::edge_descriptor>>>>
6510  Graph_d;
6511 
6512  Graph_d g;
6513 
6514  double sigma = 1.0;
6515 
6516  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
6517  boost::get(boost::edge_capacity, g);
6518 
6519  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
6520  get(boost::edge_reverse, g);
6521 
6522  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
6523  residual_capacity = get(boost::edge_residual_capacity, g);
6524 
6525  bool in1;
6526  Graph_d::edge_descriptor e1, e2, e3, e4;
6527  Graph_d::vertex_descriptor vSource, vSink;
6528  int numVert = 0;
6529  int numEdges = 0;
6530 
6531  std::cout << "build graph vertices" << std::endl;
6532  for (it = imIn.begin(), iend = imIn.end(); it != iend;
6533  ++it) // for all pixels in imIn create a vertex
6534  {
6535  o0 = it.getOffset();
6536  boost::add_vertex(g);
6537  numVert++;
6538  }
6539 
6540  std::cout << "number of vertices: " << numVert << std::endl;
6541 
6542  vSource = boost::add_vertex(g);
6543  vSink = boost::add_vertex(g);
6544 
6545  std::cout << "build graph edges" << std::endl;
6546  for (it = imIn.begin(), iend = imIn.end(); it != iend;
6547  ++it) // for all pixels in imIn create a vertex and an edge
6548  {
6549  o1 = it.getOffset();
6550  double val = imIn.pixelFromOffset(o1);
6551  int marker = imMarker.pixelFromOffset(o1);
6552 
6553  int valright = 0;
6554  int valleft = 0;
6555  int valup = 0;
6556  int valdown = 0;
6557 
6558  if (marker == 2) {
6559  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
6560  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
6561  capacity[e4] = (std::numeric_limits<double>::max)();
6562  capacity[e3] = (std::numeric_limits<double>::max)();
6563  rev[e4] = e3;
6564  rev[e3] = e4;
6565  } else if (marker == 3) {
6566  boost::tie(e4, in1) = boost::add_edge(o1, vSink, g);
6567  boost::tie(e3, in1) = boost::add_edge(vSink, o1, g);
6568  capacity[e4] = (std::numeric_limits<double>::max)();
6569  capacity[e3] = (std::numeric_limits<double>::max)();
6570  rev[e4] = e3;
6571  rev[e3] = e4;
6572  }
6573 
6574  neighb.setCenter(o1);
6575 
6576  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
6577  const offset_t o2 = nit.getOffset();
6578  if (o2 <= o1)
6579  continue;
6580  if (o2 > o1) {
6581  numEdges++;
6582  double val2 = imIn.pixelFromOffset(o2);
6583  double maxi = std::abs(val2 - val);
6584  double cost = 256 / (1 + std::pow(maxi, 2));
6585  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
6586  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
6587  capacity[e4] = cost;
6588  capacity[e3] = cost;
6589  rev[e4] = e3;
6590  rev[e3] = e4;
6591  }
6592  }
6593  }
6594 
6595  std::cout << "number of Edges : " << numEdges << std::endl;
6596 
6597  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
6598  boost::get(boost::vertex_index, g);
6599  std::vector<boost::default_color_type> color(boost::num_vertices(g));
6600 
6601  std::cout << "Compute Max flow " << std::endl;
6602  /*double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
6603  &color[0], indexmap, vSource, vSink); std::cout << "c The total flow:" <<
6604  std::endl; std::cout << "s " << flow << std::endl << std::endl;*/
6605 #if BOOST_VERSION >= 104700
6606  double flow2 =
6607  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
6608  &color[0], indexmap, vSource, vSink);
6609 #else
6610  double flow2 = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
6611  &color[0], indexmap, vSource, vSink);
6612 #endif
6613  std::cout << "c The total flow found :" << std::endl;
6614  std::cout << "s " << flow2 << std::endl << std::endl;
6615 
6616  for (it = imIn.begin(), iend = imIn.end(); it != iend;
6617  ++it) // for all pixels in imIn create a vertex and an edge
6618  {
6619  o1 = it.getOffset();
6620  if (color[o1] == color[vSource])
6621  imOut.setPixel(o1, 2);
6622  else if (color[o1] == color[vSink])
6623  imOut.setPixel(o1, 3);
6624  else if (color[o1] == 1)
6625  imOut.setPixel(o1, 4);
6626  }
6627 
6628  return RES_OK;
6629  }
6630 
6631  template <class ImageIn, class ImageVal, typename _nbmarkers, class SE,
6632  class ImageOut>
6633  RES_C t_geoCutsStochastic_Watershed(const ImageIn &imIn,
6634  const ImageVal &imVal,
6635  const _nbmarkers nbmarkers,
6636  const SE &nl, ImageOut &imOut)
6637  {
6638  MORPHEE_ENTER_FUNCTION("t_geoCutsStochastic_Watershed");
6639 
6640  std::cout << "Enter function Geo-Cuts Stochastic Watershed" << std::endl;
6641 
6642  if ((!imOut.isAllocated())) {
6643  MORPHEE_REGISTER_ERROR("Not allocated");
6644  return RES_NOT_ALLOCATED;
6645  }
6646 
6647  if ((!imIn.isAllocated())) {
6648  MORPHEE_REGISTER_ERROR("Not allocated");
6649  return RES_NOT_ALLOCATED;
6650  }
6651 
6652  if ((!imVal.isAllocated())) {
6653  MORPHEE_REGISTER_ERROR("Not allocated");
6654  return RES_NOT_ALLOCATED;
6655  }
6656 
6657  double markers = (double) nbmarkers;
6658 
6659  int size = imIn.getXSize() * imIn.getYSize() * imIn.getZSize();
6660  // std::cout<<size<<std::endl;
6661 
6662  typedef typename morphee::graph::CommonGraph32::_boostGraph BoostGraph;
6663  typedef
6664  typename boost::graph_traits<BoostGraph>::edge_iterator EdgeIterator;
6665  typedef typename boost::graph_traits<BoostGraph>::vertex_iterator
6666  VertexIterator;
6667  typedef typename boost::graph_traits<BoostGraph>::edge_descriptor
6668  EdgeDescriptor;
6669  typedef typename boost::graph_traits<BoostGraph>::vertex_descriptor
6670  VertexDescriptor;
6671  typename morphee::graph::CommonGraph32::EdgeProperty tmp;
6672  typename morphee::graph::CommonGraph32::VertexProperty vdata1;
6673  typename morphee::graph::CommonGraph32::VertexProperty label1, label2;
6674  EdgeIterator ed_it, ed_end, ed_it2, ed_end2;
6675  VertexIterator v_it, v_end;
6676  EdgeDescriptor last_edge, e1, e2;
6677 
6678  bool in1;
6679 
6680  std::vector<double> val_edges;
6681  val_edges.push_back(0.0);
6682  double last_edge_value = 0.0;
6683 
6684  std::vector<EdgeDescriptor> removed_edges;
6685 
6686  morphee::graph::CommonGraph32 G(0);
6687  morphee::graph::CommonGraph32 Tree(0);
6688 
6689  morphee::morphoBase::t_NeighborhoodGraphFromMosaic_WithPass(imIn, imVal,
6690  nl, G);
6691  Tree = morphee::graph::MinimumSpanningTreeFromGraph(G);
6692 
6693  ImageIn ImTempSurfaces = imIn.getSame();
6694  // Image<UINT8>ImTempSurfaces = imIn.t_getSame<UINT8>();
6695  // morphee::morphoBase::t_ImLabelFlatZonesWithArea(imIn,nl,ImTempSurfaces);
6696  morphee::morphoBase::t_ImLabelFlatZonesWithVolume(imIn, imVal, nl,
6697  ImTempSurfaces);
6698 
6699  // ImageIn ImTempVolumes = imIn.getSame();
6700  // ImageIn imMinima = imIn.getSame();
6701  // morphee::morphoBase::t_ImMinima(imVal,nl,1,imMinima);
6702  // Image<UINT32>imLabel = imIn.t_getSame<UINT32>();
6703  // Image<UINT32>imOut2 = imIn.t_getSame<UINT32>();
6704  // morphee::morphoBase::t_ImLabel(imMinima,nl,imLabel);
6705  // morphee::morphoBase::t_ImHierarchicalSegmentation(imVal,imLabel,nl,morphee::morphoBase::VolumicHierarchicalSegmentation,imOut2,Tree);
6706  //
6707 
6708  morphee::graph::CommonGraph32 Tree_temp = t_CopyGraph(Tree);
6709  morphee::graph::CommonGraph32 Tree_out = t_CopyGraph(Tree);
6710  morphee::graph::CommonGraph32 Tree2 = t_CopyGraph(Tree_temp);
6711 
6712  morphee::graph::t_ProjectMarkersOnGraph(ImTempSurfaces, imIn, Tree);
6713 
6714  double volume = 0.0;
6715  for (boost::tie(v_it, v_end) = boost::vertices(G.getBoostGraph());
6716  v_it != v_end; ++v_it) {
6717  Tree.vertexData(*v_it, &vdata1);
6718  volume = volume + (double) vdata1;
6719  }
6720 
6721  for (boost::tie(ed_it, ed_end) = boost::edges(G.getBoostGraph());
6722  ed_it != ed_end; ++ed_it) {
6723  G.setEdgeWeight(*ed_it, 0);
6724  }
6725 
6726  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
6727  ed_it != ed_end; ++ed_it) {
6728  Tree.edgeWeight(*ed_it, &tmp);
6729  if ((double) tmp > last_edge_value) {
6730  val_edges.push_back(tmp);
6731  last_edge_value = (double) tmp;
6732  }
6733  }
6734 
6735  while (val_edges.size() > 1) {
6736  last_edge_value = val_edges.back();
6737  val_edges.pop_back();
6738 
6739  // remove edge of maximal weight
6740  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
6741  ed_it != ed_end; ++ed_it) {
6742  // std::cout<<"look"<<std::endl;
6743  Tree.edgeWeight(*ed_it, &tmp);
6744 
6745  if (tmp == last_edge_value) {
6746  boost::tie(e1, in1) =
6747  boost::edge(Tree.edgeSource(*ed_it), Tree.edgeTarget(*ed_it),
6748  Tree_temp.getBoostGraph());
6749  removed_edges.push_back(e1);
6750  Tree_temp.removeEdge(
6751  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6752  Tree.edgeSource(*ed_it)),
6753  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6754  Tree.edgeTarget(*ed_it)));
6755  }
6756  }
6757 
6758  t_LabelConnectedComponent(Tree_temp, Tree2);
6759 
6760  while (removed_edges.size() > 0) {
6761  e1 = removed_edges.back();
6762  removed_edges.pop_back();
6763 
6764  Tree2.vertexData(
6765  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6766  Tree.edgeSource(e1)),
6767  &label1);
6768  Tree2.vertexData(
6769  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6770  Tree.edgeTarget(e1)),
6771  &label2);
6772 
6773  double S1 = 0;
6774  double S2 = 0;
6775 
6776  for (boost::tie(v_it, v_end) = boost::vertices(Tree2.getBoostGraph());
6777  v_it != v_end; ++v_it) {
6778  Tree2.vertexData(*v_it, &vdata1);
6779  if (vdata1 == label1) {
6780  Tree.vertexData(*v_it, &vdata1);
6781  S1 = S1 + (double) vdata1;
6782  } else if (vdata1 == label2) {
6783  Tree.vertexData(*v_it, &vdata1);
6784  S2 = S2 + (double) vdata1;
6785  }
6786  }
6787 
6788  // double k = markers*((S1+S2)/(double) volume);
6789  // double probability = 1 - std::pow( ( S1/(S1+S2) ) , k ) - std::pow(
6790  // ( S2/(S1+S2) ) , k ) ;
6791  double probability =
6792  1 - std::pow(1 - S1 / ((double) volume), markers) -
6793  std::pow(1 - S2 / ((double) volume), markers) +
6794  std::pow(1 - (S1 + S2) / ((double) volume), markers);
6795 
6796  // std::cout<<"probability :" <<probability<<std::endl;
6797 
6798  if (probability > 0.0) {
6799  RES_C res = Tree_out.edgeFromVertices(
6800  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6801  Tree.edgeSource(e1)),
6802  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6803  Tree.edgeTarget(e1)),
6804  &e2);
6805  Tree_out.setEdgeWeight(e2, 255.0 * probability);
6806  } else {
6807  RES_C res = Tree_out.edgeFromVertices(
6808  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6809  Tree.edgeSource(e1)),
6810  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6811  Tree.edgeTarget(e1)),
6812  &e2);
6813  Tree_out.setEdgeWeight(e2, 0.0);
6814  }
6815  }
6816  }
6817 
6818  std::cout << "project on graphs" << std::endl;
6819  Tree2 = t_CopyGraph(Tree_out);
6820  Tree_temp = t_CopyGraph(Tree_out);
6821 
6822  for (boost::tie(ed_it, ed_end) = boost::edges(Tree_out.getBoostGraph());
6823  ed_it != ed_end; ++ed_it) {
6824  Tree_out.edgeWeight(*ed_it, &tmp);
6825  double value = (double) tmp;
6826 
6827  if (value > 0.0) {
6828  Tree_temp.removeEdge(
6829  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6830  Tree_out.edgeSource(*ed_it)),
6831  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6832  Tree_out.edgeTarget(*ed_it)));
6833 
6834  t_LabelConnectedComponent(Tree_temp, Tree2);
6835 
6836  Tree_temp.addEdge(
6837  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6838  Tree_out.edgeSource(*ed_it)),
6839  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6840  Tree_out.edgeTarget(*ed_it)),
6841  tmp);
6842 
6843  for (boost::tie(ed_it2, ed_end2) = boost::edges(G.getBoostGraph());
6844  ed_it2 != ed_end2; ++ed_it2) {
6845  Tree2.vertexData(
6846  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6847  G.edgeSource(*ed_it2)),
6848  &label1);
6849  Tree2.vertexData(
6850  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
6851  G.edgeTarget(*ed_it2)),
6852  &label2);
6853 
6854  if (label1 != label2) {
6855  G.edgeWeight(*ed_it2, &tmp);
6856  G.setEdgeWeight(*ed_it2, std::max((double) tmp, value));
6857  // G.setEdgeWeight(*ed_it2,(double) tmp + value);
6858  }
6859  }
6860  }
6861  }
6862 
6863  std::cout << "project on image the pdf" << std::endl;
6864 
6865  typename ImageOut::const_iterator it, iend;
6866  morphee::selement::Neighborhood<SE, ImageOut> neighb(imOut, nl);
6867  typename morphee::selement::Neighborhood<SE, ImageOut>::iterator nit,
6868  nend;
6869  offset_t o0, o1;
6870 
6871  for (it = imOut.begin(), iend = imOut.end(); it != iend;
6872  ++it) // for all pixels in imIn create a vertex
6873  {
6874  o0 = it.getOffset();
6875  imOut.setPixel(o0, 0);
6876  }
6877 
6878  for (it = imOut.begin(), iend = imOut.end(); it != iend;
6879  ++it) // for all pixels in imIn create a vertex
6880  {
6881  o0 = it.getOffset();
6882  int val1 = imIn.pixelFromOffset(o0);
6883  double valout1 = imOut.pixelFromOffset(o0);
6884 
6885  neighb.setCenter(o0);
6886 
6887  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
6888  o1 = nit.getOffset();
6889 
6890  if (o1 > o0) {
6891  int val2 = imIn.pixelFromOffset(o1);
6892  double valout2 = imOut.pixelFromOffset(o1);
6893 
6894  if (val2 != val1) {
6895  RES_C res = G.edgeFromVertices(val1 - 1, val2 - 1, &e1);
6896  if (res == RES_OK) {
6897  G.edgeWeight(e1, &tmp);
6898  if (tmp > 0) {
6899  imOut.setPixel(o0, std::max(valout1, (double) tmp));
6900  imOut.setPixel(o1, std::max(valout2, (double) tmp));
6901  }
6902  } else {
6903  RES_C res = G.edgeFromVertices(val2 - 1, val1 - 1, &e1);
6904  if (res == RES_OK) {
6905  G.edgeWeight(e1, &tmp);
6906  if (tmp > 0) {
6907  imOut.setPixel(o0, std::max(valout1, (double) tmp));
6908  imOut.setPixel(o1, std::max(valout2, (double) tmp));
6909  }
6910  }
6911  }
6912  }
6913  }
6914  }
6915  }
6916 
6917  return RES_OK;
6918  }
6919 
6920  template <class ImageIn, class ImageVal, class ImageMark,
6921  typename _nbmarkers, class SE, class ImageOut>
6922  RES_C t_geoCutsStochastic_Watershed_2(const ImageIn &imIn,
6923  const ImageVal &imVal,
6924  const ImageMark &imMark,
6925  const _nbmarkers nbmarkers,
6926  const SE &nl, ImageOut &imOut)
6927  {
6928  MORPHEE_ENTER_FUNCTION("t_geoCutsStochastic_Watershed_2");
6929 
6930  std::cout << "Enter function Geo-Cuts Stochastic Watershed_2"
6931  << std::endl;
6932 
6933  if ((!imOut.isAllocated())) {
6934  MORPHEE_REGISTER_ERROR("Not allocated");
6935  return RES_NOT_ALLOCATED;
6936  }
6937 
6938  if ((!imIn.isAllocated())) {
6939  MORPHEE_REGISTER_ERROR("Not allocated");
6940  return RES_NOT_ALLOCATED;
6941  }
6942 
6943  if ((!imVal.isAllocated())) {
6944  MORPHEE_REGISTER_ERROR("Not allocated");
6945  return RES_NOT_ALLOCATED;
6946  }
6947 
6948  if ((!imMark.isAllocated())) {
6949  MORPHEE_REGISTER_ERROR("Not allocated");
6950  return RES_NOT_ALLOCATED;
6951  }
6952 
6953  double markers = (double) nbmarkers;
6954 
6955  int size = imIn.getXSize() * imIn.getYSize() * imIn.getZSize();
6956  // std::cout<<size<<std::endl;
6957 
6958  typedef typename morphee::graph::CommonGraph32::_boostGraph BoostGraph;
6959  typedef
6960  typename boost::graph_traits<BoostGraph>::edge_iterator EdgeIterator;
6961  typedef typename boost::graph_traits<BoostGraph>::vertex_iterator
6962  VertexIterator;
6963  typedef typename boost::graph_traits<BoostGraph>::edge_descriptor
6964  EdgeDescriptor;
6965  typedef typename boost::graph_traits<BoostGraph>::vertex_descriptor
6966  VertexDescriptor;
6967  typename morphee::graph::CommonGraph32::EdgeProperty tmp;
6968  typename morphee::graph::CommonGraph32::VertexProperty vdata1, vdata2;
6969  typename morphee::graph::CommonGraph32::VertexProperty label1, label2;
6970  EdgeIterator ed_it, ed_end, ed_it2, ed_end2;
6971  VertexIterator v_it, v_end;
6972  EdgeDescriptor last_edge, e1, e2;
6973  bool in1;
6974 
6975  std::vector<double> val_edges;
6976  val_edges.push_back(0.0);
6977  double last_edge_value = 0.0;
6978 
6979  std::vector<EdgeDescriptor> removed_edges;
6980 
6981  morphee::graph::CommonGraph32 G(0);
6982  morphee::graph::CommonGraph32 Tree(0);
6983  morphee::morphoBase::t_NeighborhoodGraphFromMosaic_WithPass(imIn, imVal,
6984  nl, G);
6985  // morphee::morphoBase::t_NeighborhoodGraphFromMosaic_WithAverageAndDifference(imIn,imVal,nl,G);
6986  Tree = morphee::graph::MinimumSpanningTreeFromGraph(G);
6987 
6988  ImageIn ImTempSurfaces = imIn.getSame();
6989  // Image<UINT8>ImTempSurfaces = imIn.t_getSame<UINT8>();
6990  morphee::morphoBase::t_ImLabelFlatZonesWithArea(imIn, nl, ImTempSurfaces);
6991  // morphee::morphoBase::t_ImLabelFlatZonesWithVolume(imIn,imVal,nl,ImTempSurfaces);
6992 
6993  // ImageIn imMinima = imIn.getSame();
6994  // morphee::morphoBase::t_ImMinima(imVal,nl,1,imMinima);
6995  // Image<UINT32>imLabel = imIn.t_getSame<UINT32>();
6996  // morphee::morphoBase::t_ImLabel(imMinima,nl,imLabel);
6997  // morphee::morphoBase::t_ImLabelMarkersWithExtinctionValues_Area(imLabel,imVal,nl,ImTempSurfaces);
6998 
6999  morphee::graph::CommonGraph32 Tree_temp = t_CopyGraph(Tree);
7000  morphee::graph::CommonGraph32 Tree_out = t_CopyGraph(Tree);
7001  morphee::graph::CommonGraph32 Tree2 = t_CopyGraph(Tree_temp);
7002  morphee::graph::CommonGraph32 TreeMark = t_CopyGraph(Tree);
7003 
7004  morphee::graph::t_ProjectMarkersOnGraph(ImTempSurfaces, imIn, Tree);
7005 
7006  morphee::graph::t_ProjectMarkersOnGraph(imMark, imIn, TreeMark);
7007 
7008  double volume = 0.0;
7009  for (boost::tie(v_it, v_end) = boost::vertices(G.getBoostGraph());
7010  v_it != v_end; ++v_it) {
7011  Tree.vertexData(*v_it, &vdata1);
7012  volume = volume + (double) vdata1;
7013  }
7014 
7015  for (boost::tie(ed_it, ed_end) = boost::edges(G.getBoostGraph());
7016  ed_it != ed_end; ++ed_it) {
7017  G.setEdgeWeight(*ed_it, 0);
7018  }
7019 
7020  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
7021  ed_it != ed_end; ++ed_it) {
7022  Tree.edgeWeight(*ed_it, &tmp);
7023  if ((double) tmp > last_edge_value) {
7024  val_edges.push_back(tmp);
7025  last_edge_value = (double) tmp;
7026  }
7027  }
7028 
7029  while (val_edges.size() > 1) {
7030  last_edge_value = val_edges.back();
7031  val_edges.pop_back();
7032 
7033  // remove edge of maximal weight
7034  for (boost::tie(ed_it, ed_end) = boost::edges(Tree.getBoostGraph());
7035  ed_it != ed_end; ++ed_it) {
7036  // std::cout<<"look"<<std::endl;
7037  Tree.edgeWeight(*ed_it, &tmp);
7038 
7039  if (tmp == last_edge_value) {
7040  boost::tie(e1, in1) =
7041  boost::edge(Tree.edgeSource(*ed_it), Tree.edgeTarget(*ed_it),
7042  Tree_temp.getBoostGraph());
7043  removed_edges.push_back(e1);
7044  Tree_temp.removeEdge(
7045  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7046  Tree.edgeSource(*ed_it)),
7047  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7048  Tree.edgeTarget(*ed_it)));
7049  }
7050  }
7051 
7052  t_LabelConnectedComponent(Tree_temp, Tree2);
7053 
7054  while (removed_edges.size() > 0) {
7055  e1 = removed_edges.back();
7056  removed_edges.pop_back();
7057 
7058  Tree2.vertexData(
7059  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7060  Tree.edgeSource(e1)),
7061  &label1);
7062  Tree2.vertexData(
7063  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7064  Tree.edgeTarget(e1)),
7065  &label2);
7066 
7067  double S1 = 0;
7068  double S2 = 0;
7069 
7070  bool region1 = false;
7071  bool region2 = false;
7072 
7073  for (boost::tie(v_it, v_end) = boost::vertices(Tree2.getBoostGraph());
7074  v_it != v_end; ++v_it) {
7075  Tree2.vertexData(*v_it, &vdata1);
7076  TreeMark.vertexData(*v_it, &vdata2);
7077 
7078  if (vdata1 == label1) {
7079  Tree.vertexData(*v_it, &vdata1);
7080  S1 = S1 + (double) vdata1;
7081  } else if (vdata1 == label2) {
7082  Tree.vertexData(*v_it, &vdata1);
7083  S2 = S2 + (double) vdata1;
7084  }
7085 
7086  if (vdata1 == label1 && vdata2 > 0) {
7087  region1 = true;
7088  } else if (vdata1 == label2 && vdata2 > 0) {
7089  region2 = true;
7090  }
7091  }
7092 
7093  // double k = markers*((S1+S2)/(double) volume);
7094  // double probability = 1 - std::pow( ( S1/(S1+S2) ) , k ) - std::pow(
7095  // ( S2/(S1+S2) ) , k ) ;
7096  double probability = 0;
7097 
7098  if (region1 == false && region2 == false) {
7099  probability = 1 - std::pow(1 - S1 / ((double) volume), markers) -
7100  std::pow(1 - S2 / ((double) volume), markers) +
7101  std::pow(1 - (S1 + S2) / ((double) volume), markers);
7102  } else if (region1 == true && region2 == false) {
7103  probability = 1 - std::pow(1 - S2 / ((double) volume), markers);
7104  } else if (region1 == false && region2 == true) {
7105  probability = 1 - std::pow(1 - S1 / ((double) volume), markers);
7106  } else if (region1 == true && region2 == true) {
7107  probability = 0;
7108  }
7109 
7110  // std::cout<<"probability :" <<probability<<std::endl;
7111 
7112  if (probability > 0.0) {
7113  RES_C res = Tree_out.edgeFromVertices(
7114  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7115  Tree.edgeSource(e1)),
7116  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7117  Tree.edgeTarget(e1)),
7118  &e2);
7119  Tree_out.setEdgeWeight(e2, 255.0 * probability);
7120  } else {
7121  RES_C res = Tree_out.edgeFromVertices(
7122  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7123  Tree.edgeSource(e1)),
7124  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7125  Tree.edgeTarget(e1)),
7126  &e2);
7127  Tree_out.setEdgeWeight(e2, 0.0);
7128  }
7129  }
7130  }
7131 
7132  std::cout << "project on graphs" << std::endl;
7133  Tree2 = t_CopyGraph(Tree_out);
7134  Tree_temp = t_CopyGraph(Tree_out);
7135 
7136  for (boost::tie(ed_it, ed_end) = boost::edges(Tree_out.getBoostGraph());
7137  ed_it != ed_end; ++ed_it) {
7138  Tree_out.edgeWeight(*ed_it, &tmp);
7139  double value = (double) tmp;
7140 
7141  if (value > 0.0) {
7142  Tree_temp.removeEdge(
7143  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7144  Tree_out.edgeSource(*ed_it)),
7145  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7146  Tree_out.edgeTarget(*ed_it)));
7147 
7148  t_LabelConnectedComponent(Tree_temp, Tree2);
7149 
7150  Tree_temp.addEdge(
7151  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7152  Tree_out.edgeSource(*ed_it)),
7153  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7154  Tree_out.edgeTarget(*ed_it)),
7155  tmp);
7156 
7157  for (boost::tie(ed_it2, ed_end2) = boost::edges(G.getBoostGraph());
7158  ed_it2 != ed_end2; ++ed_it2) {
7159  Tree2.vertexData(
7160  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7161  G.edgeSource(*ed_it2)),
7162  &label1);
7163  Tree2.vertexData(
7164  typename boost::graph_traits<BoostGraph>::vertex_descriptor(
7165  G.edgeTarget(*ed_it2)),
7166  &label2);
7167 
7168  if (label1 != label2) {
7169  G.edgeWeight(*ed_it2, &tmp);
7170  G.setEdgeWeight(*ed_it2, std::max((double) tmp, value));
7171  // G.setEdgeWeight(*ed_it2,(double) tmp + value);
7172  }
7173  }
7174  }
7175  }
7176 
7177  std::cout << "project on image the pdf" << std::endl;
7178 
7179  typename ImageOut::const_iterator it, iend;
7180  morphee::selement::Neighborhood<SE, ImageOut> neighb(imOut, nl);
7181  typename morphee::selement::Neighborhood<SE, ImageOut>::iterator nit,
7182  nend;
7183  offset_t o0, o1;
7184 
7185  for (it = imOut.begin(), iend = imOut.end(); it != iend;
7186  ++it) // for all pixels in imIn create a vertex
7187  {
7188  o0 = it.getOffset();
7189  imOut.setPixel(o0, 0);
7190  }
7191 
7192  for (it = imOut.begin(), iend = imOut.end(); it != iend;
7193  ++it) // for all pixels in imIn create a vertex
7194  {
7195  o0 = it.getOffset();
7196  int val1 = imIn.pixelFromOffset(o0);
7197  double valout1 = imOut.pixelFromOffset(o0);
7198 
7199  neighb.setCenter(o0);
7200 
7201  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
7202  o1 = nit.getOffset();
7203 
7204  if (o1 > o0) {
7205  int val2 = imIn.pixelFromOffset(o1);
7206  double valout2 = imOut.pixelFromOffset(o1);
7207 
7208  if (val2 != val1) {
7209  RES_C res = G.edgeFromVertices(val1 - 1, val2 - 1, &e1);
7210  if (res == RES_OK) {
7211  G.edgeWeight(e1, &tmp);
7212  if (tmp > 0) {
7213  imOut.setPixel(o0, std::max(valout1, (double) tmp));
7214  imOut.setPixel(o1, std::max(valout2, (double) tmp));
7215  }
7216  } else {
7217  RES_C res = G.edgeFromVertices(val2 - 1, val1 - 1, &e1);
7218  if (res == RES_OK) {
7219  G.edgeWeight(e1, &tmp);
7220  if (tmp > 0) {
7221  imOut.setPixel(o0, std::max(valout1, (double) tmp));
7222  imOut.setPixel(o1, std::max(valout2, (double) tmp));
7223  }
7224  }
7225  }
7226  }
7227  }
7228  }
7229  }
7230 
7231  return RES_OK;
7232  }
7233 
7234  template <class ImageIn, class ImageMarker, typename _Power, class SE,
7235  class ImageOut>
7236  RES_C t_geoCutsWatershed_MinCut(const ImageIn &imIn,
7237  const ImageMarker &imMarker,
7238  const _Power Power, const SE &nl,
7239  ImageOut &imOut)
7240  {
7241  MORPHEE_ENTER_FUNCTION("t_geoCutsWatershed_MinCut");
7242 
7243  std::cout << "Enter function Geo-Cuts Watershed" << std::endl;
7244 
7245  if ((!imOut.isAllocated())) {
7246  MORPHEE_REGISTER_ERROR("Not allocated");
7247  return RES_NOT_ALLOCATED;
7248  }
7249 
7250  if ((!imIn.isAllocated())) {
7251  MORPHEE_REGISTER_ERROR("Not allocated");
7252  return RES_NOT_ALLOCATED;
7253  }
7254 
7255  if ((!imMarker.isAllocated())) {
7256  MORPHEE_REGISTER_ERROR("Not allocated");
7257  return RES_NOT_ALLOCATED;
7258  }
7259 
7260  double exposant = (double) Power;
7261  std::cout << "exposant = " << exposant << std::endl;
7262  // std::cout<<"test 2^x = "<<std::pow(2.0,exposant)<<std::endl;
7263 
7264  // common image iterator
7265  typename ImageIn::const_iterator it, iend;
7266  typename ImageOut::const_iterator ito, ioend;
7267  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
7268  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
7269  offset_t o0;
7270  offset_t o1;
7271 
7272  // needed for max flow: capacit map, rev_capacity map, etc.
7273  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
7274  boost::directedS>
7275  Traits;
7276  typedef boost::adjacency_list<
7277  boost::listS, boost::vecS, boost::directedS,
7278  boost::property<boost::vertex_name_t, std::string>,
7279  boost::property<
7280  boost::edge_capacity_t, double,
7281  boost::property<boost::edge_residual_capacity_t, double,
7282  boost::property<boost::edge_reverse_t,
7283  Traits::edge_descriptor>>>>
7284  Graph_d;
7285 
7286  Graph_d g;
7287 
7288  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
7289  boost::get(boost::edge_capacity, g);
7290 
7291  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
7292  get(boost::edge_reverse, g);
7293 
7294  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
7295  residual_capacity = get(boost::edge_residual_capacity, g);
7296 
7297  bool in1;
7298  Graph_d::edge_descriptor e1, e2, e3, e4;
7299  Graph_d::vertex_descriptor vSource, vSink;
7300  int numVert = 0;
7301 
7302  std::cout << "build graph vertices" << std::endl;
7303  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7304  ++it) // for all pixels in imIn create a vertex
7305  {
7306  o0 = it.getOffset();
7307  boost::add_vertex(g);
7308  numVert++;
7309  }
7310 
7311  std::cout << "number of vertices: " << numVert << std::endl;
7312 
7313  vSource = boost::add_vertex(g);
7314  vSink = boost::add_vertex(g);
7315 
7316  std::cout << "build graph edges" << std::endl;
7317  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7318  ++it) // for all pixels in imIn create a vertex and an edge
7319  {
7320  o1 = it.getOffset();
7321  double val = imIn.pixelFromOffset(o1);
7322  int marker = imMarker.pixelFromOffset(o1);
7323 
7324  int valright = 0;
7325  int valleft = 0;
7326  int valup = 0;
7327  int valdown = 0;
7328 
7329  if (marker == 2) {
7330  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
7331  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
7332  capacity[e4] = (std::numeric_limits<double>::max)();
7333  capacity[e3] = (std::numeric_limits<double>::max)();
7334  rev[e4] = e3;
7335  rev[e3] = e4;
7336  } else if (marker == 3) {
7337  boost::tie(e4, in1) = boost::add_edge(o1, vSink, g);
7338  boost::tie(e3, in1) = boost::add_edge(vSink, o1, g);
7339  capacity[e4] = (std::numeric_limits<double>::max)();
7340  capacity[e3] = (std::numeric_limits<double>::max)();
7341  rev[e4] = e3;
7342  rev[e3] = e4;
7343  }
7344 
7345  neighb.setCenter(o1);
7346 
7347  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
7348  const offset_t o2 = nit.getOffset();
7349  if (o2 <= o1)
7350  continue;
7351  if (o2 > o1) {
7352  double val2 = imIn.pixelFromOffset(o2);
7353  double valeur = (255.0 / (std::abs(val - val2) + 1));
7354  // double valeur = (std::abs(val-val2)+1) ;
7355  double cost = std::pow(valeur, exposant);
7356  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
7357  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
7358  capacity[e4] = cost;
7359  capacity[e3] = cost;
7360  rev[e4] = e3;
7361  rev[e3] = e4;
7362  }
7363  }
7364  }
7365 
7366  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
7367  boost::get(boost::vertex_index, g);
7368  std::vector<boost::default_color_type> color(boost::num_vertices(g));
7369  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
7370  boost::num_vertices(g));
7371 
7372  std::cout << "Compute Max flow " << std::endl;
7373 #if BOOST_VERSION >= 104700
7374  double flow =
7375  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
7376  &color[0], indexmap, vSource, vSink);
7377 #else
7378  double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
7379  &color[0], indexmap, vSource, vSink);
7380 #endif
7381 
7382  std::cout << "c The total flow found :" << std::endl;
7383  std::cout << "s " << flow << std::endl << std::endl;
7384 
7385  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7386  ++it) // for all pixels in imIn create a vertex and an edge
7387  {
7388  o1 = it.getOffset();
7389  if (color[o1] == color[vSource])
7390  imOut.setPixel(o1, 2);
7391  else if (color[o1] == color[vSink])
7392  imOut.setPixel(o1, 3);
7393  else if (color[o1] == 1)
7394  imOut.setPixel(o1, 4);
7395  }
7396 
7397  return RES_OK;
7398  }
7399 
7400  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
7401  RES_C t_geoCutsWatershed_Prog_MinCut(const ImageIn &imIn,
7402  const ImageMarker &imMarker,
7403  const SE &nl, ImageOut &imOut)
7404  {
7405  MORPHEE_ENTER_FUNCTION("t_geoCutsWatershed_Prog_MinCut");
7406 
7407  std::cout << "Enter function geoCutsWatershed_Prog_MinCut" << std::endl;
7408 
7409  if ((!imOut.isAllocated())) {
7410  MORPHEE_REGISTER_ERROR("Not allocated");
7411  return RES_NOT_ALLOCATED;
7412  }
7413 
7414  if ((!imIn.isAllocated())) {
7415  MORPHEE_REGISTER_ERROR("Not allocated");
7416  return RES_NOT_ALLOCATED;
7417  }
7418 
7419  if ((!imMarker.isAllocated())) {
7420  MORPHEE_REGISTER_ERROR("Not allocated");
7421  return RES_NOT_ALLOCATED;
7422  }
7423 
7424  // common image iterator
7425  typename ImageIn::const_iterator it, iend;
7426  typename ImageOut::const_iterator ito, ioend;
7427  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
7428  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
7429  offset_t o0;
7430  offset_t o1;
7431 
7432  // needed for max flow: capacit map, rev_capacity map, etc.
7433  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
7434  boost::directedS>
7435  Traits;
7436  typedef boost::adjacency_list<
7437  boost::listS, boost::vecS, boost::directedS,
7438  boost::property<boost::vertex_name_t, std::string>,
7439  boost::property<
7440  boost::edge_capacity_t, double,
7441  boost::property<boost::edge_residual_capacity_t, double,
7442  boost::property<boost::edge_reverse_t,
7443  Traits::edge_descriptor>>>>
7444  Graph_d;
7445 
7446  Graph_d g;
7447 
7448  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
7449  boost::get(boost::edge_capacity, g);
7450 
7451  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
7452  get(boost::edge_reverse, g);
7453 
7454  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
7455  residual_capacity = get(boost::edge_residual_capacity, g);
7456 
7457  bool in1;
7458  Graph_d::edge_descriptor e1, e2, e3, e4;
7459  Graph_d::vertex_descriptor vSource, vSink;
7460  int numVert = 0;
7461 
7462  std::cout << "build graph vertices" << std::endl;
7463  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7464  ++it) // for all pixels in imIn create a vertex
7465  {
7466  o0 = it.getOffset();
7467  boost::add_vertex(g);
7468  numVert++;
7469  }
7470 
7471  std::cout << "number of vertices: " << numVert << std::endl;
7472 
7473  vSource = boost::add_vertex(g);
7474  vSink = boost::add_vertex(g);
7475 
7476  std::cout << "build graph edges" << std::endl;
7477  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7478  ++it) // for all pixels in imIn create a vertex and an edge
7479  {
7480  o1 = it.getOffset();
7481  double val = imIn.pixelFromOffset(o1);
7482  int marker = imMarker.pixelFromOffset(o1);
7483 
7484  int valright = 0;
7485  int valleft = 0;
7486  int valup = 0;
7487  int valdown = 0;
7488 
7489  if (marker == 2) {
7490  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
7491  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
7492  capacity[e4] = (std::numeric_limits<double>::max)();
7493  capacity[e3] = (std::numeric_limits<double>::max)();
7494  rev[e4] = e3;
7495  rev[e3] = e4;
7496  } else if (marker == 3) {
7497  boost::tie(e4, in1) = boost::add_edge(o1, vSink, g);
7498  boost::tie(e3, in1) = boost::add_edge(vSink, o1, g);
7499  capacity[e4] = (std::numeric_limits<double>::max)();
7500  capacity[e3] = (std::numeric_limits<double>::max)();
7501  rev[e4] = e3;
7502  rev[e3] = e4;
7503  }
7504 
7505  neighb.setCenter(o1);
7506 
7507  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
7508  const offset_t o2 = nit.getOffset();
7509  if (o2 <= o1)
7510  continue;
7511  if (o2 > o1) {
7512  double val2 = imIn.pixelFromOffset(o2);
7513  double valeur = (255.0 / (std::abs(val - val2) + 1));
7514  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
7515  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
7516  capacity[e4] = valeur;
7517  capacity[e3] = valeur;
7518  rev[e4] = e3;
7519  rev[e3] = e4;
7520  }
7521  }
7522  }
7523 
7524  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
7525  boost::get(boost::vertex_index, g);
7526  std::vector<boost::default_color_type> color(boost::num_vertices(g));
7527  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
7528  boost::num_vertices(g));
7529  std::cout << "Compute Max flow " << std::endl;
7530 #if BOOST_VERSION >= 104700
7531  double flow =
7532  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
7533  &color[0], indexmap, vSource, vSink);
7534 #else
7535  double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
7536  &color[0], indexmap, vSource, vSink);
7537 #endif
7538  std::cout << "c The total flow found :" << std::endl;
7539  std::cout << "s " << flow << std::endl << std::endl;
7540 
7541  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7542  ++it) // for all pixels in imIn create a vertex and an edge
7543  {
7544  o1 = it.getOffset();
7545  if (color[o1] == color[vSource])
7546  imOut.setPixel(o1, 0);
7547  if (color[o1] == color[vSink])
7548  imOut.setPixel(o1, 2);
7549  }
7550 
7551  for (int i = 2; i <= 15; i++) {
7552  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7553  ++it) // for all pixels in imIn create a vertex and an edge
7554  {
7555  o1 = it.getOffset();
7556  neighb.setCenter(o1);
7557 
7558  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
7559  const offset_t o2 = nit.getOffset();
7560  if (o2 <= o1)
7561  continue;
7562  if (o2 > o1) {
7563  boost::tie(e4, in1) = boost::edge(o1, o2, g);
7564  boost::tie(e3, in1) = boost::edge(o2, o1, g);
7565  double valeur = capacity[e4];
7566  double cost = std::pow(valeur, i) - residual_capacity[e4];
7567  capacity[e4] = cost;
7568  capacity[e3] = cost;
7569  rev[e4] = e3;
7570  rev[e3] = e4;
7571  }
7572  }
7573  }
7574  std::cout << "Compute Max flow " << std::endl;
7575 #if BOOST_VERSION >= 104700
7576  double flow =
7577  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
7578  &color[0], indexmap, vSource, vSink);
7579 #else
7580  double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
7581  &color[0], indexmap, vSource, vSink);
7582 #endif
7583  std::cout << "c The total flow found :" << std::endl;
7584  std::cout << "s " << flow << std::endl << std::endl;
7585 
7586  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7587  ++it) // for all pixels in imIn create a vertex and an edge
7588  {
7589  o1 = it.getOffset();
7590  int val = imOut.pixelFromOffset(o1);
7591  if (color[o1] == color[vSource])
7592  imOut.setPixel(o1, 0);
7593  if (color[o1] == color[vSink] && val == 0)
7594  imOut.setPixel(o1, 2 + i - 1);
7595  }
7596  }
7597 
7598  return RES_OK;
7599  }
7600 
7601  template <class ImageIn, class ImageMarker, typename _Power, class SE,
7602  class ImageOut>
7603  RES_C
7604  t_geoCutsWatershed_SPF(const ImageIn &imIn, const ImageMarker &imMarker,
7605  const _Power Power, const SE &nl, ImageOut &imOut)
7606  {
7607  MORPHEE_ENTER_FUNCTION("t_geoCutsWatershed_SPF");
7608 
7609  std::cout << "Enter function Geo-Cuts Watershed SPF" << std::endl;
7610 
7611  if ((!imOut.isAllocated())) {
7612  MORPHEE_REGISTER_ERROR("Not allocated");
7613  return RES_NOT_ALLOCATED;
7614  }
7615 
7616  if ((!imIn.isAllocated())) {
7617  MORPHEE_REGISTER_ERROR("Not allocated");
7618  return RES_NOT_ALLOCATED;
7619  }
7620 
7621  if ((!imMarker.isAllocated())) {
7622  MORPHEE_REGISTER_ERROR("Not allocated");
7623  return RES_NOT_ALLOCATED;
7624  }
7625 
7626  double exposant = (double) Power;
7627  std::cout << "exposant = " << exposant << std::endl;
7628 
7629  // common image iterator
7630  typename ImageIn::const_iterator it, iend;
7631  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
7632  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
7633  offset_t o0;
7634  offset_t o1;
7635 
7636  std::queue<int> temp_q;
7637 
7638  //----------------------------------------------------------------
7639  // Needed for spanning tree computation
7640  //----------------------------------------------------------------
7641  typedef boost::adjacency_list<
7642  boost::vecS, boost::vecS, boost::undirectedS,
7643  boost::property<boost::vertex_distance_t, double>,
7644  boost::property<boost::edge_capacity_t, double>>
7645  Graph_d;
7646 
7647  Graph_d g;
7648 
7649  boost::property_map<Graph_d, boost::edge_capacity_t>::type weightmap =
7650  boost::get(boost::edge_capacity, g);
7651 
7652  bool in1;
7653  Graph_d::edge_descriptor e1, e2, e3, e4;
7654  Graph_d::vertex_descriptor vRoot;
7655  int numVert = 0;
7656 
7657  //----------------------------------------------------------------
7658  //----------------------------------------------------------------
7659 
7660  std::cout << "build graph vertices" << std::endl;
7661 
7662  // double mean1 = 0;
7663  // double mean2 = 0;
7664  // double nb1= 0;
7665  // double nb2 = 0;
7666 
7667  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7668  ++it) // for all pixels in imIn create a vertex
7669  {
7670  o0 = it.getOffset();
7671  imOut.setPixel(o0, 0);
7672  boost::add_vertex(g);
7673  numVert++;
7674 
7675  // double val = imIn.pixelFromOffset(o0);
7676  // int marker = imMarker.pixelFromOffset(o0);
7677 
7678  // if (marker==2){
7679  // mean1 = mean1+val;
7680  // nb1++;
7681  //}
7682  // if (marker==3){
7683  // mean2 = mean2+val;
7684  // nb2++;
7685  //}
7686  }
7687 
7688  // mean1 = mean1/(nb1);
7689  // mean2 = mean2/(nb2);
7690  // std::cout<<"mean region 1 :"<<mean1<<std::endl;
7691  // std::cout<<"mean region 2 :"<<mean2<<std::endl;
7692 
7693  // double mean_considered = std::min(mean1,mean2);
7694 
7695  vRoot = boost::add_vertex(g);
7696 
7697  std::cout << "number of vertices: " << numVert << std::endl;
7698 
7699  std::cout << "build graph edges" << std::endl;
7700 
7701  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7702  ++it) // for all pixels in imIn create a vertex and an edge
7703  {
7704  o1 = it.getOffset();
7705  double val = imIn.pixelFromOffset(o1);
7706  int marker = imMarker.pixelFromOffset(o1);
7707 
7708  if (marker > 0) {
7709  boost::tie(e4, in1) = boost::add_edge(vRoot, o1, g);
7710  weightmap[e4] = 1.0;
7711  }
7712 
7713  neighb.setCenter(o1);
7714 
7715  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
7716  const offset_t o2 = nit.getOffset();
7717  if (o2 <= o1)
7718  continue;
7719  if (o2 > o1) {
7720  double val2 = imIn.pixelFromOffset(o2);
7721  // double cost = std::pow(std::abs((val-val2))+1,exposant);
7722  double cost = std::pow(std::max(val, val2) + 1, exposant);
7723  // double cost = 1.0 + exposant*(std::abs(val-val2));
7724  // double cost = std::abs( std::abs(val-mean_considered) -
7725  // std::abs(val2-mean_considered) ) + 1;
7726  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
7727  weightmap[e4] = cost;
7728  }
7729  }
7730  }
7731 
7732  std::cout << "Compute Shortest Path Forest" << std::endl;
7733 
7734  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
7735  boost::num_vertices(g));
7736  boost::property_map<Graph_d, boost::vertex_distance_t>::type distancemap =
7737  boost::get(boost::vertex_distance, g);
7738  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap2 =
7739  boost::get(boost::vertex_index, g);
7740 
7741  // int D[1][1];
7742 
7743  // std::cout<<"start"<<std::endl;
7744 
7745  // johnson_all_pairs_shortest_paths( g, D, indexmap2, weightmap, 0 );
7746 
7747  // std::cout<<"finished"<<std::endl;
7748 
7749  dijkstra_shortest_paths(g, vRoot, &p[0], distancemap, weightmap,
7750  indexmap2, std::less<double>(),
7751  boost::closed_plus<double>(),
7752  (std::numeric_limits<double>::max)(), 0,
7753  boost::default_dijkstra_visitor());
7754 
7755  std::cout << "Backward Nodes Labelling" << std::endl;
7756 
7757  int current_offset = 0;
7758  int marker = 0;
7759  int pixout = 0;
7760  int label = 0;
7761 
7762  // SCAN IMAGE TO FIND THE PIXELS LABELS
7763  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7764  ++it) // for all pixels in imIn create a vertex and an edge
7765  {
7766  o1 = it.getOffset();
7767 
7768  // marker = imMarker.pixelFromOffset(o1);
7769 
7770  // IMOUT TAKE THE VALUE OF THE MARKER
7771  // if(marker==0){
7772  // imOut.setPixel(o1,(distancemap[o1]));
7773  // imOut.setPixel(o1,-10.0 *
7774  //std::log(1.0/(1.0+0.00001*distancemap[o1])));
7775  // }
7776  // else{
7777  // imOut.setPixel(o1,0.0);
7778  // }
7779  //}
7780 
7781  // IF PIXELS IS MARKED
7782  marker = imMarker.pixelFromOffset(o1);
7783 
7784  // IMOUT TAKE THE VALUE OF THE MARKER
7785  if (marker > 0) {
7786  imOut.setPixel(o1, marker);
7787  }
7788 
7789  // CHECK IMOUT VALUE
7790  pixout = imOut.pixelFromOffset(o1);
7791 
7792  // IF IMOUT HAS NOT A VALUE, SCAN THE PREDECESSOR UNTIL REACHING A
7793  // MARKER
7794  if (pixout == 0) {
7795  // CURRENT POSITION
7796  current_offset = it.getOffset();
7797  ;
7798 
7799  // std::cout<<current_offset<<std::endl;
7800 
7801  temp_q.push(current_offset);
7802 
7803  // CHECK THE PREDECESSOR
7804  marker = imMarker.pixelFromOffset(p[current_offset]);
7805  pixout = imOut.pixelFromOffset(p[current_offset]);
7806 
7807  // IF BOTH MARKERS AND IMOUT HAS NO VALUES
7808  while ((marker == 0 && pixout == 0)) {
7809  // GO BACKWARD
7810  current_offset = p[current_offset];
7811 
7812  if (p[current_offset] == current_offset) {
7813  marker = 1;
7814  pixout = 1;
7815  } else {
7816  // PUSH THE PREDECESSOT IN THE QUEUE
7817  temp_q.push(current_offset);
7818 
7819  // CHECK THE PREDECESSOR
7820  marker = imMarker.pixelFromOffset(p[current_offset]);
7821  pixout = imOut.pixelFromOffset(p[current_offset]);
7822  }
7823  }
7824 
7825  // WE HAVE REACHED A MARKER
7826  if (marker > 0 && pixout == 0) {
7827  label = marker;
7828  imOut.setPixel(p[current_offset], label);
7829  } else if (marker == 0 && pixout > 0) {
7830  label = pixout;
7831  } else if (marker > 0 && pixout > 0) {
7832  label = pixout;
7833  }
7834  // EMPTY THE QUEUE AND LABEL NODES ALONG THE PATH
7835  while (temp_q.size() > 0) {
7836  current_offset = temp_q.front();
7837  temp_q.pop();
7838  imOut.setPixel(current_offset, label);
7839  }
7840  }
7841  }
7842 
7843  return RES_OK;
7844  }
7845 
7846  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
7847  RES_C t_geoCutsMax_Fiability_Forest(const ImageIn &imIn,
7848  const ImageMarker &imMarker,
7849  const SE &nl, ImageOut &imOut)
7850  {
7851  MORPHEE_ENTER_FUNCTION("t_geoCutsMax_Fiability_Forest");
7852 
7853  std::cout << "Enter function t_geoCutsMax_Fiability_Forest" << std::endl;
7854 
7855  if ((!imOut.isAllocated())) {
7856  MORPHEE_REGISTER_ERROR("Not allocated");
7857  return RES_NOT_ALLOCATED;
7858  }
7859 
7860  if ((!imIn.isAllocated())) {
7861  MORPHEE_REGISTER_ERROR("Not allocated");
7862  return RES_NOT_ALLOCATED;
7863  }
7864 
7865  if ((!imMarker.isAllocated())) {
7866  MORPHEE_REGISTER_ERROR("Not allocated");
7867  return RES_NOT_ALLOCATED;
7868  }
7869 
7870  // common image iterator
7871  typename ImageIn::const_iterator it, iend;
7872  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
7873  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
7874  offset_t o0;
7875  offset_t o1;
7876 
7877  std::queue<int> temp_q;
7878 
7879  //----------------------------------------------------------------
7880  // Needed for spanning tree computation
7881  //----------------------------------------------------------------
7882  typedef boost::adjacency_list<
7883  boost::vecS, boost::vecS, boost::undirectedS,
7884  boost::property<boost::vertex_distance_t, double>,
7885  boost::property<boost::edge_capacity_t, double>>
7886  Graph_d;
7887 
7888  Graph_d g;
7889 
7890  boost::property_map<Graph_d, boost::edge_capacity_t>::type weightmap =
7891  boost::get(boost::edge_capacity, g);
7892 
7893  boost::property_map<Graph_d, boost::edge_capacity_t>::type weightmap2 =
7894  boost::get(boost::edge_capacity, g);
7895 
7896  bool in1;
7897  Graph_d::edge_descriptor e1, e2, e3, e4;
7898  Graph_d::vertex_descriptor vRoot;
7899  int numVert = 0;
7900 
7901  //----------------------------------------------------------------
7902  //----------------------------------------------------------------
7903 
7904  std::cout << "build graph vertices" << std::endl;
7905 
7906  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7907  ++it) // for all pixels in imIn create a vertex
7908  {
7909  o0 = it.getOffset();
7910  imOut.setPixel(o0, 0);
7911  boost::add_vertex(g);
7912  numVert++;
7913  }
7914 
7915  vRoot = boost::add_vertex(g);
7916 
7917  std::cout << "number of vertices: " << numVert << std::endl;
7918 
7919  std::cout << "build graph edges" << std::endl;
7920 
7921  for (it = imIn.begin(), iend = imIn.end(); it != iend;
7922  ++it) // for all pixels in imIn create a vertex and an edge
7923  {
7924  o1 = it.getOffset();
7925  double val = imIn.pixelFromOffset(o1);
7926  int marker = imMarker.pixelFromOffset(o1);
7927 
7928  if (marker > 0) {
7929  boost::tie(e4, in1) = boost::add_edge(vRoot, o1, g);
7930  weightmap[e4] = 1.0;
7931  }
7932 
7933  neighb.setCenter(o1);
7934 
7935  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
7936  const offset_t o2 = nit.getOffset();
7937  if (o2 <= o1)
7938  continue;
7939  if (o2 > o1) {
7940  double val2 = imIn.pixelFromOffset(o2);
7941  double cost = 1.0 / (1.0 + 0.1 * std::abs(val - val2));
7942  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
7943  weightmap2[e4] = cost;
7944  }
7945  }
7946  }
7947 
7948  // for(it=imIn.begin(),iend=imIn.end(); it!=iend ; ++it) // for all pixels
7949  // in imIn create a vertex and an edge
7950  //{
7951  // o1=it.getOffset();
7952  //
7953  // neighb.setCenter(o1);
7954 
7955  // double totalcost = 0;
7956 
7957  // for(nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit)
7958  // {
7959  // const offset_t o2 = nit.getOffset();
7960  // if(o2==o1) continue;
7961  // else {
7962  // boost::tie(e4, in1) = boost::edge(o1,o2, g);
7963  // totalcost = totalcost + weightmap[e4] ;
7964  // }
7965  // }
7966 
7967  // for(nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit)
7968  // {
7969  // const offset_t o2 = nit.getOffset();
7970  // if(o2==o1) continue;
7971  // else {
7972  // boost::tie(e4, in1) = boost::edge(o1,o2, g);
7973  // weightmap2[e4] =
7974  //std::min(weightmap[e4]/totalcost,weightmap2[e4]);
7975  // }
7976  // }
7977  //}
7978 
7979  std::cout << "Compute Shortest Path Forest" << std::endl;
7980 
7981  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
7982  boost::num_vertices(g));
7983  boost::property_map<Graph_d, boost::vertex_distance_t>::type distancemap =
7984  boost::get(boost::vertex_distance, g);
7985  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap2 =
7986  boost::get(boost::vertex_index, g);
7987 
7988  dijkstra_shortest_paths(g, vRoot, &p[0], distancemap, weightmap2,
7989  indexmap2, std::greater<double>(),
7990  boost::detail::multiplication<double>(), 0.0, 1.0,
7991  boost::default_dijkstra_visitor());
7992 
7993  std::cout << "Backward Nodes Labelling" << std::endl;
7994 
7995  int current_offset = 0;
7996  int marker = 0;
7997  int pixout = 0;
7998  int label = 0;
7999 
8000  // SCAN IMAGE TO FIND THE PIXELS LABELS
8001  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8002  ++it) // for all pixels in imIn create a vertex and an edge
8003  {
8004  o1 = it.getOffset();
8005 
8006  // IF PIXELS IS MARKED
8007  marker = imMarker.pixelFromOffset(o1);
8008  // imOut.setPixel(o1,distancemap[o1]);
8009  //}
8010 
8011  // IMOUT TAKE THE VALUE OF THE MARKER
8012  if (marker > 0) {
8013  imOut.setPixel(o1, marker);
8014  }
8015 
8016  // CHECK IMOUT VALUE
8017  pixout = imOut.pixelFromOffset(o1);
8018 
8019  // IF IMOUT HAS NOT A VALUE, SCAN THE PREDECESSOR UNTIL REACHING A
8020  // MARKER
8021  if (pixout == 0) {
8022  // CURRENT POSITION
8023  current_offset = it.getOffset();
8024  ;
8025 
8026  // std::cout<<current_offset<<std::endl;
8027 
8028  temp_q.push(current_offset);
8029 
8030  // CHECK THE PREDECESSOR
8031  marker = imMarker.pixelFromOffset(p[current_offset]);
8032  pixout = imOut.pixelFromOffset(p[current_offset]);
8033 
8034  // IF BOTH MARKERS AND IMOUT HAS NO VALUES
8035  while ((marker == 0 && pixout == 0)) {
8036  // GO BACKWARD
8037  current_offset = p[current_offset];
8038 
8039  if (p[current_offset] == current_offset) {
8040  marker = 1;
8041  pixout = 1;
8042  } else {
8043  // PUSH THE PREDECESSOT IN THE QUEUE
8044  temp_q.push(current_offset);
8045 
8046  // CHECK THE PREDECESSOR
8047  marker = imMarker.pixelFromOffset(p[current_offset]);
8048  pixout = imOut.pixelFromOffset(p[current_offset]);
8049  }
8050  }
8051 
8052  // WE HAVE REACHED A MARKER
8053  if (marker > 0 && pixout == 0) {
8054  label = marker;
8055  imOut.setPixel(p[current_offset], label);
8056  } else if (marker == 0 && pixout > 0) {
8057  label = pixout;
8058  } else if (marker > 0 && pixout > 0) {
8059  label = pixout;
8060  }
8061  // EMPTY THE QUEUE AND LABEL NODES ALONG THE PATH
8062  while (temp_q.size() > 0) {
8063  current_offset = temp_q.front();
8064  temp_q.pop();
8065  imOut.setPixel(current_offset, label);
8066  }
8067  }
8068  }
8069 
8070  return RES_OK;
8071  }
8072 
8073  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
8074  RES_C t_geoCutsBiCriteria_Shortest_Forest(const ImageIn &imIn,
8075  const ImageMarker &imMarker,
8076  const SE &nl, ImageOut &imOut)
8077  {
8078  MORPHEE_ENTER_FUNCTION("t_geoCutsBiCriteria_Shortest_Forest");
8079 
8080  std::cout << "Enter function t_geoCutsBiCriteria_Shortest_Forest"
8081  << std::endl;
8082 
8083  if ((!imOut.isAllocated())) {
8084  MORPHEE_REGISTER_ERROR("Not allocated");
8085  return RES_NOT_ALLOCATED;
8086  }
8087 
8088  if ((!imIn.isAllocated())) {
8089  MORPHEE_REGISTER_ERROR("Not allocated");
8090  return RES_NOT_ALLOCATED;
8091  }
8092 
8093  if ((!imMarker.isAllocated())) {
8094  MORPHEE_REGISTER_ERROR("Not allocated");
8095  return RES_NOT_ALLOCATED;
8096  }
8097 
8098  // common image iterator
8099  typename ImageIn::const_iterator it, iend;
8100  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
8101  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
8102  offset_t o0;
8103  offset_t o1;
8104 
8105  std::queue<int> temp_q;
8106 
8107  //----------------------------------------------------------------
8108  // Needed for spanning tree computation
8109  //----------------------------------------------------------------
8110  typedef std::pair<double, double> double2;
8111 
8112  typedef boost::adjacency_list<
8113  boost::vecS, boost::vecS, boost::undirectedS,
8114  boost::property<boost::vertex_distance_t, double2>,
8115  boost::property<boost::edge_capacity_t, double2>>
8116  Graph_d;
8117 
8118  Graph_d g;
8119 
8120  boost::property_map<Graph_d, boost::edge_capacity_t>::type weightmap =
8121  boost::get(boost::edge_capacity, g);
8122 
8123  bool in1;
8124  Graph_d::edge_descriptor e1, e2, e3, e4;
8125  Graph_d::vertex_descriptor vRoot;
8126  int numVert = 0;
8127 
8128  //----------------------------------------------------------------
8129  //----------------------------------------------------------------
8130 
8131  std::cout << "build graph vertices" << std::endl;
8132 
8133  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8134  ++it) // for all pixels in imIn create a vertex
8135  {
8136  o0 = it.getOffset();
8137  imOut.setPixel(o0, 0);
8138  boost::add_vertex(g);
8139  numVert++;
8140  }
8141 
8142  vRoot = boost::add_vertex(g);
8143 
8144  std::cout << "number of vertices: " << numVert << std::endl;
8145 
8146  std::cout << "build graph edges" << std::endl;
8147 
8148  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8149  ++it) // for all pixels in imIn create a vertex and an edge
8150  {
8151  o1 = it.getOffset();
8152  double val = imIn.pixelFromOffset(o1);
8153  int marker = imMarker.pixelFromOffset(o1);
8154 
8155  if (marker > 0) {
8156  boost::tie(e4, in1) = boost::add_edge(vRoot, o1, g);
8157  weightmap[e4] = std::make_pair(1.0, 1.0);
8158  }
8159 
8160  neighb.setCenter(o1);
8161 
8162  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
8163  const offset_t o2 = nit.getOffset();
8164  if (o2 <= o1)
8165  continue;
8166  if (o2 > o1) {
8167  double val2 = imIn.pixelFromOffset(o2);
8168  // double cost = std::pow(std::abs((val-val2))+1,1.0);
8169  double cost = std::max(val, val2) + 1;
8170  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
8171  weightmap[e4] = std::make_pair(cost, 1.0);
8172  }
8173  }
8174  }
8175 
8176  std::cout << "Compute Shortest Path Forest" << std::endl;
8177 
8178  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
8179  boost::num_vertices(g));
8180  boost::property_map<Graph_d, boost::vertex_distance_t>::type distancemap =
8181  boost::get(boost::vertex_distance, g);
8182  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap2 =
8183  boost::get(boost::vertex_index, g);
8184 
8185  dijkstra_shortest_paths(
8186  g, vRoot, &p[0], distancemap, weightmap, indexmap2,
8187  boost::detail::lexico_less2<double2>(),
8188  boost::detail::lexico_addition2<double2>(),
8189  std::make_pair(std::numeric_limits<double>::max(),
8190  std::numeric_limits<double>::max()),
8191  std::make_pair(0, 0), boost::default_dijkstra_visitor());
8192 
8193  std::cout << "Backward Nodes Labelling" << std::endl;
8194 
8195  int current_offset = 0;
8196  int marker = 0;
8197  int pixout = 0;
8198  int label = 0;
8199 
8200  // SCAN IMAGE TO FIND THE PIXELS LABELS
8201  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8202  ++it) // for all pixels in imIn create a vertex and an edge
8203  {
8204  o1 = it.getOffset();
8205 
8206  // IF PIXELS IS MARKED
8207  marker = imMarker.pixelFromOffset(o1);
8208 
8209  // IMOUT TAKE THE VALUE OF THE MARKER
8210  if (marker > 0) {
8211  imOut.setPixel(o1, marker);
8212  }
8213 
8214  // CHECK IMOUT VALUE
8215  pixout = imOut.pixelFromOffset(o1);
8216 
8217  // IF IMOUT HAS NOT A VALUE, SCAN THE PREDECESSOR UNTIL REACHING A
8218  // MARKER
8219  if (pixout == 0) {
8220  // CURRENT POSITION
8221  current_offset = it.getOffset();
8222  ;
8223 
8224  // std::cout<<current_offset<<std::endl;
8225 
8226  temp_q.push(current_offset);
8227 
8228  // CHECK THE PREDECESSOR
8229  marker = imMarker.pixelFromOffset(p[current_offset]);
8230  pixout = imOut.pixelFromOffset(p[current_offset]);
8231 
8232  // IF BOTH MARKERS AND IMOUT HAS NO VALUES
8233  while ((marker == 0 && pixout == 0)) {
8234  // GO BACKWARD
8235  current_offset = p[current_offset];
8236 
8237  if (p[current_offset] == current_offset) {
8238  marker = 1;
8239  pixout = 1;
8240  } else {
8241  // PUSH THE PREDECESSOT IN THE QUEUE
8242  temp_q.push(current_offset);
8243 
8244  // CHECK THE PREDECESSOR
8245  marker = imMarker.pixelFromOffset(p[current_offset]);
8246  pixout = imOut.pixelFromOffset(p[current_offset]);
8247  }
8248  }
8249 
8250  // WE HAVE REACHED A MARKER
8251  if (marker > 0 && pixout == 0) {
8252  label = marker;
8253  imOut.setPixel(p[current_offset], label);
8254  } else if (marker == 0 && pixout > 0) {
8255  label = pixout;
8256  } else if (marker > 0 && pixout > 0) {
8257  label = pixout;
8258  }
8259  // EMPTY THE QUEUE AND LABEL NODES ALONG THE PATH
8260  while (temp_q.size() > 0) {
8261  current_offset = temp_q.front();
8262  temp_q.pop();
8263  imOut.setPixel(current_offset, label);
8264  }
8265  }
8266  }
8267 
8268  return RES_OK;
8269  }
8270 
8271  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
8272  RES_C t_geoCutsLexicographical_Shortest_Forest(const ImageIn &imIn,
8273  const ImageMarker &imMarker,
8274  const SE &nl,
8275  ImageOut &imOut)
8276  {
8277  MORPHEE_ENTER_FUNCTION("t_geoCutsLexicographical_Shortest_Forest");
8278 
8279  std::cout << "Enter function t_geoCutsLexicographical_Shortest_Forest"
8280  << std::endl;
8281 
8282  if ((!imOut.isAllocated())) {
8283  MORPHEE_REGISTER_ERROR("Not allocated");
8284  return RES_NOT_ALLOCATED;
8285  }
8286 
8287  if ((!imIn.isAllocated())) {
8288  MORPHEE_REGISTER_ERROR("Not allocated");
8289  return RES_NOT_ALLOCATED;
8290  }
8291 
8292  if ((!imMarker.isAllocated())) {
8293  MORPHEE_REGISTER_ERROR("Not allocated");
8294  return RES_NOT_ALLOCATED;
8295  }
8296 
8297  // common image iterator
8298  typename ImageIn::const_iterator it, iend;
8299  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
8300  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
8301  offset_t o0;
8302  offset_t o1;
8303 
8304  std::queue<int> temp_q;
8305 
8306  //----------------------------------------------------------------
8307  // Needed for spanning tree computation
8308  //----------------------------------------------------------------
8309  typedef std::vector<double> vdouble;
8310 
8311  typedef boost::adjacency_list<
8312  boost::vecS, boost::vecS, boost::undirectedS,
8313  boost::property<boost::vertex_distance_t, vdouble>,
8314  boost::property<boost::edge_capacity_t, vdouble>>
8315  Graph_d;
8316 
8317  Graph_d g;
8318 
8319  boost::property_map<Graph_d, boost::edge_capacity_t>::type weightmap =
8320  boost::get(boost::edge_capacity, g);
8321 
8322  bool in1;
8323  Graph_d::edge_descriptor e1, e2, e3, e4;
8324  Graph_d::vertex_descriptor vRoot;
8325  int numVert = 0;
8326 
8327  std::vector<double> roots_cost;
8328  roots_cost.push_back(1.0);
8329 
8330  std::vector<double> edges_cost;
8331  edges_cost.push_back(1.0);
8332  //----------------------------------------------------------------
8333  //----------------------------------------------------------------
8334 
8335  std::cout << "build graph vertices" << std::endl;
8336 
8337  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8338  ++it) // for all pixels in imIn create a vertex
8339  {
8340  o0 = it.getOffset();
8341  imOut.setPixel(o0, 0);
8342  boost::add_vertex(g);
8343  numVert++;
8344  }
8345 
8346  vRoot = boost::add_vertex(g);
8347 
8348  std::cout << "number of vertices: " << numVert << std::endl;
8349 
8350  std::cout << "build graph edges" << std::endl;
8351 
8352  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8353  ++it) // for all pixels in imIn create a vertex and an edge
8354  {
8355  o1 = it.getOffset();
8356  double val = imIn.pixelFromOffset(o1);
8357  int marker = imMarker.pixelFromOffset(o1);
8358 
8359  if (marker > 0) {
8360  boost::tie(e4, in1) = boost::add_edge(vRoot, o1, g);
8361  weightmap[e4] = roots_cost;
8362  }
8363 
8364  neighb.setCenter(o1);
8365 
8366  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
8367  const offset_t o2 = nit.getOffset();
8368  if (o2 <= o1)
8369  continue;
8370  if (o2 > o1) {
8371  double val2 = imIn.pixelFromOffset(o2);
8372  // double cost = std::abs(val-val2)+1;
8373  double cost = std::max(val, val2) + 1;
8374  edges_cost[0] = cost;
8375  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
8376  weightmap[e4] = edges_cost;
8377  }
8378  }
8379  }
8380 
8381  std::cout << "Compute Shortest Path Forest" << std::endl;
8382 
8383  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
8384  boost::num_vertices(g));
8385  boost::property_map<Graph_d, boost::vertex_distance_t>::type distancemap =
8386  boost::get(boost::vertex_distance, g);
8387  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap2 =
8388  boost::get(boost::vertex_index, g);
8389 
8390  std::vector<double> infinite;
8391  infinite.push_back(std::numeric_limits<double>::max());
8392 
8393  std::vector<double> zero;
8394  zero.push_back(0);
8395 
8396  dijkstra_shortest_paths(
8397  g, vRoot, &p[0], distancemap, weightmap, indexmap2,
8398  boost::detail::lexico_compare<vdouble>(),
8399  boost::detail::lexico_addition<vdouble>(), infinite, zero,
8400  boost::default_dijkstra_visitor());
8401 
8402  std::cout << "Backward Nodes Labelling" << std::endl;
8403 
8404  int current_offset = 0;
8405  int marker = 0;
8406  int pixout = 0;
8407  int label = 0;
8408 
8409  // SCAN IMAGE TO FIND THE PIXELS LABELS
8410  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8411  ++it) // for all pixels in imIn create a vertex and an edge
8412  {
8413  o1 = it.getOffset();
8414 
8415  // std::cout<<distancemap[o1]<<std::endl;
8416 
8417  // IF PIXELS IS MARKED
8418  marker = imMarker.pixelFromOffset(o1);
8419 
8420  // IMOUT TAKE THE VALUE OF THE MARKER
8421  if (marker > 0) {
8422  imOut.setPixel(o1, marker);
8423  }
8424 
8425  // CHECK IMOUT VALUE
8426  pixout = imOut.pixelFromOffset(o1);
8427 
8428  // IF IMOUT HAS NOT A VALUE, SCAN THE PREDECESSOR UNTIL REACHING A
8429  // MARKER
8430  if (pixout == 0) {
8431  // CURRENT POSITION
8432  current_offset = it.getOffset();
8433  ;
8434 
8435  // std::cout<<current_offset<<std::endl;
8436 
8437  temp_q.push(current_offset);
8438 
8439  // CHECK THE PREDECESSOR
8440  marker = imMarker.pixelFromOffset(p[current_offset]);
8441  pixout = imOut.pixelFromOffset(p[current_offset]);
8442 
8443  // IF BOTH MARKERS AND IMOUT HAS NO VALUES
8444  while ((marker == 0 && pixout == 0)) {
8445  // GO BACKWARD
8446  current_offset = p[current_offset];
8447 
8448  if (p[current_offset] == current_offset) {
8449  marker = 1;
8450  pixout = 1;
8451  } else {
8452  // PUSH THE PREDECESSOT IN THE QUEUE
8453  temp_q.push(current_offset);
8454 
8455  // CHECK THE PREDECESSOR
8456  marker = imMarker.pixelFromOffset(p[current_offset]);
8457  pixout = imOut.pixelFromOffset(p[current_offset]);
8458  }
8459  }
8460 
8461  // WE HAVE REACHED A MARKER
8462  if (marker > 0 && pixout == 0) {
8463  label = marker;
8464  imOut.setPixel(p[current_offset], label);
8465  } else if (marker == 0 && pixout > 0) {
8466  label = pixout;
8467  } else if (marker > 0 && pixout > 0) {
8468  label = pixout;
8469  }
8470  // EMPTY THE QUEUE AND LABEL NODES ALONG THE PATH
8471  while (temp_q.size() > 0) {
8472  current_offset = temp_q.front();
8473  temp_q.pop();
8474  imOut.setPixel(current_offset, label);
8475  }
8476  }
8477  }
8478 
8479  return RES_OK;
8480  }
8481 
8482  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
8483  RES_C t_geoCutsVectorial_Lexicographical_Shortest_Forest(
8484  const ImageIn &imIn, const ImageMarker &imMarker, const SE &nl,
8485  ImageOut &imOut)
8486  {
8487  MORPHEE_ENTER_FUNCTION(
8488  "t_geoCutsVectorial_Lexicographical_Shortest_Forest");
8489 
8490  std::cout << "Enter function "
8491  "t_geoCutsVectorial_Lexicographical_Shortest_Forest"
8492  << std::endl;
8493 
8494  if ((!imOut.isAllocated())) {
8495  MORPHEE_REGISTER_ERROR("Not allocated");
8496  return RES_NOT_ALLOCATED;
8497  }
8498 
8499  if ((!imIn.isAllocated())) {
8500  MORPHEE_REGISTER_ERROR("Not allocated");
8501  return RES_NOT_ALLOCATED;
8502  }
8503 
8504  if ((!imMarker.isAllocated())) {
8505  MORPHEE_REGISTER_ERROR("Not allocated");
8506  return RES_NOT_ALLOCATED;
8507  }
8508 
8509  // common image iterator
8510  typename ImageIn::const_iterator it, iend;
8511  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
8512  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
8513  offset_t o0;
8514  offset_t o1;
8515 
8516  std::queue<int> temp_q;
8517 
8518  //----------------------------------------------------------------
8519  // Needed for spanning tree computation
8520  //----------------------------------------------------------------
8521 
8522  typedef boost::adjacency_list<
8523  boost::vecS, boost::vecS, boost::undirectedS,
8524  boost::property<boost::vertex_distance_t,
8525  std::vector<std::vector<double>>>,
8526  boost::property<boost::edge_capacity_t,
8527  std::vector<std::vector<double>>>>
8528  Graph_d;
8529 
8530  Graph_d g;
8531 
8532  boost::property_map<Graph_d, boost::edge_capacity_t>::type weightmap =
8533  boost::get(boost::edge_capacity, g);
8534 
8535  bool in1;
8536  Graph_d::edge_descriptor e1, e2, e3, e4;
8537  Graph_d::vertex_descriptor vRoot;
8538  int numVert = 0;
8539 
8540  //----------------------------------------------------------------
8541  //----------------------------------------------------------------
8542 
8543  pixel_3<F_DOUBLE> pxImageIn;
8544  pixel_3<F_DOUBLE> pxImageNeigh;
8545 
8546  std::vector<std::vector<double>> root;
8547 
8548  std::vector<double> roots_cost;
8549  roots_cost.push_back(0.1);
8550  roots_cost.push_back(0.1);
8551  roots_cost.push_back(0.1);
8552 
8553  root.push_back(roots_cost);
8554 
8555  std::vector<std::vector<double>> test;
8556  test.push_back(roots_cost);
8557  test.push_back(roots_cost);
8558  int sizea = test.size();
8559 
8560  std::cout << "taille des test " << sizea << std::endl;
8561 
8562  for (int i = 0; i < 2; i++) {
8563  std::vector<double> temp = test[i];
8564  std::cout << temp[0] << " " << temp[1] << " " << temp[2] << std::endl;
8565  }
8566 
8567  std::cout << "build graph vertices" << std::endl;
8568 
8569  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8570  ++it) // for all pixels in imIn create a vertex
8571  {
8572  o0 = it.getOffset();
8573  imOut.setPixel(o0, 0);
8574  boost::add_vertex(g);
8575  numVert++;
8576  }
8577 
8578  vRoot = boost::add_vertex(g);
8579 
8580  std::cout << "number of vertices: " << numVert << std::endl;
8581 
8582  std::cout << "build graph edges" << std::endl;
8583 
8584  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8585  ++it) // for all pixels in imIn create a vertex and an edge
8586  {
8587  o1 = it.getOffset();
8588  pxImageIn = imIn.pixelFromOffset(o1);
8589 
8590  double valeur1 = pxImageIn.channel1;
8591  double valeur2 = pxImageIn.channel2;
8592  double valeur3 = pxImageIn.channel3;
8593 
8594  int marker = imMarker.pixelFromOffset(o1);
8595 
8596  if (marker > 0) {
8597  boost::tie(e4, in1) = boost::add_edge(vRoot, o1, g);
8598  weightmap[e4] = root;
8599  }
8600 
8601  neighb.setCenter(o1);
8602 
8603  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
8604  const offset_t o2 = nit.getOffset();
8605  if (o2 <= o1)
8606  continue;
8607  if (o2 > o1) {
8608  pxImageNeigh = imIn.pixelFromOffset(o2);
8609  std::vector<std::vector<double>> cost;
8610  std::vector<double> ordered_cost_vector;
8611 
8612  double valeurn1 = std::abs(pxImageNeigh.channel1 - valeur1) + 1;
8613  double valeurn2 = std::abs(pxImageNeigh.channel2 - valeur2) + 1;
8614  double valeurn3 = std::abs(pxImageNeigh.channel3 - valeur3) + 1;
8615 
8616  // double maxim = std::max(std::max(valeurn1,valeurn2),valeurn3);
8617 
8618  ordered_cost_vector.push_back(valeurn1);
8619  ordered_cost_vector.push_back(valeurn2);
8620  ordered_cost_vector.push_back(valeurn3);
8621 
8622  // double maxim = std::max(std::max(valeurn1,valeurn2),valeurn3);
8623  // double minim = std::min(std::min(valeurn1,valeurn2),valeurn3);
8624 
8625  // if(maxim >= valeurn1 && minim <= valeurn1){
8626  // ordered_cost_vector.push_back(maxim);
8627  // ordered_cost_vector.push_back(valeurn1);
8628  // ordered_cost_vector.push_back(minim);
8629  //}
8630  // else if(maxim >= valeurn2 && minim <= valeurn2){
8631  // ordered_cost_vector.push_back(maxim);
8632  // ordered_cost_vector.push_back(valeurn2);
8633  // ordered_cost_vector.push_back(minim);
8634  //}
8635  // else if(maxim >= valeurn3 && minim <= valeurn3){
8636  // ordered_cost_vector.push_back(maxim);
8637  // ordered_cost_vector.push_back(valeurn3);
8638  // ordered_cost_vector.push_back(minim);
8639  //}
8640 
8641  cost.push_back(ordered_cost_vector);
8642  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
8643  weightmap[e4] = cost;
8644  }
8645  }
8646  }
8647 
8648  std::cout << "Compute Minimum Spanning Forest" << std::endl;
8649 
8650  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
8651  boost::num_vertices(g));
8652  boost::property_map<Graph_d, boost::vertex_distance_t>::type distancemap =
8653  boost::get(boost::vertex_distance, g);
8654  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap2 =
8655  boost::get(boost::vertex_index, g);
8656 
8657  std::vector<std::vector<double>> inff;
8658  std::vector<double> infinite;
8659  infinite.push_back(std::numeric_limits<double>::max());
8660  infinite.push_back(std::numeric_limits<double>::max());
8661  infinite.push_back(std::numeric_limits<double>::max());
8662  inff.push_back(infinite);
8663 
8664  std::vector<std::vector<double>> Zeroo;
8665  std::vector<double> zero;
8666  zero.push_back(0.0);
8667  zero.push_back(0.0);
8668  zero.push_back(0.0);
8669  Zeroo.push_back(zero);
8670 
8671  dijkstra_shortest_paths(g, vRoot, &p[0], distancemap, weightmap,
8672  indexmap2,
8673  boost::detail::lexico_compare_vect_of_vect<
8674  std::vector<std::vector<double>>>(),
8675  boost::detail::lexico_addition_vect_of_vect<
8676  std::vector<std::vector<double>>>(),
8677  inff, Zeroo, boost::default_dijkstra_visitor());
8678  std::cout << "Backward Nodes Labelling" << std::endl;
8679 
8680  int current_offset = 0;
8681  int marker = 0;
8682  int pixout = 0;
8683  int label = 0;
8684 
8685  // SCAN IMAGE TO FIND THE PIXELS LABELS
8686  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8687  ++it) // for all pixels in imIn create a vertex and an edge
8688  {
8689  o1 = it.getOffset();
8690 
8691  // IF PIXELS IS MARKED
8692  marker = imMarker.pixelFromOffset(o1);
8693 
8694  // IMOUT TAKE THE VALUE OF THE MARKER
8695  if (marker > 0) {
8696  imOut.setPixel(o1, marker);
8697  }
8698 
8699  // CHECK IMOUT VALUE
8700  pixout = imOut.pixelFromOffset(o1);
8701 
8702  // IF IMOUT HAS NOT A VALUE, SCAN THE PREDECESSOR UNTIL REACHING A
8703  // MARKER
8704  if (pixout == 0) {
8705  // CURRENT POSITION
8706  current_offset = it.getOffset();
8707  ;
8708 
8709  // std::cout<<current_offset<<std::endl;
8710 
8711  temp_q.push(current_offset);
8712 
8713  // CHECK THE PREDECESSOR
8714  marker = imMarker.pixelFromOffset(p[current_offset]);
8715  pixout = imOut.pixelFromOffset(p[current_offset]);
8716 
8717  // IF BOTH MARKERS AND IMOUT HAS NO VALUES
8718  while ((marker == 0 && pixout == 0)) {
8719  // GO BACKWARD
8720  current_offset = p[current_offset];
8721 
8722  if (p[current_offset] == current_offset) {
8723  marker = 1;
8724  pixout = 1;
8725  } else {
8726  // PUSH THE PREDECESSOT IN THE QUEUE
8727  temp_q.push(current_offset);
8728 
8729  // CHECK THE PREDECESSOR
8730  marker = imMarker.pixelFromOffset(p[current_offset]);
8731  pixout = imOut.pixelFromOffset(p[current_offset]);
8732  }
8733  }
8734 
8735  // WE HAVE REACHED A MARKER
8736  if (marker > 0 && pixout == 0) {
8737  label = marker;
8738  imOut.setPixel(p[current_offset], label);
8739  } else if (marker == 0 && pixout > 0) {
8740  label = pixout;
8741  } else if (marker > 0 && pixout > 0) {
8742  label = pixout;
8743  }
8744  // EMPTY THE QUEUE AND LABEL NODES ALONG THE PATH
8745  while (temp_q.size() > 0) {
8746  current_offset = temp_q.front();
8747  temp_q.pop();
8748  imOut.setPixel(current_offset, label);
8749  }
8750  }
8751  }
8752 
8753  return RES_OK;
8754  }
8755 
8756  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
8757  RES_C t_geoCutsVectorial_Shortest_Forest(const ImageIn &imIn,
8758  const ImageMarker &imMarker,
8759  const SE &nl, ImageOut &imOut)
8760  {
8761  MORPHEE_ENTER_FUNCTION("t_geoCutsVectorial_Shortest_Forest");
8762 
8763  std::cout << "Enter function t_geoCutsVectorial_Shortest_Forest"
8764  << std::endl;
8765 
8766  if ((!imOut.isAllocated())) {
8767  MORPHEE_REGISTER_ERROR("Not allocated");
8768  return RES_NOT_ALLOCATED;
8769  }
8770 
8771  if ((!imIn.isAllocated())) {
8772  MORPHEE_REGISTER_ERROR("Not allocated");
8773  return RES_NOT_ALLOCATED;
8774  }
8775 
8776  if ((!imMarker.isAllocated())) {
8777  MORPHEE_REGISTER_ERROR("Not allocated");
8778  return RES_NOT_ALLOCATED;
8779  }
8780 
8781  // common image iterator
8782  typename ImageIn::const_iterator it, iend;
8783  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
8784  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
8785  offset_t o0;
8786  offset_t o1;
8787 
8788  std::queue<int> temp_q;
8789 
8790  //----------------------------------------------------------------
8791  // Needed for spanning tree computation
8792  //----------------------------------------------------------------
8793  typedef std::vector<double> vdouble;
8794 
8795  typedef boost::adjacency_list<
8796  boost::vecS, boost::vecS, boost::undirectedS,
8797  boost::property<boost::vertex_distance_t, vdouble>,
8798  boost::property<boost::edge_capacity_t, vdouble>>
8799  Graph_d;
8800 
8801  Graph_d g;
8802 
8803  boost::property_map<Graph_d, boost::edge_capacity_t>::type weightmap =
8804  boost::get(boost::edge_capacity, g);
8805 
8806  bool in1;
8807  Graph_d::edge_descriptor e1, e2, e3, e4;
8808  Graph_d::vertex_descriptor vRoot;
8809  int numVert = 0;
8810 
8811  //----------------------------------------------------------------
8812  //----------------------------------------------------------------
8813 
8814  pixel_3<F_DOUBLE> pxImageIn;
8815  pixel_3<F_DOUBLE> pxImageNeigh;
8816 
8817  std::vector<double> roots_cost;
8818  roots_cost.push_back(0.1);
8819  roots_cost.push_back(0.1);
8820  roots_cost.push_back(0.1);
8821 
8822  std::cout << "build graph vertices" << std::endl;
8823 
8824  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8825  ++it) // for all pixels in imIn create a vertex
8826  {
8827  o0 = it.getOffset();
8828  imOut.setPixel(o0, 0);
8829  boost::add_vertex(g);
8830  numVert++;
8831  }
8832 
8833  vRoot = boost::add_vertex(g);
8834 
8835  std::cout << "number of vertices: " << numVert << std::endl;
8836 
8837  std::cout << "build graph edges" << std::endl;
8838 
8839  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8840  ++it) // for all pixels in imIn create a vertex and an edge
8841  {
8842  o1 = it.getOffset();
8843  pxImageIn = imIn.pixelFromOffset(o1);
8844 
8845  double valeur1 = pxImageIn.channel1;
8846  double valeur2 = pxImageIn.channel2;
8847  double valeur3 = pxImageIn.channel3;
8848 
8849  int marker = imMarker.pixelFromOffset(o1);
8850 
8851  if (marker > 0) {
8852  boost::tie(e4, in1) = boost::add_edge(vRoot, o1, g);
8853  weightmap[e4] = roots_cost;
8854  }
8855 
8856  neighb.setCenter(o1);
8857 
8858  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
8859  const offset_t o2 = nit.getOffset();
8860  if (o2 <= o1)
8861  continue;
8862  if (o2 > o1) {
8863  pxImageNeigh = imIn.pixelFromOffset(o2);
8864  std::vector<double> ordered_cost_vector;
8865  double valeurn1 = std::abs(pxImageNeigh.channel1 - valeur1) + 1;
8866  double valeurn2 = std::abs(pxImageNeigh.channel2 - valeur2) + 1;
8867  double valeurn3 = std::abs(pxImageNeigh.channel3 - valeur3) + 1;
8868 
8869  // double maxim = std::max(std::max(valeurn1,valeurn2),valeurn3);
8870 
8871  ordered_cost_vector.push_back(valeurn1);
8872  ordered_cost_vector.push_back(valeurn2);
8873  ordered_cost_vector.push_back(valeurn3);
8874 
8875  // double maxim = std::max(std::max(valeurn1,valeurn2),valeurn3);
8876  // double minim = std::min(std::min(valeurn1,valeurn2),valeurn3);
8877  //
8878  // if(maxim >= valeurn1 && minim <= valeurn1){
8879  // ordered_cost_vector.push_back(maxim);
8880  // ordered_cost_vector.push_back(valeurn1);
8881  // ordered_cost_vector.push_back(minim);
8882  //}
8883  // else if(maxim >= valeurn2 && minim <= valeurn2){
8884  // ordered_cost_vector.push_back(maxim);
8885  // ordered_cost_vector.push_back(valeurn2);
8886  // ordered_cost_vector.push_back(minim);
8887  //}
8888  // else if(maxim >= valeurn3 && minim <= valeurn3){
8889  // ordered_cost_vector.push_back(maxim);
8890  // ordered_cost_vector.push_back(valeurn3);
8891  // ordered_cost_vector.push_back(minim);
8892  //}
8893 
8894  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
8895  weightmap[e4] = ordered_cost_vector;
8896  }
8897  }
8898  }
8899 
8900  std::cout << "Compute Minimum Spanning Forest" << std::endl;
8901 
8902  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
8903  boost::num_vertices(g));
8904  boost::property_map<Graph_d, boost::vertex_distance_t>::type distancemap =
8905  boost::get(boost::vertex_distance, g);
8906  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap2 =
8907  boost::get(boost::vertex_index, g);
8908 
8909  std::vector<double> infinite;
8910  infinite.push_back(std::numeric_limits<double>::max());
8911  infinite.push_back(std::numeric_limits<double>::max());
8912  infinite.push_back(std::numeric_limits<double>::max());
8913 
8914  std::vector<double> zero;
8915  zero.push_back(0.0);
8916  zero.push_back(0.0);
8917  zero.push_back(0.0);
8918 
8919  dijkstra_shortest_paths(
8920  g, vRoot, &p[0], distancemap, weightmap, indexmap2,
8921  boost::detail::lexico_compare3<vdouble>(),
8922  boost::detail::lexico_addition3<vdouble>(), infinite, zero,
8923  boost::default_dijkstra_visitor());
8924  std::cout << "Backward Nodes Labelling" << std::endl;
8925 
8926  int current_offset = 0;
8927  int marker = 0;
8928  int pixout = 0;
8929  int label = 0;
8930 
8931  // SCAN IMAGE TO FIND THE PIXELS LABELS
8932  for (it = imIn.begin(), iend = imIn.end(); it != iend;
8933  ++it) // for all pixels in imIn create a vertex and an edge
8934  {
8935  o1 = it.getOffset();
8936 
8937  // IF PIXELS IS MARKED
8938  marker = imMarker.pixelFromOffset(o1);
8939 
8940  // IMOUT TAKE THE VALUE OF THE MARKER
8941  if (marker > 0) {
8942  imOut.setPixel(o1, marker);
8943  }
8944 
8945  // CHECK IMOUT VALUE
8946  pixout = imOut.pixelFromOffset(o1);
8947 
8948  // IF IMOUT HAS NOT A VALUE, SCAN THE PREDECESSOR UNTIL REACHING A
8949  // MARKER
8950  if (pixout == 0) {
8951  // CURRENT POSITION
8952  current_offset = it.getOffset();
8953  ;
8954 
8955  // std::cout<<current_offset<<std::endl;
8956 
8957  temp_q.push(current_offset);
8958 
8959  // CHECK THE PREDECESSOR
8960  marker = imMarker.pixelFromOffset(p[current_offset]);
8961  pixout = imOut.pixelFromOffset(p[current_offset]);
8962 
8963  // IF BOTH MARKERS AND IMOUT HAS NO VALUES
8964  while ((marker == 0 && pixout == 0)) {
8965  // GO BACKWARD
8966  current_offset = p[current_offset];
8967 
8968  if (p[current_offset] == current_offset) {
8969  marker = 1;
8970  pixout = 1;
8971  } else {
8972  // PUSH THE PREDECESSOT IN THE QUEUE
8973  temp_q.push(current_offset);
8974 
8975  // CHECK THE PREDECESSOR
8976  marker = imMarker.pixelFromOffset(p[current_offset]);
8977  pixout = imOut.pixelFromOffset(p[current_offset]);
8978  }
8979  }
8980 
8981  // WE HAVE REACHED A MARKER
8982  if (marker > 0 && pixout == 0) {
8983  label = marker;
8984  imOut.setPixel(p[current_offset], label);
8985  } else if (marker == 0 && pixout > 0) {
8986  label = pixout;
8987  } else if (marker > 0 && pixout > 0) {
8988  label = pixout;
8989  }
8990  // EMPTY THE QUEUE AND LABEL NODES ALONG THE PATH
8991  while (temp_q.size() > 0) {
8992  current_offset = temp_q.front();
8993  temp_q.pop();
8994  imOut.setPixel(current_offset, label);
8995  }
8996  }
8997  }
8998 
8999  return RES_OK;
9000  }
9001 
9002  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
9003  RES_C t_geoCutsWatershed_SpanningForest(const ImageIn &imIn,
9004  const ImageMarker &imMarker,
9005  const SE &nl, ImageOut &imOut)
9006  {
9007  MORPHEE_ENTER_FUNCTION("t_geoCutsWatershed_SpanningForest");
9008 
9009  std::cout << "Enter function t_geoCutsWatershed_SpanningForest"
9010  << std::endl;
9011 
9012  if ((!imOut.isAllocated())) {
9013  MORPHEE_REGISTER_ERROR("Not allocated");
9014  return RES_NOT_ALLOCATED;
9015  }
9016 
9017  if ((!imIn.isAllocated())) {
9018  MORPHEE_REGISTER_ERROR("Not allocated");
9019  return RES_NOT_ALLOCATED;
9020  }
9021 
9022  if ((!imMarker.isAllocated())) {
9023  MORPHEE_REGISTER_ERROR("Not allocated");
9024  return RES_NOT_ALLOCATED;
9025  }
9026 
9027  // common image iterator
9028  typename ImageIn::const_iterator it, iend;
9029  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
9030  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
9031  offset_t o0;
9032  offset_t o1;
9033 
9034  std::queue<int> temp_q;
9035 
9036  //----------------------------------------------------------------
9037  // Needed for spanning tree computation
9038  //----------------------------------------------------------------
9039  typedef boost::adjacency_list<
9040  boost::vecS, boost::vecS, boost::undirectedS,
9041  boost::property<boost::vertex_distance_t, double>,
9042  boost::property<boost::edge_capacity_t, double>>
9043  Graph_d;
9044 
9045  Graph_d g;
9046 
9047  boost::property_map<Graph_d, boost::edge_capacity_t>::type weightmap =
9048  boost::get(boost::edge_capacity, g);
9049 
9050  bool in1;
9051  Graph_d::edge_descriptor e1, e2, e3, e4;
9052  Graph_d::vertex_descriptor vRoot;
9053  int numVert = 0;
9054 
9055  //----------------------------------------------------------------
9056  //----------------------------------------------------------------
9057 
9058  std::cout << "build graph vertices" << std::endl;
9059 
9060  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9061  ++it) // for all pixels in imIn create a vertex
9062  {
9063  o0 = it.getOffset();
9064  imOut.setPixel(o0, 0);
9065  boost::add_vertex(g);
9066  numVert++;
9067  }
9068 
9069  vRoot = boost::add_vertex(g);
9070 
9071  std::cout << "number of vertices: " << numVert << std::endl;
9072 
9073  std::cout << "build graph edges" << std::endl;
9074 
9075  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9076  ++it) // for all pixels in imIn create a vertex and an edge
9077  {
9078  o1 = it.getOffset();
9079  double val = imIn.pixelFromOffset(o1);
9080  int marker = imMarker.pixelFromOffset(o1);
9081 
9082  if (marker > 0) {
9083  boost::tie(e4, in1) = boost::add_edge(vRoot, o1, g);
9084  weightmap[e4] = 0.1;
9085  }
9086 
9087  neighb.setCenter(o1);
9088 
9089  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
9090  const offset_t o2 = nit.getOffset();
9091  if (o2 <= o1)
9092  continue;
9093  if (o2 > o1) {
9094  double val2 = imIn.pixelFromOffset(o2);
9095  double cost = std::abs(val - val2) + 1;
9096  // double cost = std::sqrt(std::abs(val-val2)+1);
9097  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
9098  weightmap[e4] = cost;
9099  }
9100  }
9101  }
9102 
9103  std::cout << "Compute Minimum Spanning Forest" << std::endl;
9104 
9105  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
9106  boost::num_vertices(g));
9107  boost::property_map<Graph_d, boost::vertex_distance_t>::type distancemap =
9108  boost::get(boost::vertex_distance, g);
9109  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap2 =
9110  boost::get(boost::vertex_index, g);
9111 
9112  dijkstra_shortest_paths(g, vRoot, &p[0], distancemap, weightmap,
9113  indexmap2, std::less<double>(),
9114  boost::detail::maximum<double>(),
9115  (std::numeric_limits<double>::max)(), 0,
9116  boost::default_dijkstra_visitor());
9117 
9118  // prim_minimum_spanning_tree(g, vRoot, &p[0], distancemap, weightmap,
9119  // indexmap2, boost::default_dijkstra_visitor());
9120 
9121  std::cout << "Backward Nodes Labelling" << std::endl;
9122 
9123  int current_offset = 0;
9124  int marker = 0;
9125  int pixout = 0;
9126  int label = 0;
9127 
9128  // SCAN IMAGE TO FIND THE PIXELS LABELS
9129  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9130  ++it) // for all pixels in imIn create a vertex and an edge
9131  {
9132  o1 = it.getOffset();
9133 
9134  // IF PIXELS IS MARKED
9135  marker = imMarker.pixelFromOffset(o1);
9136 
9137  // IMOUT TAKE THE VALUE OF THE MARKER
9138  if (marker > 0) {
9139  imOut.setPixel(o1, marker);
9140  }
9141 
9142  // CHECK IMOUT VALUE
9143  pixout = imOut.pixelFromOffset(o1);
9144 
9145  // IF IMOUT HAS NOT A VALUE, SCAN THE PREDECESSOR UNTIL REACHING A
9146  // MARKER
9147  if (pixout == 0) {
9148  // CURRENT POSITION
9149  current_offset = it.getOffset();
9150  ;
9151 
9152  // std::cout<<current_offset<<std::endl;
9153 
9154  temp_q.push(current_offset);
9155 
9156  // CHECK THE PREDECESSOR
9157  marker = imMarker.pixelFromOffset(p[current_offset]);
9158  pixout = imOut.pixelFromOffset(p[current_offset]);
9159 
9160  // IF BOTH MARKERS AND IMOUT HAS NO VALUES
9161  while ((marker == 0 && pixout == 0)) {
9162  // GO BACKWARD
9163  current_offset = p[current_offset];
9164 
9165  if (p[current_offset] == current_offset) {
9166  marker = 1;
9167  pixout = 1;
9168  } else {
9169  // PUSH THE PREDECESSOT IN THE QUEUE
9170  temp_q.push(current_offset);
9171 
9172  // CHECK THE PREDECESSOR
9173  marker = imMarker.pixelFromOffset(p[current_offset]);
9174  pixout = imOut.pixelFromOffset(p[current_offset]);
9175  }
9176  }
9177 
9178  // WE HAVE REACHED A MARKER
9179  if (marker > 0 && pixout == 0) {
9180  label = marker;
9181  imOut.setPixel(p[current_offset], label);
9182  } else if (marker == 0 && pixout > 0) {
9183  label = pixout;
9184  } else if (marker > 0 && pixout > 0) {
9185  label = pixout;
9186  }
9187  // EMPTY THE QUEUE AND LABEL NODES ALONG THE PATH
9188  while (temp_q.size() > 0) {
9189  current_offset = temp_q.front();
9190  temp_q.pop();
9191  imOut.setPixel(current_offset, label);
9192  }
9193  }
9194  }
9195 
9196  return RES_OK;
9197  }
9198 
9199  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
9200  RES_C t_geoCutsWatershed_SpanningForest_v2(const ImageIn &imIn,
9201  const ImageMarker &imMarker,
9202  const SE &nl, ImageOut &imOut)
9203  {
9204  MORPHEE_ENTER_FUNCTION("t_geoCutsWatershed_SpanningForest_v2");
9205 
9206  std::cout << "Enter function t_geoCutsWatershed_SpanningForest_v2"
9207  << std::endl;
9208 
9209  if ((!imOut.isAllocated())) {
9210  MORPHEE_REGISTER_ERROR("Not allocated");
9211  return RES_NOT_ALLOCATED;
9212  }
9213 
9214  if ((!imIn.isAllocated())) {
9215  MORPHEE_REGISTER_ERROR("Not allocated");
9216  return RES_NOT_ALLOCATED;
9217  }
9218 
9219  if ((!imMarker.isAllocated())) {
9220  MORPHEE_REGISTER_ERROR("Not allocated");
9221  return RES_NOT_ALLOCATED;
9222  }
9223 
9224  // common image iterator
9225 
9226  SE nl2 = morphee::selement::neighborsCross2D;
9227  morphee::selement::Neighborhood<SE, ImageIn> neighb2(imIn, nl2);
9228  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit2,
9229  nend2;
9230 
9231  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
9232  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
9233 
9234  typename ImageIn::const_iterator it, iend;
9235 
9236  offset_t o0;
9237  offset_t o1;
9238 
9239  std::queue<int> temp_q;
9240 
9241  //----------------------------------------------------------------
9242  // Needed for spanning tree computation
9243  //----------------------------------------------------------------
9244  typedef boost::adjacency_list<
9245  boost::vecS, boost::vecS, boost::undirectedS,
9246  boost::property<boost::vertex_distance_t, double>,
9247  boost::property<boost::edge_capacity_t, double>>
9248  Graph_d;
9249 
9250  Graph_d g;
9251 
9252  boost::property_map<Graph_d, boost::edge_capacity_t>::type weightmap =
9253  boost::get(boost::edge_capacity, g);
9254 
9255  bool in1;
9256  Graph_d::edge_descriptor e1, e2, e3, e4;
9257  Graph_d::vertex_descriptor vRoot;
9258  int numVert = 0;
9259 
9260  //----------------------------------------------------------------
9261  //----------------------------------------------------------------
9262  typedef typename s_from_type_to_type<ImageIn, F_SIMPLE>::image_type
9263  dist_image_type;
9264  dist_image_type work = imIn.template t_getSame<float>();
9265  RES_C res = t_ImSetConstant(work, 0.0);
9266  //----------------------------------------------------------------
9267  //----------------------------------------------------------------
9268 
9269  std::cout << "build graph vertices" << std::endl;
9270 
9271  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9272  ++it) // for all pixels in imIn create a vertex
9273  {
9274  o0 = it.getOffset();
9275  work.setPixel(o0, 0.0);
9276  imOut.setPixel(o0, 0);
9277  boost::add_vertex(g);
9278  numVert++;
9279  }
9280 
9281  vRoot = boost::add_vertex(g);
9282 
9283  std::cout << "number of vertices: " << numVert << std::endl;
9284 
9285  //----------------------------------------------------------------
9286  //------------ COMPUTE LOWER SLOPE AT EACH PIXEL
9287  //----------------------------
9288 
9289  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9290  ++it) // for all pixels in imIn create a vertex
9291  {
9292  o0 = it.getOffset();
9293  double val = imIn.pixelFromOffset(o0);
9294 
9295  neighb2.setCenter(o0);
9296  double tempval = val;
9297  double tempval2 = val;
9298  double val2 = 0;
9299 
9300  for (nit2 = neighb2.begin(), nend2 = neighb2.end(); nit2 != nend2;
9301  ++nit2) {
9302  o1 = nit2.getOffset();
9303  val2 = imIn.pixelFromOffset(o1);
9304 
9305  if (val2 < tempval) {
9306  tempval = val2;
9307  }
9308 
9309  // if(val2>tempval){
9310  // tempval = val2;
9311  //}
9312  // else if(val2<tempval2){
9313  // tempval2 = val2;
9314  //}
9315  }
9316 
9317  work.setPixel(o0, (float) val - tempval);
9318  // work.setPixel(o0,(float) tempval-tempval2);
9319 
9320  // work.setPixel(o0,0.0);
9321  }
9322 
9323  std::cout << "build graph edges" << std::endl;
9324 
9325  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9326  ++it) // for all pixels in imIn create a vertex and an edge
9327  {
9328  o1 = it.getOffset();
9329 
9330  double val = imIn.pixelFromOffset(o1);
9331  double ls1 = work.pixelFromOffset(o1);
9332 
9333  int marker = imMarker.pixelFromOffset(o1);
9334 
9335  if (marker > 0) {
9336  boost::tie(e4, in1) = boost::add_edge(vRoot, o1, g);
9337  weightmap[e4] = 0;
9338  }
9339 
9340  neighb.setCenter(o1);
9341 
9342  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
9343  const offset_t o2 = nit.getOffset();
9344 
9345  if (o2 <= o1)
9346  continue;
9347  if (o2 > o1) {
9348  double val2 = imIn.pixelFromOffset(o2);
9349  double ls2 = work.pixelFromOffset(o2);
9350  double cost = 0;
9351 
9352  if (val > val2) {
9353  cost = val2 + ls1;
9354  } else if (val2 > val) {
9355  cost = val + ls2;
9356  } else if (val2 == val) {
9357  cost = val + std::max(ls2, ls1);
9358  }
9359 
9360  // cost = std::max(val,val2) + std::max(ls2,ls1)/2;
9361  // cost = std::max(val,val2);
9362 
9363  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
9364  weightmap[e4] = cost + 1;
9365  }
9366  }
9367  }
9368 
9369  std::cout << "Compute Minimum Spanning Forest" << std::endl;
9370 
9371  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
9372  boost::num_vertices(g));
9373  boost::property_map<Graph_d, boost::vertex_distance_t>::type distancemap =
9374  boost::get(boost::vertex_distance, g);
9375  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap2 =
9376  boost::get(boost::vertex_index, g);
9377 
9378  dijkstra_shortest_paths(g, vRoot, &p[0], distancemap, weightmap,
9379  indexmap2, std::less<double>(),
9380  boost::detail::maximum<double>(),
9381  (std::numeric_limits<double>::max)(), 0,
9382  boost::default_dijkstra_visitor());
9383 
9384  // dijkstra_shortest_paths(g, vRoot, &p[0], distancemap, weightmap,
9385  // indexmap2, std::less<double>(), boost::closed_plus<double>(),
9386  // (std::numeric_limits<double>::max)(), 0,
9387  //boost::default_dijkstra_visitor());
9388 
9389  // prim_minimum_spanning_tree(g, vRoot, &p[0], distancemap, weightmap,
9390  // indexmap2, boost::default_dijkstra_visitor());
9391 
9392  std::cout << "Backward Nodes Labelling" << std::endl;
9393 
9394  int current_offset = 0;
9395  int marker = 0;
9396  int pixout = 0;
9397  int label = 0;
9398 
9399  // SCAN IMAGE TO FIND THE PIXELS LABELS
9400  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9401  ++it) // for all pixels in imIn create a vertex and an edge
9402  {
9403  o1 = it.getOffset();
9404  // imOut.setPixel(o1,distancemap[o1]);
9405 
9406  //}
9407 
9408  // IF PIXELS IS MARKED
9409  marker = imMarker.pixelFromOffset(o1);
9410 
9411  // IMOUT TAKE THE VALUE OF THE MARKER
9412  if (marker > 0) {
9413  imOut.setPixel(o1, marker);
9414  }
9415 
9416  // CHECK IMOUT VALUE
9417  pixout = imOut.pixelFromOffset(o1);
9418 
9419  // IF IMOUT HAS NOT A VALUE, SCAN THE PREDECESSOR UNTIL REACHING A
9420  // MARKER
9421  if (pixout == 0) {
9422  // CURRENT POSITION
9423  current_offset = it.getOffset();
9424  ;
9425 
9426  // std::cout<<current_offset<<std::endl;
9427 
9428  temp_q.push(current_offset);
9429 
9430  // CHECK THE PREDECESSOR
9431  marker = imMarker.pixelFromOffset(p[current_offset]);
9432  pixout = imOut.pixelFromOffset(p[current_offset]);
9433 
9434  // IF BOTH MARKERS AND IMOUT HAS NO VALUES
9435  while ((marker == 0 && pixout == 0)) {
9436  // GO BACKWARD
9437  current_offset = p[current_offset];
9438 
9439  if (p[current_offset] == current_offset) {
9440  marker = 1;
9441  pixout = 1;
9442  } else {
9443  // PUSH THE PREDECESSOT IN THE QUEUE
9444  temp_q.push(current_offset);
9445 
9446  // CHECK THE PREDECESSOR
9447  marker = imMarker.pixelFromOffset(p[current_offset]);
9448  pixout = imOut.pixelFromOffset(p[current_offset]);
9449  }
9450  }
9451 
9452  // WE HAVE REACHED A MARKER
9453  if (marker > 0 && pixout == 0) {
9454  label = marker;
9455  imOut.setPixel(p[current_offset], label);
9456  } else if (marker == 0 && pixout > 0) {
9457  label = pixout;
9458  } else if (marker > 0 && pixout > 0) {
9459  label = pixout;
9460  }
9461  // EMPTY THE QUEUE AND LABEL NODES ALONG THE PATH
9462  while (temp_q.size() > 0) {
9463  current_offset = temp_q.front();
9464  temp_q.pop();
9465  imOut.setPixel(current_offset, label);
9466  }
9467  }
9468  }
9469 
9470  return RES_OK;
9471  }
9472 
9473  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
9474  RES_C t_geoCutsReg_SpanningForest(const ImageIn &imIn,
9475  const ImageMarker &imMarker,
9476  const SE &nl, ImageOut &imOut)
9477  {
9478  MORPHEE_ENTER_FUNCTION("t_geoCutsReg_SpanningForest");
9479 
9480  std::cout << "Enter function geoCutsSpanningForest" << std::endl;
9481 
9482  if ((!imOut.isAllocated())) {
9483  MORPHEE_REGISTER_ERROR("Not allocated");
9484  return RES_NOT_ALLOCATED;
9485  }
9486 
9487  if ((!imIn.isAllocated())) {
9488  MORPHEE_REGISTER_ERROR("Not allocated");
9489  return RES_NOT_ALLOCATED;
9490  }
9491 
9492  if ((!imMarker.isAllocated())) {
9493  MORPHEE_REGISTER_ERROR("Not allocated");
9494  return RES_NOT_ALLOCATED;
9495  }
9496 
9497  // common image iterator
9498  typename ImageIn::const_iterator it, iend;
9499  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
9500  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
9501  offset_t o0;
9502  offset_t o1;
9503 
9504  std::queue<int> temp_q;
9505 
9506  //----------------------------------------------------------------
9507  // needed for spanning tree
9508  //----------------------------------------------------------------
9509  typedef boost::adjacency_list<
9510  boost::vecS, boost::vecS, boost::undirectedS,
9511  boost::property<boost::vertex_distance_t, double>,
9512  boost::property<boost::edge_capacity_t, double>>
9513  Graph_d;
9514 
9515  Graph_d g;
9516 
9517  boost::property_map<Graph_d, boost::edge_capacity_t>::type weightmap =
9518  boost::get(boost::edge_capacity, g);
9519 
9520  bool in1, in2;
9521  Graph_d::edge_descriptor e1, e2, e3, e4;
9522  Graph_d::vertex_descriptor vRoot;
9523  int numVert = 0;
9524 
9525  //----------------------------------------------------------------
9526  // needed for max flow: capacit map, rev_capacity map, etc.
9527  //----------------------------------------------------------------
9528  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
9529  boost::directedS>
9530  Traits;
9531  typedef boost::adjacency_list<
9532  boost::listS, boost::vecS, boost::directedS,
9533  boost::property<boost::vertex_name_t, std::string>,
9534  boost::property<
9535  boost::edge_capacity_t, double,
9536  boost::property<boost::edge_residual_capacity_t, double,
9537  boost::property<boost::edge_reverse_t,
9538  Traits::edge_descriptor>>>>
9539  Graph_flow;
9540 
9541  Graph_flow g_flow;
9542 
9543  boost::property_map<Graph_flow, boost::edge_capacity_t>::type capacity =
9544  boost::get(boost::edge_capacity, g_flow);
9545 
9546  boost::property_map<Graph_flow, boost::edge_reverse_t>::type rev =
9547  get(boost::edge_reverse, g_flow);
9548 
9549  boost::property_map<Graph_flow, boost::edge_residual_capacity_t>::type
9550  residual_capacity = get(boost::edge_residual_capacity, g_flow);
9551 
9552  Graph_flow::edge_descriptor e11, e22;
9553  Graph_flow::vertex_descriptor vSource, vSink;
9554 
9555  //----------------------------------------------------------------
9556  //----------------------------------------------------------------
9557 
9558  std::cout << "build graph vertices" << std::endl;
9559 
9560  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9561  ++it) // for all pixels in imIn create a vertex
9562  {
9563  o0 = it.getOffset();
9564  imOut.setPixel(o0, 0);
9565  boost::add_vertex(g);
9566 
9567  //-------------For max_flow-------------
9568  boost::add_vertex(g_flow);
9569  //------------------------------------------
9570 
9571  numVert++;
9572  }
9573 
9574  vRoot = boost::add_vertex(g);
9575 
9576  //-------------For max_flow-------------
9577  vSource = boost::add_vertex(g_flow);
9578  vSink = boost::add_vertex(g_flow);
9579  //------------------------------------------
9580 
9581  std::cout << "number of vertices: " << numVert << std::endl;
9582 
9583  std::cout << "build graph edges" << std::endl;
9584 
9585  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9586  ++it) // for all pixels in imIn create a vertex and an edge
9587  {
9588  o1 = it.getOffset();
9589  double val = imIn.pixelFromOffset(o1);
9590  int marker = imMarker.pixelFromOffset(o1);
9591 
9592  if (marker > 0) {
9593  boost::tie(e4, in1) = boost::add_edge(vRoot, o1, g);
9594  weightmap[e4] = 0.5;
9595 
9596  if (marker == 2) {
9597  boost::tie(e11, in1) = boost::add_edge(vSource, o1, g_flow);
9598  boost::tie(e22, in2) = boost::add_edge(o1, vSource, g_flow);
9599  capacity[e11] = 1000000000;
9600  capacity[e22] = 1000000000;
9601  rev[e11] = e22;
9602  rev[e22] = e11;
9603  }
9604  if (marker == 3) {
9605  boost::tie(e11, in1) = boost::add_edge(vSink, o1, g_flow);
9606  boost::tie(e22, in2) = boost::add_edge(o1, vSink, g_flow);
9607  capacity[e11] = 1000000000;
9608  capacity[e22] = 1000000000;
9609  rev[e11] = e22;
9610  rev[e22] = e11;
9611  }
9612  }
9613 
9614  neighb.setCenter(o1);
9615 
9616  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
9617  const offset_t o2 = nit.getOffset();
9618  if (o2 <= o1)
9619  continue;
9620  if (o2 > o1) {
9621  double val2 = imIn.pixelFromOffset(o2);
9622  double cost = std::abs((val - val2)) + 1;
9623  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
9624  weightmap[e4] = cost;
9625 
9626  boost::tie(e11, in1) = boost::add_edge(o1, o2, g_flow);
9627  boost::tie(e22, in2) = boost::add_edge(o2, o1, g_flow);
9628  capacity[e11] = 256 / (cost);
9629  capacity[e22] = 256 / (cost);
9630  rev[e11] = e22;
9631  rev[e22] = e11;
9632  }
9633  }
9634  }
9635 
9636  std::cout << "Compute Minimum Spanning Forest" << std::endl;
9637 
9638  std::vector<boost::graph_traits<Graph_d>::vertex_descriptor> p(
9639  boost::num_vertices(g));
9640  boost::property_map<Graph_d, boost::vertex_distance_t>::type distancemap =
9641  boost::get(boost::vertex_distance, g);
9642  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap2 =
9643  boost::get(boost::vertex_index, g);
9644 
9645  prim_minimum_spanning_tree(g, vRoot, &p[0], distancemap, weightmap,
9646  indexmap2, boost::default_dijkstra_visitor());
9647 
9648  std::cout << "Backward Nodes Labelling" << std::endl;
9649 
9650  int current_offset = 0;
9651  int first_offset = 0;
9652  int marker = 0;
9653  int pixout = 0;
9654  int label = 0;
9655 
9656  // SCAN IMAGE TO FIND THE PIXELS LABELS
9657  for (int i = 0; i < numVert; i++) {
9658  // IF PIXELS IS MARKED
9659  marker = imMarker.pixelFromOffset(i);
9660 
9661  // IMOUT TAKE THE VALUE OF THE MARKER
9662  if (marker > 0) {
9663  imOut.setPixel(i, marker);
9664  }
9665 
9666  // CHECK IMOUT VALUE
9667  pixout = imOut.pixelFromOffset(i);
9668 
9669  // IF IMOUT HAS NOT A VALUE, SCAN THE PREDECESSOR UNTIL REACHING A
9670  // MARKER
9671  if (pixout == 0) {
9672  // CURRENT POSITION
9673  current_offset = i;
9674  temp_q.push(current_offset);
9675 
9676  // CHECK THE PREDECESSOR
9677  marker = imMarker.pixelFromOffset(p[current_offset]);
9678  pixout = imOut.pixelFromOffset(p[current_offset]);
9679 
9680  // IF BOTH MARKERS AND IMOUT HAS NO VALUES
9681  while ((marker == 0 && pixout == 0)) {
9682  // GO BACKWARD
9683  current_offset = p[current_offset];
9684 
9685  // PUSH THE PREDECESSOT IN THE QUEUE
9686  temp_q.push(current_offset);
9687 
9688  // CHECK THE PREDECESSOR
9689  marker = imMarker.pixelFromOffset(p[current_offset]);
9690  pixout = imOut.pixelFromOffset(p[current_offset]);
9691  }
9692 
9693  temp_q.push(p[current_offset]);
9694 
9695  // WE HAVE REACHED A MARKER
9696  if (marker > 0 && pixout == 0) {
9697  label = marker;
9698  imOut.setPixel(p[current_offset], label);
9699  } else if (marker == 0 && pixout > 0) {
9700  label = pixout;
9701  } else if (marker > 0 && pixout > 0) {
9702  label = pixout;
9703  }
9704  // EMPTY THE QUEUE AND LABEL NODES ALONG THE PATH
9705 
9706  while (temp_q.size() > 0) {
9707  first_offset = temp_q.front();
9708  temp_q.pop();
9709  imOut.setPixel(first_offset, label);
9710 
9711  if (p[first_offset] != vRoot) {
9712  current_offset = p[first_offset];
9713  imOut.setPixel(current_offset, label);
9714 
9715  boost::tie(e11, in1) =
9716  boost::edge(first_offset, current_offset, g_flow);
9717  boost::tie(e22, in2) =
9718  boost::edge(current_offset, first_offset, g_flow);
9719 
9720  if (in1 && in2) {
9721  capacity[e22] = capacity[e22];
9722  capacity[e11] = capacity[e11];
9723  }
9724  }
9725  }
9726  }
9727  }
9728 
9729  int pix1 = 0;
9730  int pix2 = 0;
9731 
9732  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9733  ++it) // for all pixels in imIn create a vertex and an edge
9734  {
9735  o1 = it.getOffset();
9736  pix1 = imOut.pixelFromOffset(o1);
9737  neighb.setCenter(o1);
9738 
9739  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
9740  const offset_t o2 = nit.getOffset();
9741  pix2 = imOut.pixelFromOffset(o2);
9742 
9743  if (o2 <= o1)
9744  continue;
9745  if (o2 > o1) {
9746  if (pix2 != pix1) {
9747  boost::tie(e11, in1) = boost::edge(o1, o2, g_flow);
9748  boost::tie(e22, in1) = boost::edge(o2, o1, g_flow);
9749 
9750  capacity[e11] = 3.2;
9751  capacity[e22] = 3.2;
9752  }
9753  }
9754  }
9755  }
9756 
9757  boost::property_map<Graph_flow, boost::vertex_index_t>::const_type
9758  indexmap = boost::get(boost::vertex_index, g_flow);
9759  std::vector<boost::default_color_type> color(boost::num_vertices(g_flow));
9760 
9761  std::cout << "Compute Max flow" << std::endl;
9762 #if BOOST_VERSION >= 104700
9763  double flow =
9764  boykov_kolmogorov_max_flow(g_flow, capacity, residual_capacity, rev,
9765  &color[0], indexmap, vSource, vSink);
9766 #else
9767  double flow =
9768  kolmogorov_max_flow(g_flow, capacity, residual_capacity, rev,
9769  &color[0], indexmap, vSource, vSink);
9770 #endif
9771  std::cout << "c The total flow:" << std::endl;
9772  std::cout << "s " << flow << std::endl << std::endl;
9773 
9774  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9775  ++it) // for all pixels in imIn create a vertex and an edge
9776  {
9777  o1 = it.getOffset();
9778  if (color[o1] == 0)
9779  imOut.setPixel(o1, 2);
9780  if (color[o1] == 1)
9781  imOut.setPixel(o1, 4);
9782  if (color[o1] == 4)
9783  imOut.setPixel(o1, 3);
9784  }
9785 
9786  return RES_OK;
9787  }
9788 
9789  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
9790  RES_C t_geoCutsMinSurfaces_With_Line(const ImageIn &imIn,
9791  const ImageMarker &imMarker,
9792  const SE &nl, ImageOut &imOut)
9793  {
9794  MORPHEE_ENTER_FUNCTION("t_geoCutsMinSurfaces_With_Line");
9795 
9796  std::cout << "Enter function Geo-Cuts" << std::endl;
9797 
9798  if ((!imOut.isAllocated())) {
9799  MORPHEE_REGISTER_ERROR("Not allocated");
9800  return RES_NOT_ALLOCATED;
9801  }
9802 
9803  if ((!imIn.isAllocated())) {
9804  MORPHEE_REGISTER_ERROR("Not allocated");
9805  return RES_NOT_ALLOCATED;
9806  }
9807 
9808  if ((!imMarker.isAllocated())) {
9809  MORPHEE_REGISTER_ERROR("Not allocated");
9810  return RES_NOT_ALLOCATED;
9811  }
9812 
9813  // common image iterator
9814  typename ImageIn::const_iterator it, iend;
9815  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
9816  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
9817  offset_t o0;
9818  offset_t o1;
9819 
9820  // needed for max flow: capacit map, rev_capacity map, etc.
9821  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
9822  boost::directedS>
9823  Traits;
9824  typedef boost::adjacency_list<
9825  boost::listS, boost::vecS, boost::directedS,
9826  boost::property<boost::vertex_name_t, std::string>,
9827  boost::property<
9828  boost::edge_capacity_t, double,
9829  boost::property<boost::edge_residual_capacity_t, double,
9830  boost::property<boost::edge_reverse_t,
9831  Traits::edge_descriptor>>>>
9832  Graph_d;
9833 
9834  Graph_d g;
9835 
9836  double sigma = 1.0;
9837 
9838  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
9839  boost::get(boost::edge_capacity, g);
9840 
9841  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
9842  get(boost::edge_reverse, g);
9843 
9844  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
9845  residual_capacity = get(boost::edge_residual_capacity, g);
9846 
9847  bool in1;
9848  Graph_d::edge_descriptor e1, e2, e3, e4;
9849  Graph_d::vertex_descriptor vSource, vSink;
9850  int numVert = 0;
9851 
9852  std::cout << "build graph vertices" << std::endl;
9853  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9854  ++it) // for all pixels in imIn create a vertex
9855  {
9856  o0 = it.getOffset();
9857  boost::add_vertex(g);
9858  numVert++;
9859  }
9860 
9861  std::cout << "number of vertices: " << numVert << std::endl;
9862 
9863  vSource = boost::add_vertex(g);
9864  vSink = boost::add_vertex(g);
9865 
9866  std::cout << "build graph edges" << std::endl;
9867  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9868  ++it) // for all pixels in imIn create a vertex and an edge
9869  {
9870  o1 = it.getOffset();
9871  double val = imIn.pixelFromOffset(o1);
9872  int marker = imMarker.pixelFromOffset(o1);
9873 
9874  int valright = 0;
9875  int valleft = 0;
9876  int valup = 0;
9877  int valdown = 0;
9878 
9879  if (marker == 2) {
9880  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
9881  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
9882  capacity[e4] = (std::numeric_limits<double>::max)();
9883  capacity[e3] = (std::numeric_limits<double>::max)();
9884  rev[e4] = e3;
9885  rev[e3] = e4;
9886  } else if (marker == 3) {
9887  boost::tie(e4, in1) = boost::add_edge(o1, vSink, g);
9888  boost::tie(e3, in1) = boost::add_edge(vSink, o1, g);
9889  capacity[e4] = (std::numeric_limits<double>::max)();
9890  capacity[e3] = (std::numeric_limits<double>::max)();
9891  rev[e4] = e3;
9892  rev[e3] = e4;
9893  }
9894 
9895  neighb.setCenter(o1);
9896 
9897  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
9898  const offset_t o2 = nit.getOffset();
9899  if (o2 <= o1)
9900  continue;
9901  if (o2 > o1) {
9902  double val2 = imIn.pixelFromOffset(o2);
9903  double cost = 10000 / (1 + 1.5 * (val - val2) * (val - val2));
9904  // double cost = std::exp(-((val-val2)*(val-val2))/(1.0));
9905  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
9906  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
9907  capacity[e4] = cost + 1;
9908  capacity[e3] = cost + 1;
9909  rev[e4] = e3;
9910  rev[e3] = e4;
9911  }
9912  }
9913  }
9914 
9915  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
9916  boost::get(boost::vertex_index, g);
9917  std::vector<boost::default_color_type> color(boost::num_vertices(g));
9918 
9919  std::cout << "Compute Max flow" << std::endl;
9920 #if BOOST_VERSION >= 104700
9921  double flow =
9922  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
9923  &color[0], indexmap, vSource, vSink);
9924 #else
9925  double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
9926  &color[0], indexmap, vSource, vSink);
9927 #endif
9928  std::cout << "c The total flow:" << std::endl;
9929  std::cout << "s " << flow << std::endl << std::endl;
9930 
9931  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9932  ++it) // for all pixels in imIn create a vertex and an edge
9933  {
9934  o1 = it.getOffset();
9935  if (color[o1] == 0)
9936  imOut.setPixel(o1, 2);
9937  if (color[o1] == 1)
9938  imOut.setPixel(o1, 4);
9939  if (color[o1] == 4)
9940  imOut.setPixel(o1, 3);
9941  }
9942 
9943  for (it = imIn.begin(), iend = imIn.end(); it != iend;
9944  ++it) // for all pixels in imIn create a vertex and an edge
9945  {
9946  o1 = it.getOffset();
9947  double val = imOut.pixelFromOffset(o1);
9948  neighb.setCenter(o1);
9949 
9950  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
9951  const offset_t o2 = nit.getOffset();
9952  double val2 = imOut.pixelFromOffset(o2);
9953 
9954  if (val2 != val && val != 0 && val2 != 0) {
9955  imOut.setPixel(o2, 0);
9956  imOut.setPixel(o1, 0);
9957  }
9958  }
9959  }
9960 
9961  return RES_OK;
9962  }
9963 
9964  template <class ImageIn, class ImageMarker, class SE, class ImageOut>
9965  RES_C t_geoCutsMultiway_MinSurfaces(const ImageIn &imIn,
9966  const ImageMarker &imMarker,
9967  const SE &nl, ImageOut &imOut)
9968  {
9969  MORPHEE_ENTER_FUNCTION("t_geoCutsMultiway_MinSurfaces");
9970 
9971  std::cout << "Enter function Multi way Geo-Cuts" << std::endl;
9972 
9973  if ((!imOut.isAllocated())) {
9974  MORPHEE_REGISTER_ERROR("Not allocated");
9975  return RES_NOT_ALLOCATED;
9976  }
9977 
9978  if ((!imIn.isAllocated())) {
9979  MORPHEE_REGISTER_ERROR("Not allocated");
9980  return RES_NOT_ALLOCATED;
9981  }
9982 
9983  if ((!imMarker.isAllocated())) {
9984  MORPHEE_REGISTER_ERROR("Not allocated");
9985  return RES_NOT_ALLOCATED;
9986  }
9987 
9988  // common image iterator
9989  typename ImageIn::const_iterator it, iend;
9990  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
9991  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
9992  offset_t o0;
9993  offset_t o1;
9994 
9995  // needed for max flow: capacit map, rev_capacity map, etc.
9996  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
9997  boost::directedS>
9998  Traits;
9999  typedef boost::adjacency_list<
10000  boost::listS, boost::vecS, boost::directedS,
10001  boost::property<boost::vertex_name_t, std::string>,
10002  boost::property<
10003  boost::edge_capacity_t, double,
10004  boost::property<boost::edge_residual_capacity_t, double,
10005  boost::property<boost::edge_reverse_t,
10006  Traits::edge_descriptor>>>>
10007  Graph_d;
10008 
10009  Graph_d g;
10010 
10011  double sigma = 1.0;
10012 
10013  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
10014  boost::get(boost::edge_capacity, g);
10015 
10016  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
10017  get(boost::edge_reverse, g);
10018 
10019  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
10020  residual_capacity = get(boost::edge_residual_capacity, g);
10021 
10022  bool in1;
10023  Graph_d::edge_descriptor e1, e2, e3, e4;
10024  Graph_d::vertex_descriptor vSource, vSink;
10025  int numVert = 0;
10026  int numLabels = 0;
10027 
10028  std::cout << "build graph vertices" << std::endl;
10029  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10030  ++it) // for all pixels in imIn create a vertex
10031  {
10032  o0 = it.getOffset();
10033  int val2 = imMarker.pixelFromOffset(o0);
10034 
10035  imOut.setPixel(o0, 1);
10036 
10037  if (val2 > numLabels) {
10038  numLabels = val2;
10039  }
10040 
10041  boost::add_vertex(g);
10042  numVert++;
10043  }
10044 
10045  std::cout << "number of Labels: " << numLabels << std::endl;
10046 
10047  std::cout << "number of vertices: " << numVert << std::endl;
10048 
10049  vSource = boost::add_vertex(g);
10050  vSink = boost::add_vertex(g);
10051 
10052  std::cout << "build graph edges" << std::endl;
10053  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10054  ++it) // for all pixels in imIn create a vertex and an edge
10055  {
10056  o1 = it.getOffset();
10057  double val = imIn.pixelFromOffset(o1);
10058 
10059  neighb.setCenter(o1);
10060 
10061  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
10062  const offset_t o2 = nit.getOffset();
10063  if (o2 <= o1)
10064  continue;
10065  if (o2 > o1) {
10066  double val2 = imIn.pixelFromOffset(o2);
10067  double cost = 10000 / (1 + 1.5 * (val - val2) * (val - val2));
10068  // std::cout<<cost<<std::endl;
10069 
10070  // double cost = std::exp(-((val-val2)*(val-val2))/(1.0));
10071  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
10072  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
10073  capacity[e4] = cost + 1;
10074  capacity[e3] = cost + 1;
10075  rev[e4] = e3;
10076  rev[e3] = e4;
10077  }
10078  }
10079  }
10080 
10081  for (int nbk = 2; nbk <= numLabels; nbk++) {
10082  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10083  ++it) // for all pixels in imIn create a vertex
10084  {
10085  o0 = it.getOffset();
10086  int val = imMarker.pixelFromOffset(o0);
10087 
10088  if (val == nbk) {
10089  boost::tie(e4, in1) = boost::edge(vSource, o0, g);
10090  if (in1 == 0) {
10091  boost::tie(e4, in1) = boost::add_edge(vSource, o0, g);
10092  boost::tie(e3, in1) = boost::add_edge(o0, vSource, g);
10093  capacity[e4] = (std::numeric_limits<double>::max)();
10094  capacity[e3] = (std::numeric_limits<double>::max)();
10095  rev[e4] = e3;
10096  rev[e3] = e4;
10097  }
10098  } else if (val > 1 && val != nbk) {
10099  boost::tie(e4, in1) = boost::edge(o0, vSink, g);
10100  if (in1 == 0) {
10101  boost::tie(e4, in1) = boost::add_edge(o0, vSink, g);
10102  boost::tie(e3, in1) = boost::add_edge(vSink, o0, g);
10103  capacity[e4] = (std::numeric_limits<double>::max)();
10104  capacity[e3] = (std::numeric_limits<double>::max)();
10105  rev[e4] = e3;
10106  rev[e3] = e4;
10107  }
10108  }
10109  }
10110 
10111  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
10112  boost::get(boost::vertex_index, g);
10113  std::vector<boost::default_color_type> color(boost::num_vertices(g));
10114 
10115  std::cout << "Compute Max flow" << std::endl;
10116 #if BOOST_VERSION >= 104700
10117  double flow =
10118  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
10119  &color[0], indexmap, vSource, vSink);
10120 #else
10121  double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
10122  &color[0], indexmap, vSource, vSink);
10123 #endif
10124  std::cout << "c The total flow:" << std::endl;
10125  std::cout << "s " << flow << std::endl << std::endl;
10126 
10127  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10128  ++it) // for all pixels in imIn create a vertex and an edge
10129  {
10130  o1 = it.getOffset();
10131  int val = imIn.pixelFromOffset(o1);
10132  int val2 = imOut.pixelFromOffset(o1);
10133  int val3 = imMarker.pixelFromOffset(o1);
10134 
10135  if (val2 == 1) {
10136  if (color[o1] == color[vSource])
10137  imOut.setPixel(o1, nbk);
10138  }
10139 
10140  if (val3 == nbk) {
10141  boost::tie(e4, in1) = boost::edge(vSource, o1, g);
10142  if (in1 == 1) {
10143  boost::remove_edge(vSource, o1, g);
10144  boost::remove_edge(o1, vSource, g);
10145  }
10146  } else if (val3 > 1 && val3 != nbk) {
10147  boost::tie(e4, in1) = boost::edge(o1, vSink, g);
10148  if (in1 == 1) {
10149  boost::remove_edge(o1, vSink, g);
10150  boost::remove_edge(vSink, o1, g);
10151  }
10152  }
10153  }
10154  }
10155 
10156  return RES_OK;
10157  }
10158 
10159  template <class ImageIn, class ImageMarker, typename _Power, class SE,
10160  class ImageOut>
10161  RES_C t_geoCutsMultiway_Watershed(const ImageIn &imIn,
10162  const ImageMarker &imMarker,
10163  const _Power Power, const SE &nl,
10164  ImageOut &imOut)
10165  {
10166  MORPHEE_ENTER_FUNCTION("t_geoCutsMultiway_Watershed");
10167 
10168  std::cout << "Enter function Multi way watershed" << std::endl;
10169 
10170  if ((!imOut.isAllocated())) {
10171  MORPHEE_REGISTER_ERROR("Not allocated");
10172  return RES_NOT_ALLOCATED;
10173  }
10174 
10175  if ((!imIn.isAllocated())) {
10176  MORPHEE_REGISTER_ERROR("Not allocated");
10177  return RES_NOT_ALLOCATED;
10178  }
10179 
10180  if ((!imMarker.isAllocated())) {
10181  MORPHEE_REGISTER_ERROR("Not allocated");
10182  return RES_NOT_ALLOCATED;
10183  }
10184 
10185  double exposant = (double) Power;
10186  // common image iterator
10187  typename ImageIn::const_iterator it, iend;
10188  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
10189  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
10190  offset_t o0;
10191  offset_t o1;
10192 
10193  // needed for max flow: capacit map, rev_capacity map, etc.
10194  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
10195  boost::directedS>
10196  Traits;
10197  typedef boost::adjacency_list<
10198  boost::listS, boost::vecS, boost::directedS,
10199  boost::property<boost::vertex_name_t, std::string>,
10200  boost::property<
10201  boost::edge_capacity_t, double,
10202  boost::property<boost::edge_residual_capacity_t, double,
10203  boost::property<boost::edge_reverse_t,
10204  Traits::edge_descriptor>>>>
10205  Graph_d;
10206 
10207  Graph_d g;
10208 
10209  double sigma = 1.0;
10210 
10211  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
10212  boost::get(boost::edge_capacity, g);
10213 
10214  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
10215  get(boost::edge_reverse, g);
10216 
10217  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
10218  residual_capacity = get(boost::edge_residual_capacity, g);
10219 
10220  bool in1;
10221  Graph_d::edge_descriptor e1, e2, e3, e4;
10222  Graph_d::vertex_descriptor vSource, vSink;
10223  int numVert = 0;
10224  int numLabels = 0;
10225 
10226  std::cout << "build graph vertices" << std::endl;
10227  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10228  ++it) // for all pixels in imIn create a vertex
10229  {
10230  o0 = it.getOffset();
10231  int val2 = imMarker.pixelFromOffset(o0);
10232 
10233  imOut.setPixel(o0, 1);
10234 
10235  if (val2 > numLabels) {
10236  numLabels = val2;
10237  }
10238 
10239  boost::add_vertex(g);
10240  numVert++;
10241  }
10242 
10243  std::cout << "number of Labels: " << numLabels << std::endl;
10244 
10245  std::cout << "number of vertices: " << numVert << std::endl;
10246 
10247  vSource = boost::add_vertex(g);
10248  vSink = boost::add_vertex(g);
10249 
10250  std::cout << "build graph edges" << std::endl;
10251  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10252  ++it) // for all pixels in imIn create a vertex and an edge
10253  {
10254  o1 = it.getOffset();
10255  double val = imIn.pixelFromOffset(o1);
10256 
10257  neighb.setCenter(o1);
10258 
10259  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
10260  const offset_t o2 = nit.getOffset();
10261  if (o2 <= o1)
10262  continue;
10263  if (o2 > o1) {
10264  double val2 = imIn.pixelFromOffset(o2);
10265  double valeur = (255.0 / (std::abs(val - val2) + 1));
10266  double cost = std::pow(valeur, exposant);
10267 
10268  // double cost = std::exp(-((val-val2)*(val-val2))/(1.0));
10269  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
10270  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
10271  capacity[e4] = cost;
10272  capacity[e3] = cost;
10273  rev[e4] = e3;
10274  rev[e3] = e4;
10275  }
10276  }
10277  }
10278 
10279  for (int nbk = 2; nbk <= numLabels; nbk++) {
10280  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10281  ++it) // for all pixels in imIn create a vertex
10282  {
10283  o0 = it.getOffset();
10284  int val = imMarker.pixelFromOffset(o0);
10285 
10286  double cost = (std::numeric_limits<double>::max)();
10287 
10288  if (val == nbk) {
10289  boost::tie(e4, in1) = boost::edge(vSource, o0, g);
10290  if (in1 == 0) {
10291  boost::tie(e4, in1) = boost::add_edge(vSource, o0, g);
10292  boost::tie(e3, in1) = boost::add_edge(o0, vSource, g);
10293  capacity[e4] = cost;
10294  capacity[e3] = cost;
10295  rev[e4] = e3;
10296  rev[e3] = e4;
10297  }
10298  } else if (val > 1 && val != nbk) {
10299  boost::tie(e4, in1) = boost::edge(o0, vSink, g);
10300  if (in1 == 0) {
10301  boost::tie(e4, in1) = boost::add_edge(o0, vSink, g);
10302  boost::tie(e3, in1) = boost::add_edge(vSink, o0, g);
10303  capacity[e4] = cost;
10304  capacity[e3] = cost;
10305  rev[e4] = e3;
10306  rev[e3] = e4;
10307  }
10308  }
10309  }
10310 
10311  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
10312  boost::get(boost::vertex_index, g);
10313  std::vector<boost::default_color_type> color(boost::num_vertices(g));
10314 
10315  std::cout << "Compute Max flow" << std::endl;
10316 #if BOOST_VERSION >= 104700
10317  double flow =
10318  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
10319  &color[0], indexmap, vSource, vSink);
10320 #else
10321  double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
10322  &color[0], indexmap, vSource, vSink);
10323 #endif
10324  std::cout << "c The total flow:" << std::endl;
10325  std::cout << "s " << flow << std::endl << std::endl;
10326 
10327  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10328  ++it) // for all pixels in imIn create a vertex and an edge
10329  {
10330  o1 = it.getOffset();
10331  int val = imIn.pixelFromOffset(o1);
10332  int val2 = imOut.pixelFromOffset(o1);
10333  int val3 = imMarker.pixelFromOffset(o1);
10334 
10335  if (val2 == 1) {
10336  if (color[o1] == color[vSource])
10337  imOut.setPixel(o1, nbk);
10338  }
10339 
10340  if (val3 == nbk) {
10341  boost::tie(e4, in1) = boost::edge(vSource, o1, g);
10342  if (in1 == 1) {
10343  boost::remove_edge(vSource, o1, g);
10344  boost::remove_edge(o1, vSource, g);
10345  }
10346  } else if (val3 > 1 && val3 != nbk) {
10347  boost::tie(e4, in1) = boost::edge(o1, vSink, g);
10348  if (in1 == 1) {
10349  boost::remove_edge(o1, vSink, g);
10350  boost::remove_edge(vSink, o1, g);
10351  }
10352  }
10353  }
10354  }
10355 
10356  return RES_OK;
10357  }
10358 
10359  template <class ImageIn, class ImageMarker, typename _Beta, typename _Sigma,
10360  class SE, class ImageOut>
10361  RES_C t_MAP_MRF_Ising(const ImageIn &imIn, const ImageMarker &imMarker,
10362  const _Beta Beta, const _Sigma Sigma, const SE &nl,
10363  ImageOut &imOut)
10364  {
10365  MORPHEE_ENTER_FUNCTION("t_MAP_MRF_Ising");
10366 
10367  std::cout << "Enter function t_MAP_MRF_Ising" << std::endl;
10368 
10369  if ((!imOut.isAllocated())) {
10370  MORPHEE_REGISTER_ERROR("Not allocated");
10371  return RES_NOT_ALLOCATED;
10372  }
10373 
10374  if ((!imIn.isAllocated())) {
10375  MORPHEE_REGISTER_ERROR("Not allocated");
10376  return RES_NOT_ALLOCATED;
10377  }
10378 
10379  if ((!imMarker.isAllocated())) {
10380  MORPHEE_REGISTER_ERROR("Not allocated");
10381  return RES_NOT_ALLOCATED;
10382  }
10383 
10384  // common image iterator
10385  typename ImageIn::const_iterator it, iend;
10386  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
10387  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
10388  offset_t o0;
10389  offset_t o1;
10390 
10391  // needed for max flow: capacit map, rev_capacity map, etc.
10392  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
10393  boost::directedS>
10394  Traits;
10395  typedef boost::adjacency_list<
10396  boost::listS, boost::vecS, boost::directedS,
10397  boost::property<boost::vertex_name_t, std::string>,
10398  boost::property<
10399  boost::edge_capacity_t, double,
10400  boost::property<boost::edge_residual_capacity_t, double,
10401  boost::property<boost::edge_reverse_t,
10402  Traits::edge_descriptor>>>>
10403  Graph_d;
10404 
10405  Graph_d g;
10406 
10407  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
10408  boost::get(boost::edge_capacity, g);
10409 
10410  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
10411  get(boost::edge_reverse, g);
10412 
10413  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
10414  residual_capacity = get(boost::edge_residual_capacity, g);
10415 
10416  bool in1;
10417  Graph_d::edge_descriptor e1, e2, e3, e4;
10418  Graph_d::vertex_descriptor vSource, vSink;
10419  int numVert = 0;
10420 
10421  double moy_foreground = 0;
10422  double moy_background = 0;
10423  double nb_foreground = 0;
10424  double nb_background = 0;
10425 
10426  double mean_image = 0;
10427  double nb_pixels = 0;
10428 
10429  std::cout << "build graph vertices" << std::endl;
10430  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10431  ++it) // for all pixels in imIn create a vertex
10432  {
10433  o0 = it.getOffset();
10434  int valmarker = imMarker.pixelFromOffset(o0);
10435  int val = imIn.pixelFromOffset(o0);
10436  boost::add_vertex(g);
10437  numVert++;
10438 
10439  if (valmarker == 2) {
10440  moy_foreground = moy_foreground + val;
10441  nb_foreground++;
10442  } else if (valmarker == 3) {
10443  moy_background = moy_background + val;
10444  nb_background++;
10445  }
10446 
10447  mean_image = mean_image + val;
10448  nb_pixels++;
10449  }
10450 
10451  mean_image = mean_image / nb_pixels;
10452  moy_foreground = moy_foreground / nb_foreground;
10453  moy_background = moy_background / nb_background;
10454  moy_foreground = moy_foreground / 255.0;
10455  moy_background = moy_background / 255.0;
10456 
10457  std::cout << "number of vertices: " << numVert << std::endl;
10458  std::cout << "Foreground Mean: " << moy_foreground << std::endl;
10459  std::cout << "Background Mean: " << moy_background << std::endl;
10460 
10461  vSource = boost::add_vertex(g);
10462  vSink = boost::add_vertex(g);
10463 
10464  std::cout << "build graph edges" << std::endl;
10465  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10466  ++it) // for all pixels in imIn create a vertex and an edge
10467  {
10468  o1 = it.getOffset();
10469 
10470  double val1 = imIn.pixelFromOffset(o1);
10471  int valmarker = imMarker.pixelFromOffset(o1);
10472 
10473  neighb.setCenter(o1);
10474 
10475  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
10476  const offset_t o2 = nit.getOffset();
10477 
10478  if (o2 <= o1)
10479  continue;
10480  if (o2 > o1) {
10481  double cost = (double) Beta;
10482  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
10483  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
10484  capacity[e4] = cost;
10485  capacity[e3] = cost;
10486  rev[e4] = e3;
10487  rev[e3] = e4;
10488  }
10489  }
10490 
10491  if (valmarker == 2) {
10492  boost::tie(e4, in1) = boost::add_edge(o1, vSink, g);
10493  boost::tie(e3, in1) = boost::add_edge(vSink, o1, g);
10494  capacity[e4] = (std::numeric_limits<double>::max)();
10495  capacity[e3] = (std::numeric_limits<double>::max)();
10496  rev[e4] = e3;
10497  rev[e3] = e4;
10498  } else if (valmarker == 3) {
10499  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
10500  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
10501  capacity[e4] = (std::numeric_limits<double>::max)();
10502  capacity[e3] = (std::numeric_limits<double>::max)();
10503  rev[e4] = e3;
10504  rev[e3] = e4;
10505  } else {
10506  val1 = val1 / 255.0;
10507 
10508  double sigma = (double) Sigma;
10509 
10510  double sigmab = 0.2;
10511 
10512  double slink = (val1 - moy_foreground) * (val1 - moy_foreground) /
10513  (2 * sigma * sigma);
10514  double tlink = (val1 - moy_background) * (val1 - moy_background) /
10515  (2 * sigmab * sigmab);
10516 
10517  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
10518  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
10519  capacity[e4] = slink;
10520  capacity[e3] = slink;
10521  rev[e4] = e3;
10522  rev[e3] = e4;
10523 
10524  boost::tie(e4, in1) = boost::add_edge(o1, vSink, g);
10525  boost::tie(e3, in1) = boost::add_edge(vSink, o1, g);
10526  capacity[e4] = tlink;
10527  capacity[e3] = tlink;
10528  rev[e4] = e3;
10529  rev[e3] = e4;
10530  }
10531  }
10532 
10533  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
10534  boost::get(boost::vertex_index, g);
10535  std::vector<boost::default_color_type> color(boost::num_vertices(g));
10536 
10537  std::cout << "Compute Max flow" << std::endl;
10538 #if BOOST_VERSION >= 104700
10539  double flow =
10540  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
10541  &color[0], indexmap, vSource, vSink);
10542 #else
10543  double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
10544  &color[0], indexmap, vSource, vSink);
10545 #endif
10546  std::cout << "c The total flow:" << std::endl;
10547  std::cout << "s " << flow << std::endl << std::endl;
10548 
10549  std::cout << "Source Label:" << color[vSource] << std::endl;
10550  std::cout << "Sink Label:" << color[vSink] << std::endl;
10551 
10552  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10553  ++it) // for all pixels in imIn create a vertex and an edge
10554  {
10555  o1 = it.getOffset();
10556  if (color[o1] == color[vSource])
10557  imOut.setPixel(o1, 3);
10558  else if (color[o1] == color[vSink])
10559  imOut.setPixel(o1, 2);
10560  else if (color[o1] == 1)
10561  imOut.setPixel(o1, 4);
10562  }
10563 
10564  return RES_OK;
10565  }
10566 
10567  template <class ImageIn, class ImageMarker, typename _Beta, typename _Sigma,
10568  class SE, class ImageOut>
10569  RES_C t_MAP_MRF_edge_preserving(const ImageIn &imIn,
10570  const ImageMarker &imMarker,
10571  const _Beta Beta, const _Sigma Sigma,
10572  const SE &nl, ImageOut &imOut)
10573  {
10574  MORPHEE_ENTER_FUNCTION("t_MAP_MRF_edge_preserving");
10575 
10576  std::cout << "Enter function t_MAP_MRF_edge_preserving" << std::endl;
10577 
10578  if ((!imOut.isAllocated())) {
10579  MORPHEE_REGISTER_ERROR("Not allocated");
10580  return RES_NOT_ALLOCATED;
10581  }
10582 
10583  if ((!imIn.isAllocated())) {
10584  MORPHEE_REGISTER_ERROR("Not allocated");
10585  return RES_NOT_ALLOCATED;
10586  }
10587 
10588  if ((!imMarker.isAllocated())) {
10589  MORPHEE_REGISTER_ERROR("Not allocated");
10590  return RES_NOT_ALLOCATED;
10591  }
10592 
10593  // common image iterator
10594  typename ImageIn::const_iterator it, iend;
10595  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
10596  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
10597  offset_t o0;
10598  offset_t o1;
10599 
10600  // needed for max flow: capacit map, rev_capacity map, etc.
10601  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
10602  boost::directedS>
10603  Traits;
10604  typedef boost::adjacency_list<
10605  boost::listS, boost::vecS, boost::directedS,
10606  boost::property<boost::vertex_name_t, std::string>,
10607  boost::property<
10608  boost::edge_capacity_t, double,
10609  boost::property<boost::edge_residual_capacity_t, double,
10610  boost::property<boost::edge_reverse_t,
10611  Traits::edge_descriptor>>>>
10612  Graph_d;
10613 
10614  Graph_d g;
10615 
10616  double sigma = Sigma;
10617 
10618  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
10619  boost::get(boost::edge_capacity, g);
10620 
10621  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
10622  get(boost::edge_reverse, g);
10623 
10624  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
10625  residual_capacity = get(boost::edge_residual_capacity, g);
10626 
10627  bool in1;
10628  Graph_d::edge_descriptor e1, e2, e3, e4;
10629  Graph_d::vertex_descriptor vSource, vSink;
10630  int numVert = 0;
10631 
10632  double moy_foreground = 0;
10633  double moy_background = 0;
10634  double nb_foreground = 0;
10635  double nb_background = 0;
10636 
10637  double mean_image = 0;
10638  double nb_pixels = 0;
10639 
10640  double mean_difference = 0;
10641  double nb_difference = 0;
10642 
10643  std::cout << "build graph vertices" << std::endl;
10644  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10645  ++it) // for all pixels in imIn create a vertex
10646  {
10647  o0 = it.getOffset();
10648  int valmarker = imMarker.pixelFromOffset(o0);
10649  int val = imIn.pixelFromOffset(o0);
10650  boost::add_vertex(g);
10651  numVert++;
10652 
10653  if (valmarker == 2) {
10654  moy_foreground = moy_foreground + val;
10655  nb_foreground++;
10656  } else if (valmarker == 3) {
10657  moy_background = moy_background + val;
10658  nb_background++;
10659  }
10660 
10661  mean_image = mean_image + val;
10662  nb_pixels++;
10663 
10664  neighb.setCenter(o0);
10665  double vall1 = (double) val / 255.0;
10666 
10667  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
10668  const offset_t o2 = nit.getOffset();
10669  double val2 = imIn.pixelFromOffset(o2);
10670 
10671  if (o2 <= o0)
10672  continue;
10673  if (o2 > o0) {
10674  double vall2 = (double) val2 / 255.0;
10675  mean_difference =
10676  mean_difference + (vall2 - vall1) * (vall2 - vall1);
10677  nb_difference++;
10678  }
10679  }
10680  }
10681 
10682  mean_difference = mean_difference / nb_difference;
10683  mean_image = mean_image / nb_pixels;
10684 
10685  moy_foreground = moy_foreground / nb_foreground;
10686  moy_background = moy_background / nb_background;
10687  moy_foreground = moy_foreground / 255.0;
10688  moy_background = moy_background / 255.0;
10689 
10690  std::cout << "number of vertices: " << numVert << std::endl;
10691  std::cout << "Foreground Mean: " << moy_foreground << std::endl;
10692  std::cout << "Background Mean: " << moy_background << std::endl;
10693  std::cout << "Mean difference : " << mean_difference << std::endl;
10694 
10695  vSource = boost::add_vertex(g);
10696  vSink = boost::add_vertex(g);
10697 
10698  std::cout << "build graph edges" << std::endl;
10699  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10700  ++it) // for all pixels in imIn create a vertex and an edge
10701  {
10702  o1 = it.getOffset();
10703  double val1 = imIn.pixelFromOffset(o1);
10704  int valmarker = imMarker.pixelFromOffset(o1);
10705  val1 = val1 / 255;
10706 
10707  neighb.setCenter(o1);
10708 
10709  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
10710  const offset_t o2 = nit.getOffset();
10711  double val2 = imIn.pixelFromOffset(o2);
10712  val2 = val2 / 255;
10713 
10714  if (o2 <= o1)
10715  continue;
10716  if (o2 > o1) {
10717  // double cost = (double) Beta *
10718  // std::exp(-((val1-val2)*(val1-val2))/(2*mean_difference)) ;
10719  double cost =
10720  (double) Beta -
10721  ((double) Beta) * std::pow(std::abs(val1 - val2), 0.25);
10722  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
10723  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
10724  capacity[e4] = cost;
10725  capacity[e3] = cost;
10726  rev[e4] = e3;
10727  rev[e3] = e4;
10728  }
10729  }
10730 
10731  if (valmarker == 2) {
10732  boost::tie(e4, in1) = boost::add_edge(o1, vSink, g);
10733  boost::tie(e3, in1) = boost::add_edge(vSink, o1, g);
10734  capacity[e4] = (std::numeric_limits<double>::max)();
10735  capacity[e3] = (std::numeric_limits<double>::max)();
10736  rev[e4] = e3;
10737  rev[e3] = e4;
10738  } else if (valmarker == 3) {
10739  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
10740  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
10741  capacity[e4] = (std::numeric_limits<double>::max)();
10742  capacity[e3] = (std::numeric_limits<double>::max)();
10743  rev[e4] = e3;
10744  rev[e3] = e4;
10745  } else {
10746  double sigma = Sigma;
10747  double sigmab = 0.2;
10748 
10749  double val_f = (val1 - moy_foreground) * (val1 - moy_foreground) /
10750  (2 * sigma * sigma);
10751  double val_b = (val1 - moy_background) * (val1 - moy_background) /
10752  (2 * sigmab * sigmab);
10753 
10754  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
10755  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
10756  capacity[e4] = val_f;
10757  capacity[e3] = val_f;
10758  rev[e4] = e3;
10759  rev[e3] = e4;
10760 
10761  boost::tie(e4, in1) = boost::add_edge(o1, vSink, g);
10762  boost::tie(e3, in1) = boost::add_edge(vSink, o1, g);
10763  capacity[e4] = val_b;
10764  capacity[e3] = val_b;
10765  rev[e4] = e3;
10766  rev[e3] = e4;
10767  }
10768  }
10769 
10770  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
10771  boost::get(boost::vertex_index, g);
10772  std::vector<boost::default_color_type> color(boost::num_vertices(g));
10773 
10774  std::cout << "Compute Max flow" << std::endl;
10775 #if BOOST_VERSION >= 104700
10776  double flow =
10777  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
10778  &color[0], indexmap, vSource, vSink);
10779 #else
10780  double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
10781  &color[0], indexmap, vSource, vSink);
10782 #endif
10783  std::cout << "c The total flow:" << std::endl;
10784  std::cout << "s " << flow << std::endl << std::endl;
10785 
10786  std::cout << "Source Label:" << color[vSource] << std::endl;
10787  std::cout << "Sink Label:" << color[vSink] << std::endl;
10788 
10789  for (it = imIn.begin(), iend = imIn.end(); it != iend;
10790  ++it) // for all pixels in imIn create a vertex and an edge
10791  {
10792  o1 = it.getOffset();
10793  if (color[o1] == color[vSource])
10794  imOut.setPixel(o1, 3);
10795  else if (color[o1] == color[vSink])
10796  imOut.setPixel(o1, 2);
10797  else if (color[o1] == 1)
10798  imOut.setPixel(o1, 4);
10799  }
10800 
10801  return RES_OK;
10802  }
10803 
10804  // template<class ImageIn,class ImageMarker, class SE, class ImageOut >
10805  // RES_C t_MAP_MRF_Potts(const ImageIn& imIn, const ImageMarker& imMarker,
10806  //const SE& nl, ImageOut &imOut)
10807  //{
10808  // MORPHEE_ENTER_FUNCTION("t_MAP_MRF_Potts");
10809  // std::cout << "Enter function t_MAP_MRF_Potts" << std::endl;
10810 
10811  // if( (!imOut.isAllocated()) )
10812  // {
10813  // MORPHEE_REGISTER_ERROR("Not allocated");
10814  // return RES_NOT_ALLOCATED;
10815  // }
10816 
10817  // if( (!imIn.isAllocated()) )
10818  // {
10819  // MORPHEE_REGISTER_ERROR("Not allocated");
10820  // return RES_NOT_ALLOCATED;
10821  // }
10822 
10823  // if( (!imMarker.isAllocated()) )
10824  // {
10825  // MORPHEE_REGISTER_ERROR("Not allocated");
10826  // return RES_NOT_ALLOCATED;
10827  // }
10828 
10829  // //common image iterator
10830  // typename ImageIn::const_iterator it, iend;
10831  // morphee::selement::Neighborhood<SE, ImageIn > neighb(imIn,nl);
10832  // typename morphee::selement::Neighborhood<SE, ImageIn >::iterator
10833  //nit,nend; offset_t o0; offset_t o1;
10834 
10835  // //needed for max flow: capacit map, rev_capacity map, etc.
10836  // typedef
10837  //boost::adjacency_list_traits<boost::vecS,boost::vecS,boost::directedS>
10838  //Traits; typedef
10839  //boost::adjacency_list<boost::listS,boost::vecS,boost::directedS,
10840  // boost::property<boost::vertex_name_t, std::string>,
10841  // boost::property<boost::edge_capacity_t, double,
10842  // boost::property<boost::edge_residual_capacity_t, double,
10843  // boost::property<boost::edge_reverse_t, Traits::edge_descriptor> > > >
10844  //Graph_d;
10845 
10846  // Graph_d::edge_descriptor e1,e2,e3,e4;
10847  // Graph_d::vertex_descriptor vSource,vSink;
10848  // int nb_combi = 3;
10849  // bool in1, in2;
10850  // double sigma[3][2];
10851  // sigma[0][0] = 0.5 ;
10852  // sigma[0][1] = 0.5 ;
10853 
10854  // sigma[1][0] = 0.5 ;
10855  // sigma[1][1] = 0.5 ;
10856 
10857  // sigma[2][0] = 0.5 ;
10858  // sigma[2][1] = 0.5 ;
10859 
10860  // double combi_valeur[3][2];
10861  // combi_valeur[0][0] = 1.0 ;
10862  // combi_valeur[0][1] = 0.75 ;
10863 
10864  // combi_valeur[1][0] = 0.75 ;
10865  // combi_valeur[1][1] = 0.5 ;
10866 
10867  // combi_valeur[2][0] = 0.5 ;
10868  // combi_valeur[2][1] = 0.0 ;
10869 
10870  // double combi_label[3][2];
10871  // combi_label[0][0] = 4 ;
10872  // combi_label[0][1] = 3 ;
10873 
10874  // combi_label[1][0] = 3 ;
10875  // combi_label[1][1] = 2 ;
10876 
10877  // combi_label[2][0] = 2 ;
10878  // combi_label[2][1] = 1 ;
10879 
10880  // for(int nbk=0;nbk<nb_combi;nbk++){
10881 
10882  // Graph_d g;
10883 
10884  // boost::property_map<Graph_d, boost::edge_capacity_t>::type
10885  // capacity = boost::get(boost::edge_capacity, g);
10886 
10887  // boost::property_map<Graph_d, boost::edge_reverse_t>::type
10888  // rev = get(boost::edge_reverse, g);
10889 
10890  // boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
10891  // residual_capacity = get(boost::edge_residual_capacity, g);
10892 
10893  // std::cout<<"build graph vertices"<<std::endl;
10894  // int numVert = 0;
10895 
10896  // for(it=imIn.begin(),iend=imIn.end();it!=iend ; ++it) // for all pixels
10897  //in imIn create a vertex
10898  // {
10899  // o0=it.getOffset();
10900  // int val = imIn.pixelFromOffset(o0);
10901  // boost::add_vertex(g);
10902  // numVert++;
10903  // if(nbk==0){
10904  // imOut.setPixel(o0,0);
10905  // }
10906  // }
10907 
10908  // vSource = boost::add_vertex(g);
10909  // vSink = boost::add_vertex(g);
10910 
10911  // std::cout<<"build graph edges"<<std::endl;
10912  // boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
10913  //boost::get(boost::vertex_index, g); std::vector<boost::default_color_type>
10914  //color(boost::num_vertices(g)); std::cout<<"build neighborhood edges and
10915  //terminal links"<<std::endl; for(it=imIn.begin(),iend=imIn.end(); it!=iend
10916  //; ++it) // for all pixels in imIn create a vertex and an edge
10917  // {
10918  // o1=it.getOffset();
10919  // neighb.setCenter(o1);
10920  // double valCenter = imOut.pixelFromOffset(o1);
10921  // double val = 0;
10922  // double nbval = 0;
10923 
10924  // for(nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit)
10925  // {
10926  // const offset_t o2 = nit.getOffset();
10927  // double val2 = imIn.pixelFromOffset(o2);
10928  // val = val + val2;
10929  // nbval++;
10930  // if(o2<=o1) continue;
10931  // if(o2>o1 && (valCenter == 0 || valCenter == combi_label[nbk][1] ||
10932  //valCenter == combi_label[nbk][0]) ){ double cost = 0.01; boost::tie(e4,
10933  //in1) = boost::add_edge(o1,o2, g); boost::tie(e3, in1) =
10934  //boost::add_edge(o2,o1, g); capacity[e4] = cost; capacity[e3] = cost;
10935  // rev[e4] = e3;
10936  // rev[e3] = e4;
10937  // }
10938  // }
10939 
10940  // if(valCenter == 0 || valCenter == combi_label[nbk][1] || valCenter
10941  //== combi_label[nbk][0]){ val = val/nbval; double valee = val/255; double
10942  //val1 = (valee - combi_valeur[nbk][0])*(valee -
10943  //combi_valeur[nbk][0])/(2*sigma[nbk][0]*sigma[nbk][0]); double val2 =
10944  //(valee - combi_valeur[nbk][1])*(valee -
10945  //combi_valeur[nbk][1])/(2*sigma[nbk][1]*sigma[nbk][1]);
10946  //
10947  // boost::tie(e4, in1) = boost::add_edge(vSource,o1,g);
10948  // boost::tie(e3, in1) = boost::add_edge(o1,vSource,g);
10949  // capacity[e4] = val1;
10950  // capacity[e3] = val1;
10951  // rev[e4] = e3;
10952  // rev[e3] = e4;
10953 
10954  // boost::tie(e4, in1) = boost::add_edge(vSink,o1,g);
10955  // boost::tie(e3, in1) = boost::add_edge(o1,vSink,g);
10956  // capacity[e4] = val2;
10957  // capacity[e3] = val2;
10958  // rev[e4] = e3;
10959  // rev[e3] = e4;
10960  // }
10961  // }
10962 
10963  // std::cout << "Compute Max flow" << std::endl;
10964  // double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
10965  //&color[0], indexmap, vSource, vSink); std::cout << "c The total flow:" <<
10966  //std::endl; std::cout << "s " << flow << std::endl << std::endl;
10967 
10968  // std::cout << "Source Label:" <<color[vSource]<< std::endl;
10969  // std::cout << "Sink Label:" <<color[vSink]<< std::endl;
10970 
10971  // for (unsigned int i=0;i<numVert;i++)
10972  // {
10973  // int valimout = imOut.pixelFromOffset(i);
10974 
10975  // if( valimout == 0 || valimout == combi_label[nbk][1] || valimout ==
10976  //combi_label[nbk][0]){ if(color[i]==0)
10977  // imOut.setPixel(i,combi_label[nbk][1]);
10978  // if(color[i]==4)
10979  // imOut.setPixel(i,combi_label[nbk][0]);
10980  // }
10981  // }
10982 
10983  // }
10984 
10985  // return RES_OK;
10986  //}
10987 
10988  template <class ImageIn, class ImageMarker, typename _Beta, typename _Sigma,
10989  class SE, class ImageOut>
10990  RES_C t_MAP_MRF_Potts(const ImageIn &imIn, const ImageMarker &imMarker,
10991  const _Beta Beta, const _Sigma Sigma, const SE &nl,
10992  ImageOut &imOut)
10993  {
10994  MORPHEE_ENTER_FUNCTION("t_MAP_MRF_Potts");
10995  std::cout << "Enter function t_MAP_MRF_Potts" << std::endl;
10996 
10997  if ((!imOut.isAllocated())) {
10998  MORPHEE_REGISTER_ERROR("Not allocated");
10999  return RES_NOT_ALLOCATED;
11000  }
11001 
11002  if ((!imIn.isAllocated())) {
11003  MORPHEE_REGISTER_ERROR("Not allocated");
11004  return RES_NOT_ALLOCATED;
11005  }
11006 
11007  if ((!imMarker.isAllocated())) {
11008  MORPHEE_REGISTER_ERROR("Not allocated");
11009  return RES_NOT_ALLOCATED;
11010  }
11011 
11012  // common image iterator
11013  typename ImageIn::const_iterator it, iend;
11014  morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
11015  typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
11016  offset_t o0;
11017  offset_t o1;
11018 
11019  // needed for max flow: capacit map, rev_capacity map, etc.
11020  typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
11021  boost::directedS>
11022  Traits;
11023  typedef boost::adjacency_list<
11024  boost::listS, boost::vecS, boost::directedS,
11025  boost::property<boost::vertex_name_t, std::string>,
11026  boost::property<
11027  boost::edge_capacity_t, double,
11028  boost::property<boost::edge_residual_capacity_t, double,
11029  boost::property<boost::edge_reverse_t,
11030  Traits::edge_descriptor>>>>
11031  Graph_d;
11032 
11033  Graph_d::edge_descriptor e1, e2, e3, e4;
11034  Graph_d::vertex_descriptor vSource, vSink;
11035  int nb_combi = 4;
11036 
11037  bool in1;
11038  double sigma[4][2];
11039  sigma[0][0] = Sigma;
11040  sigma[0][1] = Sigma;
11041 
11042  sigma[1][0] = Sigma;
11043  sigma[1][1] = Sigma;
11044 
11045  sigma[2][0] = Sigma;
11046  sigma[2][1] = Sigma;
11047 
11048  sigma[3][0] = Sigma;
11049  sigma[3][1] = Sigma;
11050 
11051  double combi_valeur[4][2];
11052  combi_valeur[0][0] = 1.0;
11053  combi_valeur[0][1] = 0.0;
11054 
11055  combi_valeur[1][0] = 0.75;
11056  combi_valeur[1][1] = 0.0;
11057 
11058  combi_valeur[2][0] = 0.5;
11059  combi_valeur[2][1] = 0.0;
11060 
11061  combi_valeur[3][0] = 0.0;
11062  combi_valeur[3][1] = 0.0;
11063 
11064  double combi_label[4][2];
11065  combi_label[0][0] = 4;
11066  combi_label[0][1] = 0;
11067 
11068  combi_label[1][0] = 3;
11069  combi_label[1][1] = 0;
11070 
11071  combi_label[2][0] = 2;
11072  combi_label[2][1] = 0;
11073 
11074  combi_label[3][0] = 1;
11075  combi_label[3][1] = 0;
11076 
11077  for (int nbk = 0; nbk < nb_combi; nbk++) {
11078  Graph_d g;
11079 
11080  boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
11081  boost::get(boost::edge_capacity, g);
11082 
11083  boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
11084  get(boost::edge_reverse, g);
11085 
11086  boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
11087  residual_capacity = get(boost::edge_residual_capacity, g);
11088 
11089  std::cout << "build graph vertices" << std::endl;
11090  int numVert = 0;
11091 
11092  for (it = imIn.begin(), iend = imIn.end(); it != iend;
11093  ++it) // for all pixels in imIn create a vertex
11094  {
11095  o0 = it.getOffset();
11096  int val = imIn.pixelFromOffset(o0);
11097  boost::add_vertex(g);
11098  numVert++;
11099  if (nbk == 0) {
11100  imOut.setPixel(o0, 0);
11101  }
11102  }
11103 
11104  vSource = boost::add_vertex(g);
11105  vSink = boost::add_vertex(g);
11106 
11107  std::cout << "build graph edges" << std::endl;
11108  boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
11109  boost::get(boost::vertex_index, g);
11110  std::vector<boost::default_color_type> color(boost::num_vertices(g));
11111  std::cout << "build neighborhood edges and terminal links" << std::endl;
11112 
11113  for (it = imIn.begin(), iend = imIn.end(); it != iend;
11114  ++it) // for all pixels in imIn create a vertex and an edge
11115  {
11116  o1 = it.getOffset();
11117  neighb.setCenter(o1);
11118  double valCenter = imOut.pixelFromOffset(o1);
11119  double val1 = imIn.pixelFromOffset(o1);
11120 
11121  for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
11122  const offset_t o2 = nit.getOffset();
11123 
11124  if (o2 <= o1)
11125  continue;
11126  if (o2 > o1) {
11127  double cost = Beta;
11128  boost::tie(e4, in1) = boost::add_edge(o1, o2, g);
11129  boost::tie(e3, in1) = boost::add_edge(o2, o1, g);
11130  capacity[e4] = cost;
11131  capacity[e3] = cost;
11132  rev[e4] = e3;
11133  rev[e3] = e4;
11134  }
11135  }
11136 
11137  val1 = val1 / 255;
11138  val1 = (val1 - combi_valeur[nbk][0]) * (val1 - combi_valeur[nbk][0]) /
11139  (2 * sigma[nbk][0] * sigma[nbk][0]);
11140 
11141  double val2 = 0;
11142  double val3 = 0;
11143  double val4 = 0;
11144 
11145  if (nbk == 0) {
11146  val2 = (val1 - 0.75) * (val1 - 0.75) /
11147  (2 * sigma[nbk][1] * sigma[nbk][1]);
11148  val3 = (val1 - 0.5) * (val1 - 0.5) /
11149  (2 * sigma[nbk][1] * sigma[nbk][1]);
11150  val4 = (val1) * (val1) / (2 * sigma[nbk][1] * sigma[nbk][1]);
11151  } else if (nbk == 1) {
11152  val2 = (val1 - 1.0) * (val1 - 1.0) /
11153  (2 * sigma[nbk][1] * sigma[nbk][1]);
11154  val3 = (val1 - 0.5) * (val1 - 0.5) /
11155  (2 * sigma[nbk][1] * sigma[nbk][1]);
11156  val4 = (val1) * (val1) / (2 * sigma[nbk][1] * sigma[nbk][1]);
11157  } else if (nbk == 2) {
11158  val2 = (val1 - 1.0) * (val1 - 1.0) /
11159  (2 * sigma[nbk][1] * sigma[nbk][1]);
11160  val3 = (val1 - 0.75) * (val1 - 0.75) /
11161  (2 * sigma[nbk][1] * sigma[nbk][1]);
11162  val4 = (val1) * (val1) / (2 * sigma[nbk][1] * sigma[nbk][1]);
11163  } else if (nbk == 3) {
11164  val2 = (val1 - 1.0) * (val1 - 1.0) /
11165  (2 * sigma[nbk][1] * sigma[nbk][1]);
11166  val3 = (val1 - 0.75) * (val1 - 0.75) /
11167  (2 * sigma[nbk][1] * sigma[nbk][1]);
11168  val4 = (val1 - 0.5) * (val1 - 0.5) /
11169  (2 * sigma[nbk][1] * sigma[nbk][1]);
11170  }
11171 
11172  boost::tie(e4, in1) = boost::add_edge(vSource, o1, g);
11173  boost::tie(e3, in1) = boost::add_edge(o1, vSource, g);
11174  capacity[e4] = val1;
11175  capacity[e3] = val1;
11176  rev[e4] = e3;
11177  rev[e3] = e4;
11178 
11179  boost::tie(e4, in1) = boost::add_edge(vSink, o1, g);
11180  boost::tie(e3, in1) = boost::add_edge(o1, vSink, g);
11181  capacity[e4] = std::min(std::min(val2, val3), val4);
11182  capacity[e3] = std::min(std::min(val2, val3), val4);
11183  rev[e4] = e3;
11184  rev[e3] = e4;
11185  }
11186 
11187  std::cout << "Compute Max flow" << std::endl;
11188 #if BOOST_VERSION >= 104700
11189  double flow =
11190  boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
11191  &color[0], indexmap, vSource, vSink);
11192 #else
11193  double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
11194  &color[0], indexmap, vSource, vSink);
11195 #endif
11196  std::cout << "c The total flow:" << std::endl;
11197  std::cout << "s " << flow << std::endl << std::endl;
11198 
11199  std::cout << "Source Label:" << color[vSource] << std::endl;
11200  std::cout << "Sink Label:" << color[vSink] << std::endl;
11201 
11202  for (int i = 0; i < numVert; i++) {
11203  int valimout = imOut.pixelFromOffset(i);
11204 
11205  if (valimout == 0) {
11206  if (color[i] == 4)
11207  imOut.setPixel(i, combi_label[nbk][0]);
11208  }
11209  }
11210  }
11211 
11212  return RES_OK;
11213  }
11214 
11215  } // namespace graphalgo
11216 } // namespace morphee
11217 
11218 #endif // GRAPHALGO_IMPL_T_HPP
RES_T sqrt(const Image< T1 > &imIn, Image< T2 > &imOut)
sqrt() - square root of an image
Definition: DImageArith.hpp:926
RES_T pow(const Image< T1 > &imIn, Image< T2 > &imOut, double exponent=2)
pow() - power of an image
Definition: DImageArith.hpp:905
RES_T test(const Image< T1 > &imIn, const Image< T2 > &imInT, const Image< T2 > &imInF, Image< T2 > &imOut)
test() - Test
Definition: DImageArith.hpp:1109
histogram(const Image< T > &imIn, size_t *h)
Image histogram.
Definition: DImageHistogram.hpp:64
size_t label(const Image< T1 > &imIn, Image< T2 > &imOut, const StrElt &se=DEFAULT_SE)
label() - Image labelization
Definition: DMorphoLabel.hpp:564
double volume(const Image< T > &imIn)
colume() - Volume of an image
Definition: DMeasures.hpp:154
Definition: GeoCutsAlgo_impl_T.hpp:57