bioprocessing 6.0.4
coustywatershed.h
Go to the documentation of this file.
1/* Copyright (C) 2000-2013 CEA
2 *
3 * This software and supporting documentation were developed by
4 * bioPICSEL
5 * CEA/DSV/I²BM/MIRCen/LMN, Batiment 61,
6 * 18, route du Panorama
7 * 92265 Fontenay-aux-Roses
8 * France
9 */
10
11#ifndef BIOPROCESSING_WATERSHED_COUSTY
12#define BIOPROCESSING_WATERSHED_COUSTY
13
14//--- bioprocessing ----------------------------------------------------------
15#include <bioprocessing/watershed/coustyflowmap.h> // bio::CoustyflowMapRef
16#include <bioprocessing/watershed/coustystream.h> // bio::CoustyStremRef
17#include <bioprocessing/graph/volumegraph.h> // bio::VolumeGraphRef
18//--- aims -------------------------------------------------------------------
19#include <aims/vector/vector.h> // Point*
20//--- cartodata --------------------------------------------------------------
21#include <cartodata/volume/volume.h> // carto::VolumeRef
22//--- cartobase --------------------------------------------------------------
23#include <cartobase/config/verbose.h> // carto::verbose
24//--- std --------------------------------------------------------------------
25#include <iostream> // std::cout, std::endl
26//----------------------------------------------------------------------------
27
28namespace bio {
29 //==========================================================================
30 // COUSTY'S WATERSHED (Cousty et al, IEEE PAMI 2007)
31 //==========================================================================
38 template <typename T, typename L>
40 {
41 //--- typedef ------------------------------------------------------------
42 public:
43 typedef Point4dl Point;
45 typedef typename Graph::Vertex Vertex;
46 typedef typename Graph::Edge Edge;
49
50 //--- constructor --------------------------------------------------------
51 public:
52 CoustyWatershed(): _g(), _s(), _psi(), _verbose(carto::verbose), _3d(true) {}
54
55 //--- properties ---------------------------------------------------------
56 public:
57 void setVerbose( int verbose = 1 ) { _verbose = verbose; }
58 void setQuiet() { setVerbose(0); }
60 void set3D() { _3d = true; }
62 void set2D() { _3d = false; }
63
64 //--- implementation -----------------------------------------------------
65 public:
67 carto::VolumeRef<L> execute( carto::VolumeRef<T> in );
70 void execute( carto::VolumeRef<T> in, carto::VolumeRef<L> out );
71 carto::VolumeRef<L> getMinima() { return _psi.getMinima(); }
72
73 //--- helpers ------------------------------------------------------------
74 protected:
79 void computeWatershed();
81 L computeStream( Vertex x );
83 bool findEdge( Vertex y, Vertex & z );
85 void setLabel( L lab );
86
87 //--- members ------------------------------------------------------------
88 protected:
93 bool _3d;
94 };
95
96 //==========================================================================
97 // DEFINITION
98 //==========================================================================
99 //
100 template <typename T, typename L>
101 carto::VolumeRef<L> CoustyWatershed<T,L>::execute( carto::VolumeRef<T> in )
102 {
103 carto::VolumeRef<L> out( in.getSizeX(), in.getSizeY(),
104 in.getSizeZ(), in.getSizeT() );
105 out->copyHeaderFrom( in.header() );
106 execute( in, out );
107 return out;
108 }
109
110 template <typename T, typename L>
111 void CoustyWatershed<T,L>::execute( carto::VolumeRef<T> in,
112 carto::VolumeRef<L> out )
113 {
114 if( _3d )
115 _g = Graph( in, aims::strel::Connectivity6XYZ() );
116 else
117 _g = Graph( in, aims::strel::Connectivity4XY() );
118 _s = Stream();
119 _psi.setVolume( out );
120 _psi.init( _g.beginVertex(), _g.endVertex() );
122 }
123
124 template <typename T, typename L>
126 {
127 Vertex x;
128 L nb_labs = 0;
129 L lab;
130 typename FlowMap::iterator i;
131
132 int j=0;
133 long size = _psi.size();
134 if( _verbose )
135 std::cout << std::endl;
136 for( i = _psi.begin() ; i != _psi.end(); ++i )
137 {
138 if( _verbose && ( ++j % 10000 == 0 ) )
139 std::cout << "\rVertex: " << j << "/" << size << std::flush;
140 x = i->first;
141 lab = i->second;
142 if( lab == _psi.labelNone() )
143 {
144 lab = computeStream( x );
145 if( lab == _psi.labelMinus() )
146 setLabel( ++nb_labs );
147 else {
148 setLabel( lab );
149 }
150 }
151 }
152 if( _verbose )
153 std::cout << std::endl << "Labels created: " << nb_labs << std::endl;
154 }
155
156 template <typename T, typename L>
158 {
159 typename Stream::iterator i;
160 for( i = _s.begin(); i != _s.end(); ++i )
161 {
162 _psi.setLabel( *i, lab );
163 }
164 }
165
166 template <typename T, typename L>
168 {
169 _s.reset( x );
170 Stream s2( x );
171 bool breadth_first;
172 Vertex y, z;
173 L lab;
174
175 while( !s2.empty() )
176 {
177 y = *(s2.begin());
178 s2.erase( s2.begin() );
179 breadth_first = true;
180 while( breadth_first && findEdge( y, z ) )
181 {
182 lab = _psi.label(z);
183 if( lab != _psi.labelNone() )
184 return lab;
185 else if( _g.Fm( z ) < _g.Fm( y ) )
186 {
187 _s.insert( z );
188 s2.reset( z );
189 breadth_first = false;
190 }
191 else
192 {
193 _s.insert( z );
194 s2.insert( z );
195 }
196 }
197 }
198 _psi.setMinimum(y);
199 return _psi.labelMinus();
200 }
201
202 template <typename T, typename L>
204 {
205 typename Graph::edge_iterator e;
206 for( e = _g.beginEdge(y); e != _g.endEdge(y); ++e )
207 {
208 z = e->other( y );
209 if( !_s.count( z ) )
210 {
211 if( _g.weight( *e ) == _g.Fm( y ) )
212 return true;
213 }
214 }
215 z = Vertex::none();
216 return false;
217 }
218
219} // namesapce bio
220
221#endif // BIOPROCESSING_WATERSHED_COUSTY
Reference counting pointer to a CoustyFlowMap.
Reference counting pointer to a CoustyStream.
void erase(const Vertex &v)
std::pair< iterator, bool > insert(const Vertex &v)
const_iterator begin() const
void reset(Vertex x)
L computeStream(Vertex x)
Follows the descent stream from vertex v.
Point4dl Point
Point type.
carto::VolumeRef< L > execute(carto::VolumeRef< T > in)
Allocate and return the watershed segmentation of the input image.
void computeWatershed()
Iterates on the vertices of the image, and for each one follows a descent stream until it encounters ...
carto::VolumeRef< L > getMinima()
Graph::Vertex Vertex
Vertex type.
VolumeGraphRef< T, Point > Graph
Graph type.
void set2D()
When 2D mode is active, a 2D connectivity is used (4XY)
bool findEdge(Vertex y, Vertex &z)
Finds an edge of minimum altitude for y.
CoustyFlowMapRef< Vertex, L > FlowMap
FlowMap type (the labelled image)
void setVerbose(int verbose=1)
Graph::Edge Edge
Edge type.
CoustyStreamRef< Vertex > Stream
Stream type (a set of vertices)
void set3D()
When 3D mode is active, a 3D connectivity is used (6XYZ)
void setLabel(L lab)
Sets the label lab for all vertices in the stream _s.
Reference to a VolumeGraph.
Pointed::edge_iterator edge_iterator