1 #ifndef D_MOSAIC_GEOCUTS_IMPL_HPP
2 #define D_MOSAIC_GEOCUTS_IMPL_HPP
6 #include <boost/config.hpp>
8 #include <boost/utility.hpp>
10 #include <boost/graph/graph_traits.hpp>
11 #include <boost/graph/adjacency_list.hpp>
13 #include <boost/version.hpp>
14 #if BOOST_VERSION >= 104700
15 #include <boost/graph/boykov_kolmogorov_max_flow.hpp>
16 #elif BOOST_VERSION >= 103500
17 #include <boost/graph/kolmogorov_max_flow.hpp>
22 static int debugOn =
false;
24 #define SMIL_ENTER_FUNCTION(a) \
27 cout << "Entering function " << __func__ << " " << (a) << endl; \
30 #define SMIL_REGISTER_ERROR(a)
32 typedef off_t offset_t;
42 inline vector<IntPoint> filterStrElt(StrElt se)
44 vector<IntPoint> pts(0);
46 vector<IntPoint>::iterator it, itStart, itEnd;
47 itStart = se.points.begin();
48 itEnd = se.points.end();
50 for (it = itStart; it != itEnd; it++) {
51 bool ok = (4 * it->z + 2 * it->y + it->x) > 0;
56 std::cout << (ok ?
"GOOD " :
"BAD ") << std::right <<
" "
57 << std::setw(6) << it->x <<
" " << std::setw(6) << it->y
58 <<
" " << std::setw(6) << it->z << endl;
67 using namespace boost;
70 typedef adjacency_list_traits<vecS, vecS, directedS> Traits_T;
72 typedef adjacency_list<
73 vecS, vecS, directedS, property<vertex_name_t, std::string>,
74 property<edge_capacity_t, double,
75 property<edge_residual_capacity_t, double,
76 property<edge_reverse_t, Traits_T::edge_descriptor>>>>
80 typedef property_map<Graph_T, edge_capacity_t>::type EdgeCap_T;
82 typedef property_map<Graph_T, edge_reverse_t>::type EdgeRevCap_T;
84 typedef property_map<Graph_T, edge_residual_capacity_t>::type EdgeResCap_T;
86 typedef property_map<Graph_T, vertex_index_t>::type VertexIndex_T;
97 const Image<T> &imMarker,
const StrElt &nl,
100 SMIL_ENTER_FUNCTION(
"");
102 ASSERT_ALLOCATED(&imIn, &imGrad, &imMarker, &imOut);
103 ASSERT_SAME_SIZE(&imIn, &imGrad, &imMarker, &imOut);
109 EdgeCap_T capacity = boost::get(boost::edge_capacity, g);
110 EdgeRevCap_T rev = boost::get(boost::edge_reverse, g);
111 EdgeResCap_T residual_capacity =
112 boost::get(boost::edge_residual_capacity, g);
115 Graph_T::edge_descriptor e1, e2, e3, e4, e5;
116 Graph_T::vertex_descriptor vSource, vSink;
121 std::cout <<
"build Region Adjacency Graph" << std::endl;
122 std::cout <<
"build Region Adjacency Graph Vertices" << std::endl;
124 clock_t t1 = clock();
129 std::cout <<
"number of Vertices : " << numVert << std::endl;
131 for (
int i = 1; i <= numVert; i++) {
132 boost::add_vertex(g);
135 vSource = boost::add_vertex(g);
136 vSink = boost::add_vertex(g);
138 clock_t tt_marker2 = 0, tt_marker3 = 0, tt_new_edge = 0, tt_old_edge = 0;
139 clock_t t2 = clock();
140 std::cout <<
"Nodes creation time : " << double(t2 - t1) / CLOCKS_PER_SEC
143 std::cout <<
"Building Region Adjacency Graph Edges" << std::endl;
146 typename Image<T>::lineType bufIn = imIn.getPixels();
147 typename Image<T>::lineType bufOut = imOut.getPixels();
148 typename Image<T>::lineType bufMarker = imMarker.getPixels();
149 typename Image<T>::lineType bufGrad = imGrad.getPixels();
151 int pixelCount = imIn.getPixelCount();
152 for (o1 = 0; o1 < pixelCount; o1++) {
153 int val = (T) bufIn[o1];
154 int marker = (T) bufMarker[o1];
155 int val_prec = 0, marker_prec = 0;
161 if (marker == 2 && marker_prec != marker && val_prec != val) {
162 clock_t temps_marker2 = clock();
163 boost::tie(e4, in1) = boost::edge(vSource, val, g);
167 boost::tie(e4, in1) = boost::add_edge(vSource, val, g);
168 boost::tie(e3, in1) = boost::add_edge(val, vSource, g);
169 capacity[e4] = (std::numeric_limits<double>::max)();
170 capacity[e3] = (std::numeric_limits<double>::max)();
174 tt_marker2 += clock() - temps_marker2;
176 if (marker == 3 && marker_prec != marker && val_prec != val) {
177 clock_t temps_marker3 = clock();
178 boost::tie(e3, in1) = boost::edge(vSink, val, g);
181 boost::tie(e4, in1) = boost::add_edge(val, vSink, g);
182 boost::tie(e3, in1) = boost::add_edge(vSink, val, g);
183 capacity[e4] = (std::numeric_limits<double>::max)();
184 capacity[e3] = (std::numeric_limits<double>::max)();
188 tt_marker3 += clock() - temps_marker3;
192 double val_grad_o1 = imGrad.getPixel(o1);
197 morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
198 typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
200 neighb.setCenter(o1);
202 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
203 const offset_t o2 = nit.getOffset();
208 int val2 = imIn.pixelFromOffset(o2);
210 double val_grad_o2 = imGrad.pixelFromOffset(o2);
211 double maxi = std::max(val_grad_o1, val_grad_o2);
212 double cost = 10000.0 / (1.0 +
std::pow(maxi, 4));
214 if (val2_prec == val2) {
216 capacity[e4] = capacity[e4] + cost;
217 capacity[e3] = capacity[e3] + cost;
219 boost::tie(e5, in1) = boost::edge(val, val2, g);
222 clock_t temps_new_edge = clock();
226 boost::tie(e4, in1) = boost::add_edge(val, val2, g);
227 boost::tie(e3, in1) = boost::add_edge(val2, val, g);
232 tt_new_edge += clock() - temps_new_edge;
235 clock_t temps_old_edge = clock();
237 boost::tie(e4, in1) = boost::edge(val, val2, g);
238 boost::tie(e3, in1) = boost::edge(val2, val, g);
239 capacity[e4] = capacity[e4] + cost;
240 capacity[e3] = capacity[e3] + cost;
241 tt_old_edge += clock() - temps_old_edge;
249 marker_prec = marker;
254 std::cout <<
"Number of edges : " << numEdges << std::endl;
256 std::cout <<
"Edges creation time : " << double(t2 - t1) / CLOCKS_PER_SEC
258 std::cout <<
"Marker2 : " << double(tt_marker2) / CLOCKS_PER_SEC
260 std::cout <<
"Marker3 : " << double(tt_marker3) / CLOCKS_PER_SEC
262 std::cout <<
"New edges : " << double(tt_new_edge) / CLOCKS_PER_SEC
264 std::cout <<
"Old edges : " << double(tt_old_edge) / CLOCKS_PER_SEC
267 boost::property_map<Graph_T, boost::vertex_index_t>::type indexmap =
268 boost::get(boost::vertex_index, g);
269 std::vector<boost::default_color_type> color(boost::num_vertices(g));
271 std::cout <<
"Compute Max flow" << std::endl;
273 #if BOOST_VERSION >= 104700
275 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
276 &color[0], indexmap, vSource, vSink);
278 double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
279 &color[0], indexmap, vSource, vSink);
281 std::cout <<
"c The total flow:" << std::endl;
282 std::cout <<
"s " << flow << std::endl << std::endl;
284 std::cout <<
"Flow computation time : " << double(t2 - t1) / CLOCKS_PER_SEC
288 pixelCount = imIn.getPixelCount();
289 for (o1 = 0; o1 < pixelCount; o1++) {
290 int val = (T) bufIn[o1];
295 if (color[val] == color[vSource])
297 else if (color[val] == color[vSink])
305 std::cout <<
"Computing imOut took : " << double(t2 - t1) / CLOCKS_PER_SEC
319 template <
class ImageIn,
class ImageGrad,
class ImageMarker,
class SE,
321 RES_T geoCutsMinSurfaces_with_Line(
322 const ImageIn &imIn,
const ImageGrad &imGrad,
const ImageMarker &imMarker,
323 const SE &nl, ImageOut &imOut)
325 SMIL_ENTER_FUNCTION(
"");
327 std::cout <<
"Enter function t_geoCutsMinSurfaces_With_Line" << std::endl;
329 if ((!imOut.isAllocated())) {
330 SMIL_REGISTER_ERROR(
"Not allocated");
331 return RES_NOT_ALLOCATED;
334 if ((!imIn.isAllocated())) {
335 SMIL_REGISTER_ERROR(
"Not allocated");
336 return RES_NOT_ALLOCATED;
339 if ((!imGrad.isAllocated())) {
340 SMIL_REGISTER_ERROR(
"Not allocated");
341 return RES_NOT_ALLOCATED;
344 if ((!imMarker.isAllocated())) {
345 SMIL_REGISTER_ERROR(
"Not allocated");
346 return RES_NOT_ALLOCATED;
350 typename ImageIn::const_iterator it, iend;
351 morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
352 typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
357 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
360 typedef boost::adjacency_list<
361 boost::listS, boost::vecS, boost::directedS,
362 boost::property<boost::vertex_name_t, std::string>,
364 boost::edge_capacity_t, double,
365 boost::property<boost::edge_residual_capacity_t, double,
366 boost::property<boost::edge_reverse_t,
367 Traits::edge_descriptor>>>>
374 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
375 boost::get(boost::edge_capacity, g);
377 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
378 get(boost::edge_reverse, g);
380 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
381 residual_capacity = get(boost::edge_residual_capacity, g);
384 Graph_d::edge_descriptor e1, e2, e3, e4;
385 Graph_d::vertex_descriptor vSource, vSink;
388 std::cout <<
"build Region Adjacency Graph" << std::endl;
390 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
393 int val = imIn.pixelFromOffset(o0);
400 std::cout <<
"build Region Adjacency Graph Vertices :" << numVert
403 for (
int i = 0; i <= numVert; i++) {
404 boost::add_vertex(g);Mosaic_GeoCuts.hpp
407 vSource = boost::add_vertex(g);
408 vSink = boost::add_vertex(g);
410 std::cout <<
"build Region Adjacency Graph Edges" << std::endl;
412 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
416 int val = imIn.pixelFromOffset(o1);
417 int marker = imMarker.pixelFromOffset(o1);
420 boost::tie(e4, in1) = boost::edge(vSource, val, g);
423 boost::tie(e4, in1) = boost::add_edge(vSource, val, g);
424 boost::tie(e3, in1) = boost::add_edge(val, vSource, g);
425 capacity[e4] = (std::numeric_limits<double>::max)();
426 capacity[e3] = (std::numeric_limits<double>::max)();
430 }
else if (marker == 3) {
431 boost::tie(e3, in1) = boost::edge(vSink, val, g);
434 boost::tie(e4, in1) = boost::add_edge(val, vSink, g);
435 boost::tie(e3, in1) = boost::add_edge(vSink, val, g);
436 capacity[e4] = (std::numeric_limits<double>::max)();
437 capacity[e3] = (std::numeric_limits<double>::max)();
443 neighb.setCenter(o1);
445 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
446 const offset_t o2 = nit.getOffset();
447 int val2 = imIn.pixelFromOffset(o2);
451 boost::tie(e3, in1) = boost::edge(val, val2, g);
454 double val3 = imGrad.pixelFromOffset(o1);
455 double val4 = imGrad.pixelFromOffset(o2);
456 double maxi = std::max(val3, val4);
457 double cost = 10000000.0 / (1.0 +
std::pow(maxi, 5));
461 boost::tie(e4, in1) = boost::add_edge(val, val2, g);
462 boost::tie(e3, in1) = boost::add_edge(val2, val, g);
469 boost::tie(e4, in1) = boost::edge(val, val2, g);
470 boost::tie(e3, in1) = boost::edge(val2, val, g);
471 capacity[e4] = capacity[e4] + cost;
472 capacity[e3] = capacity[e3] + cost;
479 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
480 boost::get(boost::vertex_index, g);
481 std::vector<boost::default_color_type> color(boost::num_vertices(g));
483 std::cout <<
"Compute Max flow" << std::endl;
484 #if BOOST_VERSION >= 104700
486 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
487 &color[0], indexmap, vSource, vSink);
489 double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
490 &color[0], indexmap, vSource, vSink);
492 std::cout <<
"c The total flow:" << std::endl;
493 std::cout <<
"s " << flow << std::endl << std::endl;
495 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
498 int val = imIn.pixelFromOffset(o1);
500 if (color[val] == color[vSource])
501 imOut.setPixel(o1, 2);
502 else if (color[val] == color[vSink])
503 imOut.setPixel(o1, 3);
505 imOut.setPixel(o1, 4);
508 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
511 int valeur_c = imOut.pixelFromOffset(o1);
512 neighb.setCenter(o1);
514 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
515 const offset_t o2 = nit.getOffset();
516 int valeur_n = imOut.pixelFromOffset(o2);
518 if (valeur_n != valeur_c && valeur_n != 0 && valeur_c != 0) {
519 imOut.setPixel(o1, 0);
534 template <
class ImageLabel,
class ImageVal,
class ImageMarker,
class SE,
536 RES_T geoCutsMinSurfaces_with_steps(
537 const ImageLabel &imLabel,
const ImageVal &imVal,
538 const ImageMarker &imMarker,
const SE &nl, F_SIMPLE step_x,
539 F_SIMPLE step_y, F_SIMPLE step_z, ImageOut &imOut)
541 SMIL_ENTER_FUNCTION(
"(multi-valued version)");
546 if (!imOut.isAllocated() || !imLabel.isAllocated() ||
547 !imVal.isAllocated() || !imMarker.isAllocated()) {
548 SMIL_REGISTER_ERROR(
"Image not allocated");
549 return RES_NOT_ALLOCATED;
553 typename ImageLabel::const_iterator it, iend;
554 morphee::selement::Neighborhood<SE, ImageLabel> neighb(imLabel, nl);
555 typename morphee::selement::Neighborhood<SE, ImageLabel>::iterator nit,
561 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
564 typedef boost::adjacency_list<
565 boost::vecS, boost::vecS, boost::directedS,
566 boost::property<boost::vertex_name_t, std::string>,
568 boost::edge_capacity_t, F_DOUBLE,
569 boost::property<boost::edge_residual_capacity_t, F_DOUBLE,
570 boost::property<boost::edge_reverse_t,
571 Traits::edge_descriptor>>>>
578 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
579 boost::get(boost::edge_capacity, g);
580 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
581 get(boost::edge_reverse, g);
582 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
583 residual_capacity = get(boost::edge_residual_capacity, g);
586 Graph_d::edge_descriptor e1, e2, e3, e4, e5;
587 Graph_d::vertex_descriptor vSource, vSink;
593 clock_t t1 = clock();
595 morphee::stats::t_measMinMax(imLabel, not_used, max);
601 for (
int i = 0; i <= numVert; i++) {
602 boost::add_vertex(g);
604 vSource = boost::add_vertex(g);
605 vSink = boost::add_vertex(g);
607 clock_t tt_marker2 = 0, tt_marker3 = 0, tt_new_edge = 0, tt_old_edge = 0;
608 clock_t t2 = clock();
615 for (it = imLabel.begin(), iend = imLabel.end(); it != iend; ++it) {
617 typename ImageLabel::value_type
label = imLabel.pixelFromOffset(o1),
619 typename ImageMarker::value_type marker = imMarker.pixelFromOffset(o1),
623 if (marker == 2 && marker_prec != marker &&
626 clock_t temps_marker2 = clock();
627 boost::tie(e4, in1) = boost::edge(vSource,
label, g);
630 boost::tie(e4, in1) = boost::add_edge(vSource,
label, g);
631 boost::tie(e3, in1) = boost::add_edge(
label, vSource, g);
632 capacity[e4] = (std::numeric_limits<F_DOUBLE>::max)();
633 capacity[e3] = (std::numeric_limits<F_DOUBLE>::max)();
637 tt_marker2 += clock() - temps_marker2;
638 }
else if (marker == 3 && marker_prec != marker &&
641 clock_t temps_marker3 = clock();
642 boost::tie(e3, in1) = boost::edge(vSink,
label, g);
646 boost::tie(e4, in1) = boost::add_edge(
label, vSink, g);
647 boost::tie(e3, in1) = boost::add_edge(vSink,
label, g);
648 capacity[e4] = (std::numeric_limits<F_DOUBLE>::max)();
649 capacity[e3] = (std::numeric_limits<F_DOUBLE>::max)();
653 tt_marker3 += clock() - temps_marker3;
656 neighb.setCenter(o1);
657 typename ImageVal::value_type val_o1 = imVal.pixelFromOffset(o1);
658 typename ImageLabel::value_type label2_prec =
661 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
662 const offset_t o2 = nit.getOffset();
665 typename ImageLabel::value_type label2 =
666 imLabel.pixelFromOffset(o2);
667 if (
label != label2) {
668 typename ImageVal::value_type val_o2 = imVal.pixelFromOffset(o2);
670 F_SIMPLE
diff = t_Distance_L1(val_o1, val_o2);
674 dx = std::abs(it.getX() - nit.getX());
675 dy = std::abs(it.getY() - nit.getY());
676 dz = std::abs(it.getZ() - nit.getZ());
716 F_DOUBLE cost = surf / (1 +
diff);
731 if (label2_prec == label2)
734 capacity[e4] = capacity[e4] + cost;
735 capacity[e3] = capacity[e3] + cost;
737 boost::tie(e5, in1) = boost::edge(
label, label2, g);
739 clock_t temps_new_edge = clock();
743 boost::tie(e4, in1) = boost::add_edge(
label, label2, g);
744 boost::tie(e3, in1) = boost::add_edge(label2,
label, g);
749 tt_new_edge += clock() - temps_new_edge;
752 clock_t temps_old_edge = clock();
754 boost::tie(e4, in1) = boost::edge(
label, label2, g);
755 boost::tie(e3, in1) = boost::edge(label2,
label, g);
756 capacity[e4] = capacity[e4] + cost;
757 capacity[e3] = capacity[e3] + cost;
758 tt_old_edge += clock() - temps_old_edge;
760 label2_prec = label2;
766 marker_prec = marker;
788 Graph_d::vertex_descriptor sink_neighbour;
789 typename boost::graph_traits<Graph_d>::adjacency_iterator ai, ai_end;
790 UINT32 rem_edges = 0;
791 for (boost::tie(ai, ai_end) = adjacent_vertices(vSink, g); ai != ai_end;
793 sink_neighbour = *ai;
794 tie(e1, in1) = edge(sink_neighbour, vSource, g);
799 capacity[rev[e1]] = 0;
801 tie(e2, in1) = edge(vSink, sink_neighbour, g);
803 capacity[rev[e2]] = 0;
812 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
813 boost::get(boost::vertex_index, g);
814 std::vector<boost::default_color_type> color(boost::num_vertices(g));
818 #if BOOST_VERSION >= 104700
820 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
821 &color[0], indexmap, vSource, vSink);
823 F_DOUBLE flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
824 &color[0], indexmap, vSource, vSink);
833 for (it = imLabel.begin(), iend = imLabel.end(); it != iend; ++it) {
835 typename ImageLabel::value_type
label = imLabel.pixelFromOffset(o1);
838 imOut.setPixel(o1, 0);
842 if (color[
label] == color[vSource])
843 imOut.setPixel(o1, 2);
845 imOut.setPixel(o1, 3);
864 template <
class ImageLabel,
class ImageVal,
class ImageMarker,
class SE,
866 RES_T geoCutsMinSurfaces_with_steps_vGradient(
867 const ImageLabel &imLabel,
const ImageVal &imVal,
868 const ImageMarker &imMarker,
const SE &nl, F_SIMPLE step_x,
869 F_SIMPLE step_y, F_SIMPLE step_z, ImageOut &imOut)
871 SMIL_ENTER_FUNCTION(
"(multi-valued version)");
876 if (!imOut.isAllocated() || !imLabel.isAllocated() ||
877 !imVal.isAllocated() || !imMarker.isAllocated()) {
878 SMIL_REGISTER_ERROR(
"Image not allocated");
879 return RES_NOT_ALLOCATED;
883 typename ImageLabel::const_iterator it, iend;
884 morphee::selement::Neighborhood<SE, ImageLabel> neighb(imLabel, nl);
885 typename morphee::selement::Neighborhood<SE, ImageLabel>::iterator nit,
891 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
894 typedef boost::adjacency_list<
895 boost::vecS, boost::vecS, boost::directedS,
896 boost::property<boost::vertex_name_t, std::string>,
898 boost::edge_capacity_t, F_DOUBLE,
899 boost::property<boost::edge_residual_capacity_t, F_DOUBLE,
900 boost::property<boost::edge_reverse_t,
901 Traits::edge_descriptor>>>>
908 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
909 boost::get(boost::edge_capacity, g);
910 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
911 get(boost::edge_reverse, g);
912 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
913 residual_capacity = get(boost::edge_residual_capacity, g);
916 Graph_d::edge_descriptor e1, e2, e3, e4, e5;
917 Graph_d::vertex_descriptor vSource, vSink;
923 clock_t t1 = clock();
925 morphee::stats::t_measMinMax(imLabel, not_used, max);
931 for (
int i = 0; i <= numVert; i++) {
932 boost::add_vertex(g);
934 vSource = boost::add_vertex(g);
935 vSink = boost::add_vertex(g);
937 clock_t tt_marker2 = 0, tt_marker3 = 0, tt_new_edge = 0, tt_old_edge = 0;
938 clock_t t2 = clock();
945 for (it = imLabel.begin(), iend = imLabel.end(); it != iend; ++it) {
947 typename ImageLabel::value_type
label = imLabel.pixelFromOffset(o1),
949 typename ImageMarker::value_type marker = imMarker.pixelFromOffset(o1),
953 if (marker == 2 && marker_prec != marker &&
956 clock_t temps_marker2 = clock();
957 boost::tie(e4, in1) = boost::edge(vSource,
label, g);
960 boost::tie(e4, in1) = boost::add_edge(vSource,
label, g);
961 boost::tie(e3, in1) = boost::add_edge(
label, vSource, g);
962 capacity[e4] = (std::numeric_limits<F_DOUBLE>::max)();
963 capacity[e3] = (std::numeric_limits<F_DOUBLE>::max)();
967 tt_marker2 += clock() - temps_marker2;
968 }
else if (marker == 3 && marker_prec != marker &&
971 clock_t temps_marker3 = clock();
972 boost::tie(e3, in1) = boost::edge(vSink,
label, g);
976 boost::tie(e4, in1) = boost::add_edge(
label, vSink, g);
977 boost::tie(e3, in1) = boost::add_edge(vSink,
label, g);
978 capacity[e4] = (std::numeric_limits<F_DOUBLE>::max)();
979 capacity[e3] = (std::numeric_limits<F_DOUBLE>::max)();
983 tt_marker3 += clock() - temps_marker3;
986 neighb.setCenter(o1);
987 typename ImageVal::value_type val_o1 = imVal.pixelFromOffset(o1);
988 typename ImageLabel::value_type label2_prec =
991 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
992 const offset_t o2 = nit.getOffset();
995 typename ImageLabel::value_type label2 =
996 imLabel.pixelFromOffset(o2);
997 if (
label != label2) {
998 typename ImageVal::value_type val_o2 = imVal.pixelFromOffset(o2);
999 F_SIMPLE
diff = std::max(val_o1, val_o2);
1002 dx = std::abs(it.getX() - nit.getX());
1003 dy = std::abs(it.getY() - nit.getY());
1004 dz = std::abs(it.getZ() - nit.getZ());
1041 F_DOUBLE cost = surf / (1 +
diff);
1053 if (label2_prec == label2)
1056 capacity[e4] = capacity[e4] + cost;
1057 capacity[e3] = capacity[e3] + cost;
1059 boost::tie(e5, in1) = boost::edge(
label, label2, g);
1061 clock_t temps_new_edge = clock();
1065 boost::tie(e4, in1) = boost::add_edge(
label, label2, g);
1066 boost::tie(e3, in1) = boost::add_edge(label2,
label, g);
1067 capacity[e4] = cost;
1068 capacity[e3] = cost;
1071 tt_new_edge += clock() - temps_new_edge;
1074 clock_t temps_old_edge = clock();
1076 boost::tie(e4, in1) = boost::edge(
label, label2, g);
1077 boost::tie(e3, in1) = boost::edge(label2,
label, g);
1078 capacity[e4] = capacity[e4] + cost;
1079 capacity[e3] = capacity[e3] + cost;
1080 tt_old_edge += clock() - temps_old_edge;
1082 label2_prec = label2;
1088 marker_prec = marker;
1110 Graph_d::vertex_descriptor sink_neighbour;
1111 typename boost::graph_traits<Graph_d>::adjacency_iterator ai, ai_end;
1112 UINT32 rem_edges = 0;
1113 for (boost::tie(ai, ai_end) = adjacent_vertices(vSink, g); ai != ai_end;
1115 sink_neighbour = *ai;
1116 tie(e1, in1) = edge(sink_neighbour, vSource, g);
1121 capacity[rev[e1]] = 0;
1123 tie(e2, in1) = edge(vSink, sink_neighbour, g);
1125 capacity[rev[e2]] = 0;
1134 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
1135 boost::get(boost::vertex_index, g);
1136 std::vector<boost::default_color_type> color(boost::num_vertices(g));
1139 #if BOOST_VERSION >= 104700
1141 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
1142 &color[0], indexmap, vSource, vSink);
1144 F_DOUBLE flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
1145 &color[0], indexmap, vSource, vSink);
1154 for (it = imLabel.begin(), iend = imLabel.end(); it != iend; ++it) {
1155 o1 = it.getOffset();
1156 typename ImageLabel::value_type
label = imLabel.pixelFromOffset(o1);
1159 imOut.setPixel(o1, 0);
1163 if (color[
label] == color[vSource])
1164 imOut.setPixel(o1, 2);
1166 imOut.setPixel(o1, 3);
1184 template <
class ImageIn,
class ImageGrad,
class ImageMarker,
class SE,
1186 RES_T geoCutsMinSurfaces_with_steps_old(
1187 const ImageIn &imIn,
const ImageGrad &imGrad,
const ImageMarker &imMarker,
1188 const SE &nl, F_SIMPLE step_x, F_SIMPLE step_y, F_SIMPLE step_z,
1191 SMIL_ENTER_FUNCTION(
"");
1193 std::cout <<
"Enter function t_geoCutsMinSurfaces" << std::endl;
1195 if ((!imOut.isAllocated())) {
1196 SMIL_REGISTER_ERROR(
"Not allocated");
1197 return RES_NOT_ALLOCATED;
1200 if ((!imIn.isAllocated())) {
1201 SMIL_REGISTER_ERROR(
"Not allocated");
1202 return RES_NOT_ALLOCATED;
1205 if ((!imGrad.isAllocated())) {
1206 SMIL_REGISTER_ERROR(
"Not allocated");
1207 return RES_NOT_ALLOCATED;
1210 if ((!imMarker.isAllocated())) {
1211 SMIL_REGISTER_ERROR(
"Not allocated");
1212 return RES_NOT_ALLOCATED;
1216 typename ImageIn::const_iterator it, iend;
1217 morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
1218 typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
1223 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
1226 typedef boost::adjacency_list<
1227 boost::vecS, boost::vecS, boost::directedS,
1228 boost::property<boost::vertex_name_t, std::string>,
1230 boost::edge_capacity_t, double,
1231 boost::property<boost::edge_residual_capacity_t, double,
1232 boost::property<boost::edge_reverse_t,
1233 Traits::edge_descriptor>>>>
1238 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
1239 boost::get(boost::edge_capacity, g);
1241 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
1242 get(boost::edge_reverse, g);
1244 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
1245 residual_capacity = get(boost::edge_residual_capacity, g);
1248 Graph_d::edge_descriptor e1, e2, e3, e4, e5;
1249 Graph_d::vertex_descriptor vSource, vSink;
1254 std::cout <<
"build Region Adjacency Graph" << std::endl;
1256 std::cout <<
"build Region Adjacency Graph Vertices" << std::endl;
1258 clock_t t1 = clock();
1260 morphee::stats::t_measMinMax(imIn, not_used, max);
1262 std::cout <<
"number of Vertices : " << numVert << std::endl;
1264 for (
int i = 1; i <= numVert; i++) {
1265 boost::add_vertex(g);
1268 vSource = boost::add_vertex(g);
1269 vSink = boost::add_vertex(g);
1271 clock_t tt_marker2 = 0, tt_marker3 = 0, tt_new_edge = 0, tt_old_edge = 0;
1272 clock_t t2 = clock();
1273 std::cout <<
"Nodes creation time : " << double(t2 - t1) / CLOCKS_PER_SEC
1276 std::cout <<
"Building Region Adjacency Graph Edges" << std::endl;
1279 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
1280 o1 = it.getOffset();
1282 int val = imIn.pixelFromOffset(o1);
1283 int marker = imMarker.pixelFromOffset(o1);
1284 int val_prec = 0, marker_prec = 0;
1287 if (marker == 2 && marker_prec != marker && val_prec != val) {
1288 clock_t temps_marker2 = clock();
1289 boost::tie(e4, in1) = boost::edge(vSource, val, g);
1293 boost::tie(e4, in1) = boost::add_edge(vSource, val, g);
1294 boost::tie(e3, in1) = boost::add_edge(val, vSource, g);
1295 capacity[e4] = (std::numeric_limits<double>::max)();
1296 capacity[e3] = (std::numeric_limits<double>::max)();
1300 tt_marker2 += clock() - temps_marker2;
1301 }
else if (marker == 3 && marker_prec != marker && val_prec != val) {
1302 clock_t temps_marker3 = clock();
1303 boost::tie(e3, in1) = boost::edge(vSink, val, g);
1306 boost::tie(e4, in1) = boost::add_edge(val, vSink, g);
1307 boost::tie(e3, in1) = boost::add_edge(vSink, val, g);
1308 capacity[e4] = (std::numeric_limits<double>::max)();
1309 capacity[e3] = (std::numeric_limits<double>::max)();
1313 tt_marker3 += clock() - temps_marker3;
1316 neighb.setCenter(o1);
1318 double val_grad_o1 = imGrad.pixelFromOffset(o1);
1321 int val2_prec = val;
1323 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
1324 const offset_t o2 = nit.getOffset();
1328 int val2 = imIn.pixelFromOffset(o2);
1331 double val_grad_o2 = imGrad.pixelFromOffset(o2);
1334 double diff = t_Distance_L1(val_grad_o1, val_grad_o2);
1339 std::pow(step_y * (it.getY() - nit.getY()), 2) +
1340 std::pow(step_z * (it.getZ() - nit.getZ()), 2));
1345 double cost = dist / (1 +
diff);
1350 capacity[e4] = capacity[e4] + cost;
1351 capacity[e3] = capacity[e3] + cost;
1353 boost::tie(e5, in1) = boost::edge(val, val2, g);
1356 clock_t temps_new_edge = clock();
1360 boost::tie(e4, in1) = boost::add_edge(val, val2, g);
1361 boost::tie(e3, in1) = boost::add_edge(val2, val, g);
1362 capacity[e4] = cost;
1363 capacity[e3] = cost;
1366 tt_new_edge += clock() - temps_new_edge;
1369 clock_t temps_old_edge = clock();
1371 boost::tie(e4, in1) = boost::edge(val, val2, g);
1372 boost::tie(e3, in1) = boost::edge(val2, val, g);
1373 capacity[e4] = capacity[e4] + cost;
1374 capacity[e3] = capacity[e3] + cost;
1375 tt_old_edge += clock() - temps_old_edge;
1383 marker_prec = marker;
1387 std::cout <<
"Number of edges : " << numEdges << std::endl;
1389 std::cout <<
"Edges creation time : " << double(t2 - t1) / CLOCKS_PER_SEC
1391 std::cout <<
"Marker2 : " << double(tt_marker2) / CLOCKS_PER_SEC
1393 std::cout <<
"Marker3 : " << double(tt_marker3) / CLOCKS_PER_SEC
1395 std::cout <<
"New edges : " << double(tt_new_edge) / CLOCKS_PER_SEC
1397 std::cout <<
"Old edges : " << double(tt_old_edge) / CLOCKS_PER_SEC
1400 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
1401 boost::get(boost::vertex_index, g);
1402 std::vector<boost::default_color_type> color(boost::num_vertices(g));
1404 std::cout <<
"Compute Max flow" << std::endl;
1406 #if BOOST_VERSION >= 104700
1408 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
1409 &color[0], indexmap, vSource, vSink);
1411 double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
1412 &color[0], indexmap, vSource, vSink);
1414 std::cout <<
"c The total flow:" << std::endl;
1415 std::cout <<
"s " << flow << std::endl;
1417 std::cout <<
"Flow computation time : " << double(t2 - t1) / CLOCKS_PER_SEC
1422 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
1423 o1 = it.getOffset();
1425 int val = imIn.pixelFromOffset(o1);
1428 imOut.setPixel(o1, 0);
1430 if (color[val] == color[vSource])
1431 imOut.setPixel(o1, 2);
1432 else if (color[val] == color[vSink])
1433 imOut.setPixel(o1, 3);
1435 imOut.setPixel(o1, 20);
1441 std::cout <<
"Computing imOut took : " << double(t2 - t1) / CLOCKS_PER_SEC
1445 std::cout <<
"WARNING : Missclassified nodes : " << miss <<
"\n";
1458 RES_T geoCutsMultiWay_MinSurfaces(
const Image<T> &imIn,
1459 const Image<T> &imGrad,
1460 const Image<T> &imMarker,
const StrElt &nl,
1463 SMIL_ENTER_FUNCTION(
"");
1465 ASSERT_ALLOCATED(&imIn, &imGrad, &imMarker, &imOut);
1466 ASSERT_SAME_SIZE(&imIn, &imGrad, &imMarker, &imOut);
1470 typename Image<T>::lineType bufIn = imIn.getPixels();
1471 typename Image<T>::lineType bufOut = imOut.getPixels();
1472 typename Image<T>::lineType bufMarker = imMarker.getPixels();
1473 typename Image<T>::lineType bufGrad = imGrad.getPixels();
1475 std::cout <<
"build Region Adjacency Graph" << std::endl;
1478 EdgeCap_T capacity = boost::get(boost::edge_capacity, g);
1479 EdgeRevCap_T rev = boost::get(boost::edge_reverse, g);
1480 EdgeResCap_T residual_capacity =
1481 boost::get(boost::edge_residual_capacity, g);
1484 Graph_T::edge_descriptor e1, e2, e3, e4;
1485 Graph_T::vertex_descriptor vSource, vSink;
1489 int pixelCount = imIn.getPixelCount();
1490 for (o0 = 0; o0 < pixelCount; o0++) {
1491 int val = (int) bufIn[o0];
1492 int val2 = (int) bufMarker[o0];
1495 if (val2 > numLabels) {
1499 if (val > numVert) {
1504 std::cout <<
"number of labels :" << numLabels << std::endl;
1506 std::cout <<
"build Region Adjacency Graph Vertices" << std::endl;
1508 for (
int i = 0; i <= numVert; i++) {
1509 boost::add_vertex(g);
1512 vSource = boost::add_vertex(g);
1513 vSink = boost::add_vertex(g);
1515 std::vector<boost::default_color_type> color(boost::num_vertices(g));
1516 VertexIndex_T indexmap = boost::get(boost::vertex_index, g);
1518 std::cout <<
"build Region Adjacency Graph Edges" << std::endl;
1520 vector<IntPoint> pts = filterStrElt(nl);
1521 vector<IntPoint>::iterator itBegin, itEnd;
1522 itBegin = pts.begin();
1525 int width = imIn.getWidth();
1526 int height = imIn.getHeight();
1527 int depth = imIn.getDepth();
1529 int strideY = width;
1530 int strideZ = width * height;
1531 for (
int z = 0; z < depth; z++) {
1532 off_t p0 = z * strideZ;
1533 for (
int y = 0; y < height; y++) {
1535 for (
int x = 0; x < width; x++) {
1536 int val = (int) bufIn[o1];
1541 vector<IntPoint>::iterator it;
1542 for (it = itBegin; it != itEnd; it++) {
1543 if (x + it->x > width - 1 || x + it->x < 0)
1545 if (y + it->y > height - 1 || y + it->y < 0)
1547 if (z + it->z > depth - 1 || z + it->z < 0)
1549 offset_t o2 = o1 + it->z *strideZ + it->y *strideY + it->x;
1553 int val2 = bufIn[o2];
1557 boost::tie(e3, in1) = boost::edge(val, val2, g);
1560 double val3 = (double) bufGrad[o1];
1561 double val4 = (double) bufGrad[o2];
1562 double maxi = std::max(val3, val4);
1563 double cost = 10000.0 / (1.0 +
std::pow(maxi, 4));
1567 boost::tie(e4, in1) = boost::add_edge(val, val2, g);
1568 boost::tie(e3, in1) = boost::add_edge(val2, val, g);
1569 capacity[e4] = cost;
1570 capacity[e3] = cost;
1575 boost::tie(e4, in1) = boost::edge(val, val2, g);
1576 boost::tie(e3, in1) = boost::edge(val2, val, g);
1577 capacity[e4] = capacity[e4] + cost;
1578 capacity[e3] = capacity[e3] + cost;
1585 for (
int nbk = 2; nbk <= numLabels; nbk++) {
1587 for (
int o0 = 0; o0 < pixelCount; o0++) {
1588 int val = (int) bufMarker[o0];
1589 int val2 = (int) bufIn[o0];
1592 boost::tie(e4, in1) = boost::edge(vSource, val2, g);
1594 boost::tie(e4, in1) = boost::add_edge(vSource, val2, g);
1595 boost::tie(e3, in1) = boost::add_edge(val2, vSource, g);
1596 capacity[e4] = (std::numeric_limits<double>::max)();
1597 capacity[e3] = (std::numeric_limits<double>::max)();
1601 }
else if (val > 1 && val != nbk) {
1602 boost::tie(e4, in1) = boost::edge(val2, vSink, g);
1604 boost::tie(e4, in1) = boost::add_edge(val2, vSink, g);
1605 boost::tie(e3, in1) = boost::add_edge(vSink, val2, g);
1606 capacity[e4] = (std::numeric_limits<double>::max)();
1607 capacity[e3] = (std::numeric_limits<double>::max)();
1614 std::cout <<
"Compute Max flow" << nbk << std::endl;
1615 #if BOOST_VERSION >= 104700
1617 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
1618 &color[0], indexmap, vSource, vSink);
1620 double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
1621 &color[0], indexmap, vSource, vSink);
1624 std::cout <<
"c The total flow:" << std::endl;
1625 std::cout <<
"s " << flow << std::endl << std::endl;
1628 for (
int o1 = 0; o1 < pixelCount; o1++) {
1629 int val = (int) bufIn[o1];
1630 int val2 = (int) bufOut[o1];
1631 int val3 = (int) bufMarker[o1];
1634 if (color[val] == color[vSource])
1635 bufOut[o1] = (T) nbk;
1639 boost::tie(e4, in1) = boost::edge(vSource, val, g);
1641 boost::remove_edge(vSource, val, g);
1642 boost::remove_edge(val, vSource, g);
1644 }
else if (val3 > 1 && val3 != nbk) {
1645 boost::tie(e4, in1) = boost::edge(val, vSink, g);
1647 boost::remove_edge(val, vSink, g);
1648 boost::remove_edge(vSink, val, g);
1664 template <
class ImageIn,
class ImageGrad,
class ImageMosaic,
1665 class ImageMarker,
class SE,
class ImageOut>
1666 RES_T geoCutsOptimize_Mosaic(
1667 const ImageIn &imIn,
const ImageGrad &imGrad,
const ImageMosaic &imMosaic,
1668 const ImageMarker &imMarker,
const SE &nl, ImageOut &imOut)
1670 SMIL_ENTER_FUNCTION(
"");
1672 std::cout <<
"Enter function t_geoCutsOptimize_Mosaic" << std::endl;
1674 if ((!imOut.isAllocated())) {
1675 SMIL_REGISTER_ERROR(
"Not allocated");
1676 return RES_NOT_ALLOCATED;
1679 if ((!imIn.isAllocated())) {
1680 SMIL_REGISTER_ERROR(
"Not allocated");
1681 return RES_NOT_ALLOCATED;
1684 if ((!imGrad.isAllocated())) {
1685 SMIL_REGISTER_ERROR(
"Not allocated");
1686 return RES_NOT_ALLOCATED;
1689 if ((!imMosaic.isAllocated())) {
1690 SMIL_REGISTER_ERROR(
"Not allocated");
1691 return RES_NOT_ALLOCATED;
1694 if ((!imMarker.isAllocated())) {
1695 SMIL_REGISTER_ERROR(
"Not allocated");
1696 return RES_NOT_ALLOCATED;
1700 typename ImageIn::const_iterator it, iend;
1701 morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
1702 typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
1707 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
1710 typedef boost::adjacency_list<
1711 boost::listS, boost::vecS, boost::directedS,
1712 boost::property<boost::vertex_name_t, std::string>,
1714 boost::edge_capacity_t, double,
1715 boost::property<boost::edge_residual_capacity_t, double,
1716 boost::property<boost::edge_reverse_t,
1717 Traits::edge_descriptor>>>>
1724 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
1725 boost::get(boost::edge_capacity, g);
1727 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
1728 get(boost::edge_reverse, g);
1730 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
1731 residual_capacity = get(boost::edge_residual_capacity, g);
1734 Graph_d::edge_descriptor e1, e2, e3, e4;
1735 Graph_d::vertex_descriptor vSource, vSink;
1739 std::cout <<
"build Region Adjacency Graph" << std::endl;
1741 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
1743 o0 = it.getOffset();
1744 int val = imIn.pixelFromOffset(o0);
1745 int val2 = imMarker.pixelFromOffset(o0);
1747 imOut.setPixel(o0, 1);
1749 if (val2 > numLabels) {
1753 if (val > numVert) {
1757 std::cout <<
"numlabels = " << numLabels << std::endl;
1759 std::cout <<
"build Region Adjacency Graph Vertices" << std::endl;
1761 for (
int i = 0; i <= numVert; i++) {
1762 boost::add_vertex(g);
1765 vSource = boost::add_vertex(g);
1766 vSink = boost::add_vertex(g);
1768 std::vector<boost::default_color_type> color(boost::num_vertices(g));
1769 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
1770 boost::get(boost::vertex_index, g);
1772 std::cout <<
"build Region Adjacency Graph Edges" << std::endl;
1774 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
1776 o1 = it.getOffset();
1777 int val = imIn.pixelFromOffset(o1);
1778 int marker = imMarker.pixelFromOffset(o1);
1779 neighb.setCenter(o1);
1781 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
1782 const offset_t o2 = nit.getOffset();
1783 int val2 = imIn.pixelFromOffset(o2);
1787 boost::tie(e3, in1) = boost::edge(val, val2, g);
1790 double val3 = imGrad.pixelFromOffset(o1);
1791 double val4 = imGrad.pixelFromOffset(o2);
1792 double maxi = std::max(val3, val4);
1793 double cost = 1000 / (1 + 0.1 * (maxi) * (maxi));
1797 boost::tie(e4, in1) = boost::add_edge(val, val2, g);
1798 boost::tie(e3, in1) = boost::add_edge(val2, val, g);
1799 capacity[e4] = cost;
1800 capacity[e3] = cost;
1805 boost::tie(e4, in1) = boost::edge(val, val2, g);
1806 boost::tie(e3, in1) = boost::edge(val2, val, g);
1807 capacity[e4] = capacity[e4] + cost;
1808 capacity[e3] = capacity[e3] + cost;
1815 for (
int label1 = 1; label1 < numLabels; label1++) {
1816 for (
int label2 = label1 + 1; label2 <= numLabels; label2++) {
1817 if (label1 != label2) {
1818 std::cout <<
"Optimize Pair of labels: " << label1 <<
" " << label2
1821 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
1823 o0 = it.getOffset();
1824 int val = imMarker.pixelFromOffset(o0);
1825 int val2 = imIn.pixelFromOffset(o0);
1827 if (val == label1) {
1828 boost::tie(e4, in1) = boost::edge(vSource, val2, g);
1830 boost::tie(e4, in1) = boost::add_edge(vSource, val2, g);
1831 boost::tie(e3, in1) = boost::add_edge(val2, vSource, g);
1832 capacity[e4] = (std::numeric_limits<double>::max)();
1833 capacity[e3] = (std::numeric_limits<double>::max)();
1837 }
else if (val == label2) {
1838 boost::tie(e4, in1) = boost::edge(val2, vSink, g);
1840 boost::tie(e4, in1) = boost::add_edge(val2, vSink, g);
1841 boost::tie(e3, in1) = boost::add_edge(vSink, val2, g);
1842 capacity[e4] = (std::numeric_limits<double>::max)();
1843 capacity[e3] = (std::numeric_limits<double>::max)();
1850 std::cout <<
"Compute Max flow" << std::endl;
1851 #if BOOST_VERSION >= 104700
1853 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
1854 &color[0], indexmap, vSource, vSink);
1857 kolmogorov_max_flow(g, capacity, residual_capacity, rev,
1858 &color[0], indexmap, vSource, vSink);
1860 std::cout <<
"c The total flow:" << std::endl;
1861 std::cout <<
"s " << flow << std::endl << std::endl;
1863 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
1865 o1 = it.getOffset();
1866 int val = imIn.pixelFromOffset(o1);
1867 int val2 = imMosaic.pixelFromOffset(o1);
1868 int val3 = imMarker.pixelFromOffset(o1);
1870 if (val2 == label1 || val2 == label2) {
1871 if (color[val] == color[vSource])
1872 imOut.setPixel(o1, label1);
1873 else if (color[val] == color[vSink])
1874 imOut.setPixel(o1, label2);
1876 imOut.setPixel(o1, label2);
1879 if (val3 == label1) {
1880 boost::tie(e4, in1) = boost::edge(vSource, val, g);
1882 boost::remove_edge(vSource, val, g);
1883 boost::remove_edge(val, vSource, g);
1885 }
else if (val3 == label2) {
1886 boost::tie(e4, in1) = boost::edge(val, vSink, g);
1888 boost::remove_edge(val, vSink, g);
1889 boost::remove_edge(vSink, val, g);
1906 template <
class ImageIn,
class ImageGrad,
class ImageCurvature,
1907 class ImageMarker,
typename _Beta,
class SE,
class ImageOut>
1908 RES_T geoCutsRegularized_MinSurfaces(
1909 const ImageIn &imIn,
const ImageGrad &imGrad,
1910 const ImageCurvature &imCurvature,
const ImageMarker &imMarker,
1911 const _Beta Beta,
const SE &nl, ImageOut &imOut)
1913 SMIL_ENTER_FUNCTION(
"");
1915 std::cout <<
"Enter function t_geoCutsRegularized_MinSurfaces"
1918 if ((!imOut.isAllocated())) {
1919 SMIL_REGISTER_ERROR(
"Not allocated");
1920 return RES_NOT_ALLOCATED;
1923 if ((!imIn.isAllocated())) {
1924 SMIL_REGISTER_ERROR(
"Not allocated");
1925 return RES_NOT_ALLOCATED;
1928 if ((!imGrad.isAllocated())) {
1929 SMIL_REGISTER_ERROR(
"Not allocated");
1930 return RES_NOT_ALLOCATED;
1933 if ((!imCurvature.isAllocated())) {
1934 SMIL_REGISTER_ERROR(
"Not allocated");
1935 return RES_NOT_ALLOCATED;
1938 if ((!imMarker.isAllocated())) {
1939 SMIL_REGISTER_ERROR(
"Not allocated");
1940 return RES_NOT_ALLOCATED;
1944 typename ImageIn::const_iterator it, iend;
1945 morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
1946 typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
1951 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
1954 typedef boost::adjacency_list<
1955 boost::listS, boost::vecS, boost::directedS,
1956 boost::property<boost::vertex_name_t, std::string>,
1958 boost::edge_capacity_t, double,
1959 boost::property<boost::edge_residual_capacity_t, double,
1960 boost::property<boost::edge_reverse_t,
1961 Traits::edge_descriptor>>>>
1968 std::cout <<
"Reg. :" << beta << std::endl;
1970 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
1971 boost::get(boost::edge_capacity, g);
1973 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
1974 get(boost::edge_reverse, g);
1976 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
1977 residual_capacity = get(boost::edge_residual_capacity, g);
1980 Graph_d::edge_descriptor e1, e2, e3, e4;
1981 Graph_d::vertex_descriptor vSource, vSink;
1984 std::cout <<
"build Region Adjacency Graph" << std::endl;
1986 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
1988 o0 = it.getOffset();
1989 int val = imIn.pixelFromOffset(o0);
1990 if (val > numVert) {
1995 std::cout <<
"build Region Adjacency Graph Vertices" << std::endl;
1997 for (
int i = 1; i <= numVert; i++) {
1998 boost::add_vertex(g);
2001 vSource = boost::add_vertex(g);
2002 vSink = boost::add_vertex(g);
2004 std::cout <<
"build Region Adjacency Graph Edges" << std::endl;
2006 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2008 o1 = it.getOffset();
2009 int val = imIn.pixelFromOffset(o1);
2010 int marker = imMarker.pixelFromOffset(o1);
2014 boost::tie(e4, in1) = boost::edge(vSource, val, g);
2016 boost::tie(e4, in1) = boost::add_edge(vSource, val, g);
2017 boost::tie(e3, in1) = boost::add_edge(val, vSource, g);
2018 capacity[e4] = (std::numeric_limits<double>::max)();
2019 capacity[e3] = (std::numeric_limits<double>::max)();
2023 }
else if (marker == 3) {
2024 boost::tie(e3, in1) = boost::edge(vSink, val, g);
2026 boost::tie(e4, in1) = boost::add_edge(val, vSink, g);
2027 boost::tie(e3, in1) = boost::add_edge(vSink, val, g);
2028 capacity[e4] = (std::numeric_limits<double>::max)();
2029 capacity[e3] = (std::numeric_limits<double>::max)();
2035 neighb.setCenter(o1);
2037 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
2038 const offset_t o2 = nit.getOffset();
2039 int val2 = imIn.pixelFromOffset(o2);
2043 boost::tie(e3, in1) = boost::edge(val, val2, g);
2045 double val3 = imGrad.pixelFromOffset(o1);
2046 double val4 = imGrad.pixelFromOffset(o2);
2048 double val5 = imCurvature.pixelFromOffset(o1);
2049 double val6 = imCurvature.pixelFromOffset(o2);
2051 double maxigrad = std::max(val3, val4);
2053 double maxicurv = std::max(val5, val6);
2057 double costcurvature = (beta) *maxicurv;
2059 double costgradient = 10000.0 / (1 +
std::pow(maxigrad, 2));
2061 double cost = costgradient + costcurvature;
2064 boost::tie(e4, in1) = boost::add_edge(val, val2, g);
2065 boost::tie(e3, in1) = boost::add_edge(val2, val, g);
2066 capacity[e4] = cost;
2067 capacity[e3] = cost;
2071 boost::tie(e4, in1) = boost::edge(val, val2, g);
2072 boost::tie(e3, in1) = boost::edge(val2, val, g);
2073 capacity[e4] = capacity[e4] + cost;
2074 capacity[e3] = capacity[e3] + cost;
2082 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
2083 boost::get(boost::vertex_index, g);
2084 std::vector<boost::default_color_type> color(boost::num_vertices(g));
2086 std::cout <<
"Compute Max flow" << std::endl;
2087 #if BOOST_VERSION >= 104700
2089 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
2090 &color[0], indexmap, vSource, vSink);
2092 double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
2093 &color[0], indexmap, vSource, vSink);
2095 std::cout <<
"c The total flow:" << std::endl;
2096 std::cout <<
"s " << flow << std::endl << std::endl;
2098 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2100 o1 = it.getOffset();
2101 int val = imIn.pixelFromOffset(o1);
2104 imOut.setPixel(o1, 0);
2106 if (color[val] == color[vSource])
2107 imOut.setPixel(o1, 3);
2108 if (color[val] == 1)
2109 imOut.setPixel(o1, 4);
2110 if (color[val] == color[vSink])
2111 imOut.setPixel(o1, 2);
2124 template <
class ImageIn,
class ImageMosaic,
class ImageMarker,
class SE,
2126 RES_T geoCutsSegment_Graph(
const ImageIn &imIn,
const ImageMosaic &imMosaic,
2127 const ImageMarker &imMarker,
const SE &nl,
2130 SMIL_ENTER_FUNCTION(
"");
2132 std::cout <<
"Enter function optimize mosaic t_geoCutsSegment_Graph"
2135 if ((!imOut.isAllocated())) {
2136 SMIL_REGISTER_ERROR(
"Not allocated");
2137 return RES_NOT_ALLOCATED;
2140 if ((!imIn.isAllocated())) {
2141 SMIL_REGISTER_ERROR(
"Not allocated");
2142 return RES_NOT_ALLOCATED;
2145 if ((!imMosaic.isAllocated())) {
2146 SMIL_REGISTER_ERROR(
"Not allocated");
2147 return RES_NOT_ALLOCATED;
2150 if ((!imMarker.isAllocated())) {
2151 SMIL_REGISTER_ERROR(
"Not allocated");
2152 return RES_NOT_ALLOCATED;
2156 typename ImageIn::const_iterator it, iend;
2157 morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
2158 typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
2163 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
2166 typedef boost::adjacency_list<
2167 boost::listS, boost::vecS, boost::directedS,
2168 boost::property<boost::vertex_name_t, std::string>,
2170 boost::edge_capacity_t, double,
2171 boost::property<boost::edge_residual_capacity_t, double,
2172 boost::property<boost::edge_reverse_t,
2173 Traits::edge_descriptor>>>>
2180 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
2181 boost::get(boost::edge_capacity, g);
2183 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
2184 get(boost::edge_reverse, g);
2186 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
2187 residual_capacity = get(boost::edge_residual_capacity, g);
2190 Graph_d::edge_descriptor e1, e2, e3, e4;
2191 Graph_d::vertex_descriptor vSource, vSink;
2193 double meanclasse1 = 0.0;
2194 double meanclasse12 = 0.0;
2196 double meanclasse2 = 0.5;
2198 double sigma1 = 0.25;
2199 double sigma2 = 0.5;
2201 double max_value = 0.0;
2202 double max_longueur = 0.0;
2204 std::cout <<
"build Region Adjacency Graph" << std::endl;
2206 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2208 o0 = it.getOffset();
2209 int val = imMosaic.pixelFromOffset(o0);
2210 int val2 = imIn.pixelFromOffset(o0);
2211 int val3 = imMarker.pixelFromOffset(o0);
2213 if (val > numVert) {
2216 if (val2 > max_value) {
2219 if (val3 > max_longueur) {
2220 max_longueur = val3;
2224 std::cout <<
"build Region Adjacency Graph Vertices" << std::endl;
2226 std::cout <<
"Number of Vertices : " << numVert << std::endl;
2228 std::cout <<
"Max value : " << max_value << std::endl;
2230 for (
int i = 0; i <= numVert; i++) {
2231 boost::add_vertex(g);
2234 vSource = boost::add_vertex(g);
2235 vSink = boost::add_vertex(g);
2237 std::cout <<
"build Region Adjacency Graph Edges" << std::endl;
2239 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2241 o1 = it.getOffset();
2242 int val = imMosaic.pixelFromOffset(o1);
2245 boost::tie(e4, in1) = boost::edge(vSource, val, g);
2249 double valee = (double) imIn.pixelFromOffset(o1) / max_value;
2251 (double) imMarker.pixelFromOffset(o1) / max_longueur;
2253 double cost1 = 4 * (1 - longueur) + (valee - meanclasse1) *
2254 (valee - meanclasse1) /
2255 (2 * sigma1 * sigma1);
2256 double cost12 = 4 * (1 - longueur) + (valee - meanclasse12) *
2257 (valee - meanclasse12) /
2258 (2 * sigma1 * sigma1);
2259 double cost2 = 4 * (1 - 0.17) + (valee - meanclasse2) *
2260 (valee - meanclasse2) /
2261 (2 * sigma2 * sigma2);
2272 boost::tie(e4, in1) = boost::add_edge(vSource, val, g);
2273 boost::tie(e3, in1) = boost::add_edge(val, vSource, g);
2274 capacity[e4] = std::min(cost1, cost12);
2275 capacity[e3] = std::min(cost1, cost12);
2279 boost::tie(e4, in1) = boost::add_edge(vSink, val, g);
2280 boost::tie(e3, in1) = boost::add_edge(val, vSink, g);
2281 capacity[e4] = cost2;
2282 capacity[e3] = cost2;
2287 neighb.setCenter(o1);
2289 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
2290 const offset_t o2 = nit.getOffset();
2291 int val2 = imMosaic.pixelFromOffset(o2);
2294 if (val != val2 && val2 > 0) {
2295 boost::tie(e3, in1) = boost::edge(val, val2, g);
2297 double valee1 = (double) imIn.pixelFromOffset(o1) / max_value;
2298 double valee2 = (double) imIn.pixelFromOffset(o2) / max_value;
2301 (double) imMarker.pixelFromOffset(o1) / max_longueur;
2303 (double) imMarker.pixelFromOffset(o2) / max_longueur;
2305 double cost_diff = 0.01 *
std::exp(-0.01 * (valee1 - valee2) *
2307 double cost_longueur = 0.1;
2311 boost::tie(e4, in1) = boost::add_edge(val, val2, g);
2312 boost::tie(e3, in1) = boost::add_edge(val2, val, g);
2313 capacity[e4] = cost_longueur;
2314 capacity[e3] = cost_longueur;
2324 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
2325 boost::get(boost::vertex_index, g);
2326 std::vector<boost::default_color_type> color(boost::num_vertices(g));
2328 std::cout <<
"Compute Max flow" << std::endl;
2329 #if BOOST_VERSION >= 104700
2331 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
2332 &color[0], indexmap, vSource, vSink);
2334 double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
2335 &color[0], indexmap, vSource, vSink);
2337 std::cout <<
"c The total flow:" << std::endl;
2338 std::cout <<
"s " << flow << std::endl << std::endl;
2340 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2342 o1 = it.getOffset();
2343 int val = imMosaic.pixelFromOffset(o1);
2345 if (color[val] == color[vSource])
2346 imOut.setPixel(o1, 10);
2347 if (color[val] == 1)
2348 imOut.setPixel(o1, 0);
2349 if (color[val] == color[vSink])
2350 imOut.setPixel(o1, 30);
2362 template <
class ImageIn,
class ImageMosaic,
class ImageMarker,
typename _Beta,
2363 typename _Sigma,
class SE,
class ImageOut>
2364 RES_T MAP_MRF_edge_preserving(
2365 const ImageIn &imIn,
const ImageMosaic &imMosaic,
2366 const ImageMarker &imMarker,
const _Beta Beta,
const _Sigma Sigma,
2367 const SE &nl, ImageOut &imOut)
2369 SMIL_ENTER_FUNCTION(
"");
2371 std::cout <<
"Enter function t_MAP_MRF_edge_preserving" << std::endl;
2373 if ((!imOut.isAllocated())) {
2374 SMIL_REGISTER_ERROR(
"Not allocated");
2375 return RES_NOT_ALLOCATED;
2378 if ((!imIn.isAllocated())) {
2379 SMIL_REGISTER_ERROR(
"Not allocated");
2380 return RES_NOT_ALLOCATED;
2383 if ((!imMosaic.isAllocated())) {
2384 SMIL_REGISTER_ERROR(
"Not allocated");
2385 return RES_NOT_ALLOCATED;
2388 if ((!imMarker.isAllocated())) {
2389 SMIL_REGISTER_ERROR(
"Not allocated");
2390 return RES_NOT_ALLOCATED;
2394 typename ImageIn::const_iterator it, iend;
2395 morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
2396 typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
2401 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
2404 typedef boost::adjacency_list<
2405 boost::listS, boost::vecS, boost::directedS,
2406 boost::property<boost::vertex_name_t, std::string>,
2408 boost::edge_capacity_t, double,
2409 boost::property<boost::edge_residual_capacity_t, double,
2410 boost::property<boost::edge_reverse_t,
2411 Traits::edge_descriptor>>>>
2416 double sigma = Sigma;
2418 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
2419 boost::get(boost::edge_capacity, g);
2421 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
2422 get(boost::edge_reverse, g);
2424 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
2425 residual_capacity = get(boost::edge_residual_capacity, g);
2428 Graph_d::edge_descriptor e1, e2, e3, e4;
2429 Graph_d::vertex_descriptor vSource, vSink;
2432 std::cout <<
"build Region Adjacency Graph" << std::endl;
2434 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2436 o0 = it.getOffset();
2437 int val = imMosaic.pixelFromOffset(o0);
2438 imOut.setPixel(o0, 0);
2440 if (val > numVert) {
2445 double *
mean =
new double[numVert + 1];
2446 int *nb_val =
new int[numVert + 1];
2447 int *marker =
new int[numVert + 1];
2449 for (
int i = 0; i <= numVert; i++) {
2450 boost::add_vertex(g);
2456 vSource = boost::add_vertex(g);
2457 vSink = boost::add_vertex(g);
2459 double meanforeground = 0;
2460 double meanbackground = 0;
2461 double nb_foreground = 0;
2462 double nb_background = 0;
2464 std::cout <<
"Compute Mean Value in Regions" << std::endl;
2466 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2468 o0 = it.getOffset();
2469 int val = imIn.pixelFromOffset(o0);
2470 int val2 = imMosaic.pixelFromOffset(o0);
2471 int val3 = imMarker.pixelFromOffset(o0);
2472 double valeur = (double) val;
2474 mean[val2] =
mean[val2] + (valeur / 255.0);
2475 nb_val[val2] = nb_val[val2] + 1;
2478 meanforeground = meanforeground + (valeur / 255.0);
2481 }
else if (val3 == 3) {
2482 meanbackground = meanbackground + (valeur / 255.0);
2488 meanforeground = meanforeground / nb_foreground;
2489 meanbackground = meanbackground / nb_background;
2491 std::cout <<
"Mean Foreground " << meanforeground << std::endl;
2492 std::cout <<
"Mean Background " << meanbackground << std::endl;
2494 std::cout <<
"Compute terminal links" << std::endl;
2496 double sigmab = 0.2;
2498 for (
int i = 0; i <= numVert; i++) {
2501 if (marker[i] == 2 && nb_val[i] > 0) {
2502 boost::tie(e4, in1) = boost::add_edge(vSource, i, g);
2503 boost::tie(e3, in1) = boost::add_edge(i, vSource, g);
2504 capacity[e4] = (std::numeric_limits<double>::max)();
2505 capacity[e3] = (std::numeric_limits<double>::max)();
2508 }
else if (marker[i] == 3 && nb_val[i] > 0) {
2509 boost::tie(e4, in1) = boost::add_edge(vSink, i, g);
2510 boost::tie(e3, in1) = boost::add_edge(i, vSink, g);
2511 capacity[e4] = (std::numeric_limits<double>::max)();
2512 capacity[e3] = (std::numeric_limits<double>::max)();
2518 else if (nb_val[i] > 0) {
2519 double valee =
mean[i];
2520 double sigma = Sigma;
2521 double val2 = (valee - meanforeground) * (valee - meanforeground) /
2522 (2 * sigma * sigma);
2523 double val1 = (valee - meanbackground) * (valee - meanbackground) /
2524 (2 * sigmab * sigmab);
2526 boost::tie(e4, in1) = boost::add_edge(vSource, i, g);
2527 boost::tie(e3, in1) = boost::add_edge(i, vSource, g);
2528 capacity[e4] = nb_val[i] * val1;
2529 capacity[e3] = nb_val[i] * val1;
2533 boost::tie(e4, in1) = boost::add_edge(i, vSink, g);
2534 boost::tie(e3, in1) = boost::add_edge(vSink, i, g);
2535 capacity[e4] = nb_val[i] * val2;
2536 capacity[e3] = nb_val[i] * val2;
2542 std::cout <<
"build Region Adjacency Graph Edges" << std::endl;
2544 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2546 o1 = it.getOffset();
2547 int val = imMosaic.pixelFromOffset(o1);
2548 neighb.setCenter(o1);
2550 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
2551 const offset_t o2 = nit.getOffset();
2552 int val2 = imMosaic.pixelFromOffset(o2);
2556 boost::tie(e3, in1) = boost::edge(val, val2, g);
2557 double cost = (double) Beta -
2561 boost::tie(e4, in1) = boost::add_edge(val, val2, g);
2562 boost::tie(e3, in1) = boost::add_edge(val2, val, g);
2563 capacity[e4] = cost;
2564 capacity[e3] = cost;
2568 boost::tie(e4, in1) = boost::edge(val, val2, g);
2569 boost::tie(e3, in1) = boost::edge(val2, val, g);
2570 capacity[e4] = capacity[e4] + cost;
2571 capacity[e3] = capacity[e3] + cost;
2582 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
2583 boost::get(boost::vertex_index, g);
2584 std::vector<boost::default_color_type> color(boost::num_vertices(g));
2586 std::cout <<
"Compute Max flow" << std::endl;
2588 #if BOOST_VERSION >= 104700
2590 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
2591 &color[0], indexmap, vSource, vSink);
2593 double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
2594 &color[0], indexmap, vSource, vSink);
2596 std::cout <<
"c The total flow:" << std::endl;
2597 std::cout <<
"s " << flow << std::endl << std::endl;
2599 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2601 o1 = it.getOffset();
2602 int val = imMosaic.pixelFromOffset(o1);
2604 if (color[val] == color[vSource])
2605 imOut.setPixel(o1, 2);
2606 else if (color[val] == color[vSink])
2607 imOut.setPixel(o1, 3);
2609 imOut.setPixel(o1, 4);
2621 template <
class ImageIn,
class ImageMosaic,
class ImageMarker,
typename _Beta,
2622 typename _Sigma,
class SE,
class ImageOut>
2623 RES_T MAP_MRF_Ising(
const ImageIn &imIn,
const ImageMosaic &imMosaic,
2624 const ImageMarker &imMarker,
const _Beta Beta,
2625 const _Sigma Sigma,
const SE &nl, ImageOut &imOut)
2627 SMIL_ENTER_FUNCTION(
"");
2629 std::cout <<
"Enter function t_MAP_MRF_Ising" << std::endl;
2631 if ((!imOut.isAllocated())) {
2632 SMIL_REGISTER_ERROR(
"Not allocated");
2633 return RES_NOT_ALLOCATED;
2636 if ((!imIn.isAllocated())) {
2637 SMIL_REGISTER_ERROR(
"Not allocated");
2638 return RES_NOT_ALLOCATED;
2641 if ((!imMosaic.isAllocated())) {
2642 SMIL_REGISTER_ERROR(
"Not allocated");
2643 return RES_NOT_ALLOCATED;
2646 if ((!imMarker.isAllocated())) {
2647 SMIL_REGISTER_ERROR(
"Not allocated");
2648 return RES_NOT_ALLOCATED;
2653 typename ImageIn::const_iterator it, iend;
2654 morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
2655 typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
2660 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
2663 typedef boost::adjacency_list<
2664 boost::listS, boost::vecS, boost::directedS,
2665 boost::property<boost::vertex_name_t, std::string>,
2667 boost::edge_capacity_t, double,
2668 boost::property<boost::edge_residual_capacity_t, double,
2669 boost::property<boost::edge_reverse_t,
2670 Traits::edge_descriptor>>>>
2675 double sigma = Sigma;
2677 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
2678 boost::get(boost::edge_capacity, g);
2680 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
2681 get(boost::edge_reverse, g);
2683 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
2684 residual_capacity = get(boost::edge_residual_capacity, g);
2687 Graph_d::edge_descriptor e1, e2, e3, e4;
2688 Graph_d::vertex_descriptor vSource, vSink;
2691 std::cout <<
"build Region Adjacency Graph" << std::endl;
2693 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2695 o0 = it.getOffset();
2696 int val = imMosaic.pixelFromOffset(o0);
2697 imOut.setPixel(o0, 0);
2699 if (val > numVert) {
2704 double *
mean =
new double[numVert + 1];
2705 int *nb_val =
new int[numVert + 1];
2706 int *marker =
new int[numVert + 1];
2708 for (
int i = 0; i <= numVert; i++) {
2709 boost::add_vertex(g);
2715 vSource = boost::add_vertex(g);
2716 vSink = boost::add_vertex(g);
2718 double meanforeground = 0;
2719 double meanbackground = 0;
2720 double nb_foreground = 0;
2721 double nb_background = 0;
2723 std::cout <<
"Compute Mean Value in Regions" << std::endl;
2725 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2727 o0 = it.getOffset();
2728 int val = imIn.pixelFromOffset(o0);
2729 int val2 = imMosaic.pixelFromOffset(o0);
2730 int val3 = imMarker.pixelFromOffset(o0);
2731 double valeur = (double) val;
2733 mean[val2] =
mean[val2] + (valeur / 255.0);
2734 nb_val[val2] = nb_val[val2] + 1;
2737 meanforeground = meanforeground + (valeur / 255.0);
2740 }
else if (val3 == 3) {
2741 meanbackground = meanbackground + (valeur / 255.0);
2747 meanforeground = meanforeground / nb_foreground;
2748 meanbackground = meanbackground / nb_background;
2750 std::cout <<
"Mean Foreground " << meanforeground << std::endl;
2751 std::cout <<
"Mean Background " << meanbackground << std::endl;
2753 std::cout <<
"Compute terminal links" << std::endl;
2755 double sigmab = 0.2;
2758 for (
int i = 0; i <= numVert; i++) {
2761 if (marker[i] == 2 && nb_val[i] > 0) {
2762 boost::tie(e4, in1) = boost::add_edge(vSource, i, g);
2763 boost::tie(e3, in1) = boost::add_edge(i, vSource, g);
2764 capacity[e4] = (std::numeric_limits<double>::max)();
2765 capacity[e3] = (std::numeric_limits<double>::max)();
2768 }
else if (marker[i] == 3 && nb_val[i] > 0) {
2769 boost::tie(e4, in1) = boost::add_edge(vSink, i, g);
2770 boost::tie(e3, in1) = boost::add_edge(i, vSink, g);
2771 capacity[e4] = (std::numeric_limits<double>::max)();
2772 capacity[e3] = (std::numeric_limits<double>::max)();
2776 }
else if (nb_val[i] > 0) {
2777 double valee =
mean[i];
2778 double sigma = Sigma;
2779 double val2 = (valee - meanforeground) * (valee - meanforeground) /
2780 (2 * sigma * sigma);
2781 double val1 = (valee - meanbackground) * (valee - meanbackground) /
2782 (2 * sigmab * sigmab);
2784 boost::tie(e4, in1) = boost::add_edge(vSource, i, g);
2785 boost::tie(e3, in1) = boost::add_edge(i, vSource, g);
2786 capacity[e4] = nb_val[i] * val1;
2787 capacity[e3] = nb_val[i] * val1;
2791 boost::tie(e4, in1) = boost::add_edge(i, vSink, g);
2792 boost::tie(e3, in1) = boost::add_edge(vSink, i, g);
2793 capacity[e4] = nb_val[i] * val2;
2794 capacity[e3] = nb_val[i] * val2;
2804 std::cout <<
"build Region Adjacency Graph Edges" << std::endl;
2806 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2808 o1 = it.getOffset();
2809 int val = imMosaic.pixelFromOffset(o1);
2810 neighb.setCenter(o1);
2812 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
2813 const offset_t o2 = nit.getOffset();
2814 int val2 = imMosaic.pixelFromOffset(o2);
2818 boost::tie(e3, in1) = boost::edge(val, val2, g);
2819 double cost = (double) Beta;
2822 boost::tie(e4, in1) = boost::add_edge(val, val2, g);
2823 boost::tie(e3, in1) = boost::add_edge(val2, val, g);
2824 capacity[e4] = cost;
2825 capacity[e3] = cost;
2829 boost::tie(e4, in1) = boost::edge(val, val2, g);
2830 boost::tie(e3, in1) = boost::edge(val2, val, g);
2831 capacity[e4] = capacity[e4] + cost;
2832 capacity[e3] = capacity[e3] + cost;
2839 std::cout <<
"Number of vertices " << numVert << std::endl;
2840 std::cout <<
"Number of Edges " << numEdges << std::endl;
2842 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
2843 boost::get(boost::vertex_index, g);
2844 std::vector<boost::default_color_type> color(boost::num_vertices(g));
2846 std::cout <<
"Compute Max flow" << std::endl;
2847 #if BOOST_VERSION >= 104700
2849 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
2850 &color[0], indexmap, vSource, vSink);
2852 double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
2853 &color[0], indexmap, vSource, vSink);
2855 std::cout <<
"c The total flow:" << std::endl;
2856 std::cout <<
"s " << flow << std::endl << std::endl;
2858 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2860 o1 = it.getOffset();
2861 int val = imMosaic.pixelFromOffset(o1);
2863 if (color[val] == color[vSource])
2864 imOut.setPixel(o1, 2);
2865 else if (color[val] == color[vSink])
2866 imOut.setPixel(o1, 3);
2868 imOut.setPixel(o1, 4);
2880 template <
class ImageIn,
class ImageMosaic,
class ImageMarker,
typename _Beta,
2881 typename _Sigma,
class SE,
class ImageOut>
2882 RES_T MAP_MRF_Potts(
const ImageIn &imIn,
const ImageMosaic &imMosaic,
2883 const ImageMarker &imMarker,
const _Beta Beta,
2884 const _Sigma Sigma,
const SE &nl, ImageOut &imOut)
2886 SMIL_ENTER_FUNCTION(
"");
2888 std::cout <<
"Enter function t_MAP_MRF_Potts" << std::endl;
2890 if ((!imOut.isAllocated())) {
2891 SMIL_REGISTER_ERROR(
"Not allocated");
2892 return RES_NOT_ALLOCATED;
2895 if ((!imIn.isAllocated())) {
2896 SMIL_REGISTER_ERROR(
"Not allocated");
2897 return RES_NOT_ALLOCATED;
2900 if ((!imMosaic.isAllocated())) {
2901 SMIL_REGISTER_ERROR(
"Not allocated");
2902 return RES_NOT_ALLOCATED;
2905 if ((!imMarker.isAllocated())) {
2906 SMIL_REGISTER_ERROR(
"Not allocated");
2907 return RES_NOT_ALLOCATED;
2911 typename ImageIn::const_iterator it, iend;
2912 morphee::selement::Neighborhood<SE, ImageIn> neighb(imIn, nl);
2913 typename morphee::selement::Neighborhood<SE, ImageIn>::iterator nit, nend;
2918 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
2921 typedef boost::adjacency_list<
2922 boost::listS, boost::vecS, boost::directedS,
2923 boost::property<boost::vertex_name_t, std::string>,
2925 boost::edge_capacity_t, double,
2926 boost::property<boost::edge_residual_capacity_t, double,
2927 boost::property<boost::edge_reverse_t,
2928 Traits::edge_descriptor>>>>
2933 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
2934 boost::get(boost::edge_capacity, g);
2936 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
2937 get(boost::edge_reverse, g);
2939 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
2940 residual_capacity = get(boost::edge_residual_capacity, g);
2943 Graph_d::edge_descriptor e1, e2, e3, e4;
2944 Graph_d::vertex_descriptor vSource, vSink, vSource2, vSink2;
2948 double meanlabel1 = 0;
2949 double meanlabel2 = 0;
2950 double meanlabel3 = 0;
2952 double nb_label1 = 0;
2953 double nb_label2 = 0;
2954 double nb_label3 = 0;
2956 double Sigmal = (double) Sigma;
2958 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2960 o0 = it.getOffset();
2961 int val = imMosaic.pixelFromOffset(o0);
2963 imOut.setPixel(o0, 0);
2965 if (val > numVert) {
2970 double *
mean =
new double[numVert + 1];
2971 int *nb_val =
new int[numVert + 1];
2972 int *marker =
new int[numVert + 1];
2974 std::cout <<
"number of regions : " << numVert << std::endl;
2976 for (
int i = 0; i <= numVert; i++) {
2982 std::cout <<
"build Region Adjacency Graph" << std::endl;
2984 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
2986 o0 = it.getOffset();
2987 imOut.setPixel(o0, 0);
2989 int val = imIn.pixelFromOffset(o0);
2990 int val2 = imMosaic.pixelFromOffset(o0);
2991 int val3 = imMarker.pixelFromOffset(o0);
2993 double valeur = (double) val;
2995 mean[val2] =
mean[val2] + (valeur / 255.0);
2996 nb_val[val2] = nb_val[val2]++;
2999 meanlabel1 = meanlabel1 + (valeur / 255.0);
3002 }
else if (val3 == 3) {
3003 meanlabel2 = meanlabel2 + (valeur / 255.0);
3006 }
else if (val3 == 4) {
3007 meanlabel3 = meanlabel3 + (valeur / 255.0);
3013 meanlabel1 = meanlabel1 / nb_label1;
3014 meanlabel2 = meanlabel2 / nb_label2;
3015 meanlabel3 = meanlabel3 / nb_label3;
3017 std::cout <<
"Mean Label 1 " << meanlabel1 << std::endl;
3018 std::cout <<
"Mean Label 2 " << meanlabel2 << std::endl;
3019 std::cout <<
"Mean Label 3 " << meanlabel3 << std::endl;
3021 std::cout <<
"Compute terminal links" << std::endl;
3023 for (
int i = 0; i <= numVert; i++) {
3024 boost::add_vertex(g);
3028 vSource = boost::add_vertex(g);
3029 vSink = boost::add_vertex(g);
3031 for (
int i = 0; i <= numVert; i++) {
3032 if (marker[i] == 4 && nb_val[i] > 0) {
3033 boost::tie(e4, in1) = boost::add_edge(vSink, i, g);
3034 boost::tie(e3, in1) = boost::add_edge(i, vSink, g);
3035 capacity[e4] = (std::numeric_limits<double>::max)();
3036 capacity[e3] = (std::numeric_limits<double>::max)();
3039 }
else if (marker[i] > 0 && nb_val[i] > 0) {
3040 boost::tie(e4, in1) = boost::add_edge(vSource, i, g);
3041 boost::tie(e3, in1) = boost::add_edge(i, vSource, g);
3042 capacity[e4] = (std::numeric_limits<double>::max)();
3043 capacity[e3] = (std::numeric_limits<double>::max)();
3046 }
else if (nb_val[i] > 0) {
3047 double valee =
mean[i];
3050 (valee - meanlabel3) * (valee - meanlabel3) / (2 * 0.05 * 0.05);
3056 (valee - meanlabel1) * (valee - meanlabel1) / (2 * Sigmal * Sigmal);
3057 val3 = (valee - meanlabel2) * (valee - meanlabel2) / (2 * 0.2 * 0.2);
3059 boost::tie(e4, in1) = boost::add_edge(vSource, i, g);
3060 boost::tie(e3, in1) = boost::add_edge(i, vSource, g);
3061 capacity[e4] = val1;
3062 capacity[e3] = val1;
3066 boost::tie(e4, in1) = boost::add_edge(i, vSink, g);
3067 boost::tie(e3, in1) = boost::add_edge(vSink, i, g);
3068 capacity[e4] = std::min(val2, val3);
3069 capacity[e3] = std::min(val2, val3);
3075 std::cout <<
"build Region Adjacency Graph Edges" << std::endl;
3077 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
3079 o1 = it.getOffset();
3080 int val = imMosaic.pixelFromOffset(o1);
3081 neighb.setCenter(o1);
3083 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
3084 const offset_t o2 = nit.getOffset();
3085 int val2 = imMosaic.pixelFromOffset(o2);
3089 boost::tie(e3, in1) = boost::edge(val, val2, g);
3090 double cost = (double) Beta;
3092 boost::tie(e4, in1) = boost::add_edge(val, val2, g);
3093 boost::tie(e3, in1) = boost::add_edge(val2, val, g);
3094 capacity[e4] = cost;
3095 capacity[e3] = cost;
3099 boost::tie(e4, in1) = boost::edge(val, val2, g);
3100 boost::tie(e3, in1) = boost::edge(val2, val, g);
3101 capacity[e4] = capacity[e4] + cost;
3102 capacity[e3] = capacity[e3] + cost;
3109 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
3110 boost::get(boost::vertex_index, g);
3111 std::vector<boost::default_color_type> color(boost::num_vertices(g));
3113 std::cout <<
"Compute Max flow" << std::endl;
3114 #if BOOST_VERSION >= 104700
3116 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
3117 &color[0], indexmap, vSource, vSink);
3119 double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
3120 &color[0], indexmap, vSource, vSink);
3122 std::cout <<
"c The total flow:" << std::endl;
3123 std::cout <<
"s " << flow << std::endl << std::endl;
3125 std::cout <<
"Source Label:" << color[vSource] << std::endl;
3126 std::cout <<
"Sink Label:" << color[vSink] << std::endl;
3128 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
3130 o1 = it.getOffset();
3131 int valimout = imOut.pixelFromOffset(o1);
3132 int val = imMosaic.pixelFromOffset(o1);
3134 if (nb_val[val] > 0) {
3135 if (valimout == 0) {
3136 if (color[val] == 4)
3137 imOut.setPixel(o1, 4);
3144 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity2 =
3145 boost::get(boost::edge_capacity, g2);
3147 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev2 =
3148 get(boost::edge_reverse, g2);
3150 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
3151 residual_capacity2 = get(boost::edge_residual_capacity, g2);
3153 for (
int i = 0; i <= numVert; i++) {
3154 boost::add_vertex(g2);
3157 vSource2 = boost::add_vertex(g2);
3158 vSink2 = boost::add_vertex(g2);
3160 for (
int i = 0; i <= numVert; i++) {
3161 if (marker[i] == 3 && nb_val[i] > 0) {
3162 boost::tie(e4, in1) = boost::add_edge(vSink2, i, g2);
3163 boost::tie(e3, in1) = boost::add_edge(i, vSink2, g2);
3164 capacity2[e4] = (std::numeric_limits<double>::max)();
3165 capacity2[e3] = (std::numeric_limits<double>::max)();
3168 }
else if (marker[i] == 2 && nb_val[i] > 0) {
3169 boost::tie(e4, in1) = boost::add_edge(vSource2, i, g2);
3170 boost::tie(e3, in1) = boost::add_edge(i, vSource2, g2);
3171 capacity2[e4] = (std::numeric_limits<double>::max)();
3172 capacity2[e3] = (std::numeric_limits<double>::max)();
3175 }
else if (nb_val[i] > 0) {
3176 double valee =
mean[i];
3178 (valee - meanlabel2) * (valee - meanlabel2) / (2 * 0.2 * 0.2);
3180 (valee - meanlabel1) * (valee - meanlabel1) / (2 * Sigmal * Sigmal);
3182 boost::tie(e4, in1) = boost::add_edge(vSource2, i, g2);
3183 boost::tie(e3, in1) = boost::add_edge(i, vSource2, g2);
3184 capacity2[e4] = val1;
3185 capacity2[e3] = val1;
3189 boost::tie(e4, in1) = boost::add_edge(i, vSink2, g2);
3190 boost::tie(e3, in1) = boost::add_edge(vSink2, i, g2);
3191 capacity2[e4] = val2;
3192 capacity2[e3] = val2;
3198 std::cout <<
"build Region Adjacency Graph Edges" << std::endl;
3200 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
3202 o1 = it.getOffset();
3203 int val = imMosaic.pixelFromOffset(o1);
3204 neighb.setCenter(o1);
3206 for (nit = neighb.begin(), nend = neighb.end(); nit != nend; ++nit) {
3207 const offset_t o2 = nit.getOffset();
3208 int val2 = imMosaic.pixelFromOffset(o2);
3212 boost::tie(e3, in1) = boost::edge(val, val2, g2);
3213 double cost = (double) Beta;
3215 boost::tie(e4, in1) = boost::add_edge(val, val2, g2);
3216 boost::tie(e3, in1) = boost::add_edge(val2, val, g2);
3217 capacity2[e4] = cost;
3218 capacity2[e3] = cost;
3222 boost::tie(e4, in1) = boost::edge(val, val2, g2);
3223 boost::tie(e3, in1) = boost::edge(val2, val, g2);
3224 capacity2[e4] = capacity2[e4] + cost;
3225 capacity2[e3] = capacity2[e3] + cost;
3232 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap2 =
3233 boost::get(boost::vertex_index, g2);
3234 std::vector<boost::default_color_type> color2(boost::num_vertices(g2));
3236 std::cout <<
"Compute Max flow" << std::endl;
3237 #if BOOST_VERSION >= 104700
3238 flow = boykov_kolmogorov_max_flow(g2, capacity2, residual_capacity2, rev2,
3239 &color2[0], indexmap2, vSource2, vSink2);
3241 flow = kolmogorov_max_flow(g2, capacity2, residual_capacity2, rev2,
3242 &color2[0], indexmap2, vSource2, vSink2);
3244 std::cout <<
"c The total flow:" << std::endl;
3245 std::cout <<
"s " << flow << std::endl << std::endl;
3247 std::cout <<
"Source Label:" << color[vSource2] << std::endl;
3248 std::cout <<
"Sink Label:" << color[vSink2] << std::endl;
3250 for (it = imIn.begin(), iend = imIn.end(); it != iend; ++it) {
3252 o1 = it.getOffset();
3253 int valimout = imOut.pixelFromOffset(o1);
3254 int val = imMosaic.pixelFromOffset(o1);
3256 if (nb_val[val] > 0) {
3257 if (valimout == 0) {
3258 if (color2[val] == 4)
3259 imOut.setPixel(o1, 3);
3279 inline void printSE(StrElt ss)
3281 cout << indent <<
"Structuring Element" << endl;
3282 cout << indent <<
"Type: " << ss.seT << endl;
3283 cout << indent <<
"Size: " << ss.size << endl;
3284 size_t ptNbr = ss.points.size();
3285 cout << indent <<
"Point Nbr: " << ptNbr << endl;
3289 vector<IntPoint>::iterator itStart = ss.points.begin();
3290 vector<IntPoint>::iterator it, itEnd;
3291 itEnd = ss.points.end();
3293 vector<IntPoint> z(0);
3294 z = filterStrElt(ss);
3295 itStart = z.begin();
3297 for (it = itStart; it != itEnd; it++) {
3301 cout <<
" =================== " << endl;
3304 void testHandleSE(StrElt &se)
3310 int sz = se.getSize();
3311 se = se.homothety(sz);
3315 cout <<
"* width " << imIn.getWidth() << endl;
3316 cout <<
"* height " << imIn.getHeight() << endl;
3317 cout <<
"* depth " << imIn.getDepth() << endl;
RES_T sqrt(const Image< T1 > &imIn, Image< T2 > &imOut)
sqrt() - square root of an image
Definition: DImageArith.hpp:926
RES_T diff(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
diff() - Difference between two images.
Definition: DImageArith.hpp:448
RES_T exp(const Image< T1 > &imIn, Image< T2 > &imOut, int base=0)
exp() - exponential of an image
Definition: DImageArith.hpp:881
RES_T pow(const Image< T1 > &imIn, Image< T2 > &imOut, double exponent=2)
pow() - power of an image
Definition: DImageArith.hpp:905
RES_T mean(const Image< T > &imIn, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Mean filter.
Definition: DMorphoFilter.hpp:258
size_t label(const Image< T1 > &imIn, Image< T2 > &imOut, const StrElt &se=DEFAULT_SE)
label() - Image labelization
Definition: DMorphoLabel.hpp:564
T maxVal(const Image< T > &imIn, bool onlyNonZero=false)
maxVal() - Max value of an image
Definition: DMeasures.hpp:348
RES_T geoCutsMinSurfaces(const Image< T1 > &imIn, const Image< T2 > &imMarker, const StrElt &nl, Image< T2 > &imOut)
Geo Cuts algorithm on a pixel adjacency graph, ImMarker is composed of three values 0 for unmarked pi...
Definition: MinSurfaces.hpp:314