DGtal  1.5.beta
SaturatedSegmentation.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file SaturatedSegmentation.ih
19  * @author Tristan Roussillon (\c tristan.roussillon@liris.cnrs.fr )
20  * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
21  *
22  * @date 2011/07/21
23  *
24  * Implementation of inline methods defined in SaturatedSegmentation.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 
30 //////////////////////////////////////////////////////////////////////////////
31 #include <cstdlib>
32 //////////////////////////////////////////////////////////////////////////////
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 // IMPLEMENTATION of inline methods.
36 ///////////////////////////////////////////////////////////////////////////////
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 // class SaturatedSegmentation::SegmentComputerIterator
40 ///////////////////////////////////////////////////////////////////////////////
41 
42 
43 //////////////////////////////////////////////////////////////////////////////
44 // ------------------------- Some processings -----------------------
45 //////////////////////////////////////////////////////////////////////////////
46 
47 
48  template <typename TSegmentComputer>
49 inline
50 bool
51 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::doesIntersectNext(const ConstIterator& it, const ConstIterator& itb, const ConstIterator& ite)
52 {
53  typedef typename IteratorCirculatorTraits<typename SegmentComputer::ConstIterator>::Type Type;
54  return this->doesIntersectNext( it, itb, ite, Type() );
55 }
56 
57 
58 template <typename TSegmentComputer>
59 inline
60 bool
61 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::doesIntersectNext(const ConstIterator& it, const ConstIterator& itb, const ConstIterator& ite, IteratorType )
62 {
63  ConstIterator previousIt(it);
64  if ( (it != itb)&&(it != ite) ) {
65  --previousIt;
66  SegmentComputer tmpSegmentComputer=mySegmentComputer.getSelf();
67  tmpSegmentComputer.init(previousIt);
68  return tmpSegmentComputer.extendFront();
69  }
70  else
71  {
72  return false;
73  }
74 }
75 
76  template <typename TSegmentComputer>
77 inline
78 bool
79 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::doesIntersectNext(const ConstIterator& it,
80  const ConstIterator& /*itb*/,
81  const ConstIterator& /*ite*/,
82  CirculatorType )
83 {
84  return this->doesIntersectNext(it);
85 }
86 
87 
88  template <typename TSegmentComputer>
89 inline
90 bool
91 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::doesIntersectNext(const ConstIterator& it)
92 {
93  ConstIterator previousIt(it); --previousIt;
94 
95  SegmentComputer tmpSegmentComputer=mySegmentComputer.getSelf();
96  tmpSegmentComputer.init(previousIt);
97  return tmpSegmentComputer.extendFront();
98 }
99 
100 
101  template <typename TSegmentComputer>
102 inline
103 void
104 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::initFirstMaximalSegment()
105 {
106  if ( (myS->myMode == "First") || (myS->myMode == "First++") ) {
107  DGtal::firstMaximalSegment(mySegmentComputer, myS->myStart, myS->myBegin, myS->myEnd);
108  }
109  else
110  if ( (myS->myMode == "Last") || (myS->myMode == "Last++") ) {
111  DGtal::lastMaximalSegment(mySegmentComputer, myS->myStart, myS->myBegin, myS->myEnd);
112  }
113  else { // (myS->myMode == "MostCentered") or (myS->myMode == "MostCentered++")
114  DGtal::mostCenteredMaximalSegment(mySegmentComputer, myS->myStart, myS->myBegin, myS->myEnd);
115  }
116 }
117 
118 
119  template <typename TSegmentComputer>
120 inline
121 void
122 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::initLastMaximalSegment()
123 {
124 
125  ConstIterator i(myS->myStop);
126 
127  if (isNotEmpty(myS->myStop,myS->myEnd)) {
128 
129  if ((myS->myMode == "First")||(myS->myMode == "First++")) {
130  DGtal::firstMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
131  }
132  else
133  if ((myS->myMode == "Last")||(myS->myMode == "Last++")) {
134  DGtal::lastMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
135  }
136  else { // (myS->myMode == "MostCentered") or (myS->myMode == "MostCentered++")
137  DGtal::mostCenteredMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
138  }
139 
140  DGtal::previousMaximalSegment(mySegmentComputer, myS->myBegin );
141 
142  } else { //processing of a whole linear range
143  --i; //set i to the last point (not past-to-last)
144  if ((myS->myMode == "First")||(myS->myMode == "First++")) {
145 
146  DGtal::firstMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
147  }
148  else
149  if ((myS->myMode == "Last")||(myS->myMode == "Last++")) {
150  DGtal::lastMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
151  }
152  else { // (myS->myMode == "MostCentered") or (myS->myMode == "MostCentered++")
153  DGtal::mostCenteredMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
154  }
155 
156  }
157 
158  if ((myS->myMode == "MostCentered++") || (myS->myMode == "First++") || (myS->myMode == "Last++"))
159  { //take the next maximal segment in the "++" modes
160  DGtal::nextMaximalSegment(mySegmentComputer, myS->myEnd);
161  }
162 
163  myLastMaximalSegmentBegin = mySegmentComputer.begin();
164  myLastMaximalSegmentEnd = mySegmentComputer.end();
165 
166 }
167 
168 
169 
170  template <typename TSegmentComputer>
171 inline
172 void
173 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::nextMaximalSegment()
174 {
175 
176  if ( myFlagIsLast ) { //if end
177 
178  myFlagIsValid = false;
179 
180  } else { //otherwise
181 
182  myFlagIntersectPrevious = myFlagIntersectNext;
183 
184  DGtal::nextMaximalSegment(mySegmentComputer, myS->myEnd );
185 
186  if ( (mySegmentComputer.begin() == myLastMaximalSegmentBegin)
187  &&(mySegmentComputer.end() == myLastMaximalSegmentEnd) ) { //if only one segment
188 
189  myFlagIntersectNext = doesIntersectNext( mySegmentComputer.end(), myS->myBegin, myS->myEnd );
190  myFlagIsLast = true;
191 
192  } else { //otherwise
193  myFlagIntersectNext = doesIntersectNext( mySegmentComputer.end() );
194  }
195 
196  }
197 
198 }
199 
200 
201 
202 //////////////////////////////////////////////////////////////////////////////
203 // ------------------------- Standard services -----------------------
204 //////////////////////////////////////////////////////////////////////////////
205 
206 
207  template <typename TSegmentComputer>
208 inline
209 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::SegmentComputerIterator (
210  const SaturatedSegmentation<TSegmentComputer> *s,
211  const TSegmentComputer& aSegmentComputer,
212  const bool& aIsValid )
213  : myS( s ),
214  mySegmentComputer( aSegmentComputer ),
215  myFlagIsValid( aIsValid ),
216  myFlagIntersectNext( false ),
217  myFlagIntersectPrevious( false ),
218  myFlagIsLast( false )
219  {
220 
221  if (myFlagIsValid) {
222  if ( isNotEmpty<ConstIterator>(myS->myStart, myS->myStop) )
223  { //if at least one element
224 
225  this->initLastMaximalSegment();
226  this->initFirstMaximalSegment();
227 
228  myFlagIntersectPrevious = doesIntersectNext( mySegmentComputer.begin(), myS->myBegin, myS->myEnd );
229 
230  if ( (mySegmentComputer.begin() == myLastMaximalSegmentBegin)
231  &&(mySegmentComputer.end() == myLastMaximalSegmentEnd) )
232  { //if only one segment
233 
234  myFlagIntersectNext = doesIntersectNext( mySegmentComputer.end(), myS->myBegin, myS->myEnd );
235  myFlagIsLast = true;
236 
237  } else //otherwise
238  {
239  myFlagIntersectNext = doesIntersectNext( mySegmentComputer.end() );
240  }
241 
242  }
243  else
244  {
245  myFlagIsValid = false;
246  }
247  }
248  }
249 
250 template <typename TSegmentComputer>
251 inline
252 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::SegmentComputerIterator
253 ( const SegmentComputerIterator & other )
254  : myS( other.myS ),
255  mySegmentComputer( other.mySegmentComputer ),
256  myFlagIsValid( other.myFlagIsValid ),
257  myLastMaximalSegmentBegin( other.myLastMaximalSegmentBegin ),
258  myLastMaximalSegmentEnd( other.myLastMaximalSegmentEnd ),
259  myFlagIntersectNext( other.myFlagIntersectNext ),
260  myFlagIntersectPrevious( other.myFlagIntersectPrevious ) ,
261  myFlagIsLast( other.myFlagIsLast )
262 {
263 }
264 
265 
266  template <typename TSegmentComputer>
267 inline
268 typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator&
269 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator=
270 ( const SegmentComputerIterator & other )
271 {
272  if ( this != &other )
273  {
274  myS = other.myS;
275  mySegmentComputer = other.mySegmentComputer;
276  myFlagIsValid = other.myFlagIsValid;
277  myLastMaximalSegmentBegin = other.myLastMaximalSegmentBegin;
278  myLastMaximalSegmentEnd = other.myLastMaximalSegmentEnd;
279  myFlagIntersectNext = other.myFlagIntersectNext;
280  myFlagIntersectPrevious = other.myFlagIntersectPrevious;
281  myFlagIsLast = other.myFlagIsLast;
282  }
283  return *this;
284 }
285 
286 
287  template <typename TSegmentComputer>
288 inline
289 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::~SegmentComputerIterator()
290 {
291 }
292 
293 ///////////////////////////////////////////////////////////////////////////////
294 // ------------------------- iteration services -------------------------
295 //////////////////////////////////////////////////////////////////////////////
296 
297 
298  template <typename TSegmentComputer>
299 inline
300 const TSegmentComputer&
301 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator*() const
302 {
303  return mySegmentComputer;
304 }
305 
306 
307  template <typename TSegmentComputer>
308 inline
309 const TSegmentComputer*
310 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator->() const
311 {
312  return &mySegmentComputer;
313 }
314 
315 
316  template <typename TSegmentComputer>
317 inline
318 TSegmentComputer
319 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::get() const
320 {
321  return mySegmentComputer;
322 }
323 
324 
325  template <typename TSegmentComputer>
326 inline
327 typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator &
328 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator++()
329 {
330  this->nextMaximalSegment();
331  return *this;
332 }
333 
334 
335  template <typename TSegmentComputer>
336 inline
337 bool
338 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator==
339 ( const SegmentComputerIterator & other ) const
340 {
341  if ( isValid() )
342  return ( (other.isValid() ) &&
343 ( mySegmentComputer.begin() == other.mySegmentComputer.begin() ) &&
344 ( mySegmentComputer.end() == other.mySegmentComputer.end() ) );
345  else
346  return ( ! other.isValid() );
347 
348 }
349 
350  template <typename TSegmentComputer>
351 inline
352 bool
353 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator!=
354 ( const SegmentComputerIterator & other ) const
355 {
356  return !(*this == other);
357 }
358 
359 //////////////////////////////////////////////////////////////////////////////
360 // ------------------------- accessors -------------------------
361 //////////////////////////////////////////////////////////////////////////////
362 
363  template <typename TSegmentComputer>
364 inline
365 bool
366 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::intersectNext() const
367 {
368  return myFlagIntersectNext;
369 }
370 
371  template <typename TSegmentComputer>
372 inline
373 bool
374 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::intersectPrevious() const
375 {
376  return myFlagIntersectPrevious;
377 }
378 
379 
380 
381  template <typename TSegmentComputer>
382 inline
383 const typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::ConstIterator
384 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::begin() const
385 {
386  return mySegmentComputer.begin();
387 }
388 
389  template <typename TSegmentComputer>
390 inline
391 const typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::ConstIterator
392 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::end() const
393 {
394  return mySegmentComputer.end();
395 }
396 
397 
398 
399 ///////////////////////////////////////////////////////////////////////////////
400 // class SaturatedSegmentation
401 ///////////////////////////////////////////////////////////////////////////////
402 
403 ///////////////////////////////////////////////////////////////////////////////
404 // Interface - public :
405 
406 
407  template <typename TSegmentComputer>
408 DGtal::SaturatedSegmentation<TSegmentComputer>::SaturatedSegmentation
409 (const ConstIterator& itb, const ConstIterator& ite, const SegmentComputer& aSegmentComputer)
410  : myBegin(itb),
411  myEnd(ite),
412  myStart(itb),
413  myStop(ite),
414  myMode("MostCentered"),
415  mySegmentComputer(aSegmentComputer)
416 {
417 }
418 
419 
420  template <typename TSegmentComputer>
421 inline
422 void
423 DGtal::SaturatedSegmentation<TSegmentComputer>::setSubRange
424 (const ConstIterator& itb, const ConstIterator& ite)
425 {
426  myStart = itb;
427  myStop = ite;
428  myMode = "MostCentered";
429 }
430 
431  template <typename TSegmentComputer>
432 inline
433 void
434 DGtal::SaturatedSegmentation<TSegmentComputer>::setMode
435 (const std::string& aMode)
436 {
437  if ( (aMode == "First") || (aMode == "Last") || (aMode == "MostCentered")
438  || (aMode == "First++") || (aMode == "Last++") || (aMode == "MostCentered++") )
439  myMode = aMode;
440  else
441  {
442  std::cerr << "[DGtal::SaturatedSegmentation<TSegmentComputer>::setMode(const std::string& aMode)]"
443  << " ERROR. Unknown mode." << std::endl;
444  throw InputException();
445  }
446 }
447 
448 
449  template <typename TSegmentComputer>
450 inline
451 DGtal::SaturatedSegmentation<TSegmentComputer>::~SaturatedSegmentation()
452 {
453 }
454 
455 
456  template <typename TSegmentComputer>
457 inline
458 typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator
459 DGtal::SaturatedSegmentation<TSegmentComputer>::begin() const
460 {
461  return SegmentComputerIterator(this, mySegmentComputer, true);
462 }
463 
464 
465  template <typename TSegmentComputer>
466 inline
467 typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator
468 DGtal::SaturatedSegmentation<TSegmentComputer>::end() const
469 {
470  return SegmentComputerIterator(this, mySegmentComputer, false);
471 }
472 
473 
474 
475  template <typename TSegmentComputer>
476 inline
477 void
478 DGtal::SaturatedSegmentation<TSegmentComputer>::selfDisplay ( std::ostream & out ) const
479 {
480  out << "[SaturatedSegmentation]";
481 }
482 
483 
484  template <typename TSegmentComputer>
485 inline
486 bool
487 DGtal::SaturatedSegmentation<TSegmentComputer>::isValid() const
488 {
489  return true;
490 }
491 
492 
493 
494 ///////////////////////////////////////////////////////////////////////////////
495 // Implementation of inline functions //
496 
497  template <typename TSegmentComputer>
498 inline
499 std::ostream&
500 DGtal::operator<< ( std::ostream & out,
501  const SaturatedSegmentation<TSegmentComputer> & object )
502 {
503  object.selfDisplay( out );
504  return out;
505 }
506 
507 // //
508 ///////////////////////////////////////////////////////////////////////////////
509 
510