42 #ifndef _D_GEOCUTS_WATERSHED_HPP_
43 #define _D_GEOCUTS_WATERSHED_HPP_
50 #ifndef __BOOST_INCLUDED__
51 #define __BOOST_INCLUDED__
53 #include <boost/config.hpp>
55 #include <boost/utility.hpp>
57 #include <boost/graph/graph_traits.hpp>
58 #include <boost/graph/adjacency_list.hpp>
64 #include <boost/version.hpp>
68 #include "../boost_ext/kolmogorov_max_flow_min_cost.hpp"
72 #include <boost/graph/connected_components.hpp>
79 using namespace geocuts;
88 template <
class T1,
class T2>
90 const Image<T2> &imMarker,
const double Power,
93 std::cout <<
"Enter function Geo-Cuts Watershed" << std::endl;
95 ASSERT_ALLOCATED(&imIn, &imMarker, &imOut);
96 ASSERT_SAME_SIZE(&imIn, &imMarker, &imOut);
102 double exposant = Power;
105 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
109 typedef boost::adjacency_list<
110 boost::vecS, boost::vecS, boost::directedS,
111 boost::property<boost::vertex_name_t, std::string>,
113 boost::edge_capacity_t, double,
114 boost::property<boost::edge_residual_capacity_t, double,
115 boost::property<boost::edge_reverse_t,
116 Traits_d::edge_descriptor>>>>
121 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
122 boost::get(boost::edge_capacity, g);
124 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
125 get(boost::edge_reverse, g);
127 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
128 residual_capacity = get(boost::edge_residual_capacity, g);
130 Graph_d::edge_descriptor e1, e2, e3, e4;
131 Graph_d::vertex_descriptor vSource, vSink;
132 T1 numVertex =
maxVal(imIn);
135 std::cout <<
"build graph vertices" << std::endl;
136 std::cout <<
"number of vertices : " << numVertex << std::endl;
139 for (off_t i = 0; i < (off_t) pixelCount; i++) {
140 boost::add_vertex(g);
144 vSource = boost::add_vertex(g);
145 vSink = boost::add_vertex(g);
151 off_t strideY = width;
152 off_t strideZ = width * height;
153 for (
int z = 0; z < depth; z++) {
154 off_t p0Z = z * strideZ;
155 for (
int y = 0; y < height; y++) {
156 off_t p0Y = y * strideY;
157 for (
int x = 0; x < width; x++) {
158 off_t o1 = p0Z + p0Y + x;
161 vector<IntPoint> pts = filterStrElt(nl);
162 vector<IntPoint>::iterator itBegin, itEnd, it;
163 itBegin = pts.begin();
167 T2 marker = bufMarker[o1];
169 bool hasEdge =
false;
171 boost::tie(e4, hasEdge) = boost::add_edge(vSource, o1, g);
172 boost::tie(e3, hasEdge) = boost::add_edge(o1, vSource, g);
173 capacity[e4] = (std::numeric_limits<double>::max)();
174 capacity[e3] = (std::numeric_limits<double>::max)();
177 }
else if (marker == 3) {
178 boost::tie(e4, hasEdge) = boost::add_edge(o1, vSink, g);
179 boost::tie(e3, hasEdge) = boost::add_edge(vSink, o1, g);
180 capacity[e4] = (std::numeric_limits<double>::max)();
181 capacity[e3] = (std::numeric_limits<double>::max)();
186 for (it = itBegin; it != itEnd; it++) {
187 if (x + it->x > width - 1 || x + it->x < 0)
189 if (y + it->y > height - 1 || y + it->y < 0)
191 if (z + it->z > depth - 1 || z + it->z < 0)
194 off_t o2 = o1 + it->z * strideZ + it->y * strideY + it->x;
199 double valeur = (255.0 / (std::abs((
double) (val1 - val2)) + 1));
200 double cost =
std::pow(valeur, exposant);
202 bool hasEdge =
false;
203 boost::tie(e4, hasEdge) = boost::add_edge(o1, o2, g);
204 boost::tie(e3, hasEdge) = boost::add_edge(o2, o1, g);
214 std::cout <<
"Compute Max flow" << std::endl;
215 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
216 boost::get(boost::vertex_index, g);
217 std::vector<boost::default_color_type> color(boost::num_vertices(g));
218 #if BOOST_VERSION >= 104700
220 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
221 &color[0], indexmap, vSource, vSink);
223 double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
224 &color[0], indexmap, vSource, vSink);
226 std::cout <<
"c The total flow:" << std::endl;
227 std::cout <<
"s " << flow << std::endl << std::endl;
230 for (off_t o1 = 0; o1 < (off_t) pixelCount; o1++) {
231 if (color[o1] == color[vSource])
233 else if (color[o1] == color[vSink])
235 else if (color[o1] == 1)
247 template <
class T1,
class T2>
249 const Image<T2> &imMarker,
const double Power,
252 std::cout <<
"Enter function Multi way watershed" << std::endl;
253 ASSERT_ALLOCATED(&imIn, &imMarker, &imOut);
254 ASSERT_SAME_SIZE(&imIn, &imMarker, &imOut);
260 double exposant = Power;
263 typedef boost::adjacency_list_traits<boost::vecS, boost::vecS,
267 typedef boost::adjacency_list<
268 boost::vecS, boost::vecS, boost::directedS,
269 boost::property<boost::vertex_name_t, std::string>,
271 boost::edge_capacity_t, double,
272 boost::property<boost::edge_residual_capacity_t, double,
273 boost::property<boost::edge_reverse_t,
274 Traits_d::edge_descriptor>>>>
279 boost::property_map<Graph_d, boost::edge_capacity_t>::type capacity =
280 boost::get(boost::edge_capacity, g);
282 boost::property_map<Graph_d, boost::edge_reverse_t>::type rev =
283 get(boost::edge_reverse, g);
285 boost::property_map<Graph_d, boost::edge_residual_capacity_t>::type
286 residual_capacity = get(boost::edge_residual_capacity, g);
288 Graph_d::edge_descriptor e1, e2, e3, e4;
289 Graph_d::vertex_descriptor vSource, vSink;
290 T1 numVertex =
maxVal(imIn);
291 T2 numLabels =
maxVal(imMarker);
293 std::cout <<
"build graph vertices" << std::endl;
296 for (off_t i = 0; i < (off_t) pixelCount; i++) {
297 boost::add_vertex(g);
301 std::cout <<
"number of Labels: " << numLabels << std::endl;
302 std::cout <<
"number of vertices: " << numVertex << std::endl;
304 vSource = boost::add_vertex(g);
305 vSink = boost::add_vertex(g);
307 std::cout <<
"build graph edges" << std::endl;
313 off_t strideY = width;
314 off_t strideZ = width * height;
315 for (
int z = 0; z < depth; z++) {
316 off_t p0Z = z * strideZ;
317 for (
int y = 0; y < height; y++) {
318 off_t p0Y = y * strideY;
319 for (
int x = 0; x < width; x++) {
320 off_t o1 = p0Z + p0Y + x;
323 vector<IntPoint> pts = filterStrElt(nl);
324 vector<IntPoint>::iterator itBegin, itEnd, it;
325 itBegin = pts.begin();
330 for (it = itBegin; it != itEnd; it++) {
331 if (x + it->x > width - 1 || x + it->x < 0)
333 if (y + it->y > height - 1 || y + it->y < 0)
335 if (z + it->z > depth - 1 || z + it->z < 0)
338 off_t o2 = o1 + it->z * strideZ + it->y * strideY + it->x;
343 double valeur = (255.0 / (std::abs((
double) (val1 - val2)) + 1));
344 double cost =
std::pow(valeur, exposant);
346 bool hasEdge =
false;
347 boost::tie(e4, hasEdge) = boost::add_edge(o1, o2, g);
348 boost::tie(e3, hasEdge) = boost::add_edge(o2, o1, g);
358 for (T2 nbk = 2; nbk <= numLabels; nbk++) {
360 for (off_t o0 = 0; o0 < (off_t) pixelCount; o0++) {
361 T2 val1 = bufMarker[o0];
364 double cost = std::numeric_limits<double>::max();
367 boost::tie(e4, hasEdge) = boost::edge(vSource, o0, g);
369 boost::tie(e4, hasEdge) = boost::add_edge(vSource, o0, g);
370 boost::tie(e3, hasEdge) = boost::add_edge(o0, vSource, g);
376 }
else if (val1 > 1 && val1 != nbk) {
377 boost::tie(e4, hasEdge) = boost::edge(val2, vSink, g);
379 boost::tie(e4, hasEdge) = boost::add_edge(o0, vSink, g);
380 boost::tie(e3, hasEdge) = boost::add_edge(vSink, o0, g);
389 std::cout <<
"Compute Max flow" << std::endl;
390 boost::property_map<Graph_d, boost::vertex_index_t>::type indexmap =
391 boost::get(boost::vertex_index, g);
392 std::vector<boost::default_color_type> color(boost::num_vertices(g));
393 #if BOOST_VERSION >= 104700
395 boykov_kolmogorov_max_flow(g, capacity, residual_capacity, rev,
396 &color[0], indexmap, vSource, vSink);
398 double flow = kolmogorov_max_flow(g, capacity, residual_capacity, rev,
399 &color[0], indexmap, vSource, vSink);
401 std::cout <<
"c The total flow:" << std::endl;
402 std::cout <<
"s " << flow << std::endl << std::endl;
405 for (off_t o1 = 0; o1 < (off_t) pixelCount; o1++) {
406 T1 val1 = (int) bufIn[o1];
407 T2 val2 = (int) bufOut[o1];
408 T2 val3 = (int) bufMarker[o1];
411 if (color[val1] == color[vSource])
412 bufOut[o1] = (T2) nbk;
417 boost::tie(e4, hasEdge) = boost::edge(vSource, o1, g);
419 boost::remove_edge(vSource, o1, g);
420 boost::remove_edge(o1, vSource, g);
422 }
else if (val3 > 1) {
423 boost::tie(e4, hasEdge) = boost::edge(o1, vSink, g);
425 boost::remove_edge(o1, vSink, g);
426 boost::remove_edge(vSink, o1, g);
size_t getDepth() const
Get image depth (Z)
Definition: DBaseImage.h:90
size_t getWidth() const
Get image width.
Definition: DBaseImage.h:80
size_t getPixelCount() const
Get the number of pixels.
Definition: DBaseImage.h:160
size_t getHeight() const
Get image height.
Definition: DBaseImage.h:85
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:105
Base structuring element.
Definition: DStructuringElement.h:68
RES_T pow(const Image< T1 > &imIn, Image< T2 > &imOut, double exponent=2)
pow() - power of an image
Definition: DImageArith.hpp:905
T maxVal(const Image< T > &imIn, bool onlyNonZero=false)
maxVal() - Max value of an image
Definition: DMeasures.hpp:348
RES_T geoCutsMultiway_Watershed(const Image< T1 > &imIn, const Image< T2 > &imMarker, const double Power, const StrElt &nl, Image< T2 > &imOut)
Watershed as a mutli_terminal cut (multi label)
Definition: Watershed.hpp:248
RES_T geoCutsWatershed_MinCut(const Image< T1 > &imIn, const Image< T2 > &imMarker, const double Power, const StrElt &nl, Image< T2 > &imOut)
Watershed as a Minimum Cut (2 labels)
Definition: Watershed.hpp:89