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.
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.
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/>.
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
24 * Implementation of inline methods defined in SaturatedSegmentation.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
32 //////////////////////////////////////////////////////////////////////////////
34 ///////////////////////////////////////////////////////////////////////////////
35 // IMPLEMENTATION of inline methods.
36 ///////////////////////////////////////////////////////////////////////////////
38 ///////////////////////////////////////////////////////////////////////////////
39 // class SaturatedSegmentation::SegmentComputerIterator
40 ///////////////////////////////////////////////////////////////////////////////
43 //////////////////////////////////////////////////////////////////////////////
44 // ------------------------- Some processings -----------------------
45 //////////////////////////////////////////////////////////////////////////////
48 template <typename TSegmentComputer>
51 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::doesIntersectNext(const ConstIterator& it, const ConstIterator& itb, const ConstIterator& ite)
53 typedef typename IteratorCirculatorTraits<typename SegmentComputer::ConstIterator>::Type Type;
54 return this->doesIntersectNext( it, itb, ite, Type() );
58 template <typename TSegmentComputer>
61 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::doesIntersectNext(const ConstIterator& it, const ConstIterator& itb, const ConstIterator& ite, IteratorType )
63 ConstIterator previousIt(it);
64 if ( (it != itb)&&(it != ite) ) {
66 SegmentComputer tmpSegmentComputer=mySegmentComputer.getSelf();
67 tmpSegmentComputer.init(previousIt);
68 return tmpSegmentComputer.extendFront();
76 template <typename TSegmentComputer>
79 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::doesIntersectNext(const ConstIterator& it,
80 const ConstIterator& /*itb*/,
81 const ConstIterator& /*ite*/,
84 return this->doesIntersectNext(it);
88 template <typename TSegmentComputer>
91 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::doesIntersectNext(const ConstIterator& it)
93 ConstIterator previousIt(it); --previousIt;
95 SegmentComputer tmpSegmentComputer=mySegmentComputer.getSelf();
96 tmpSegmentComputer.init(previousIt);
97 return tmpSegmentComputer.extendFront();
101 template <typename TSegmentComputer>
104 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::initFirstMaximalSegment()
106 if ( (myS->myMode == "First") || (myS->myMode == "First++") ) {
107 DGtal::firstMaximalSegment(mySegmentComputer, myS->myStart, myS->myBegin, myS->myEnd);
110 if ( (myS->myMode == "Last") || (myS->myMode == "Last++") ) {
111 DGtal::lastMaximalSegment(mySegmentComputer, myS->myStart, myS->myBegin, myS->myEnd);
113 else { // (myS->myMode == "MostCentered") or (myS->myMode == "MostCentered++")
114 DGtal::mostCenteredMaximalSegment(mySegmentComputer, myS->myStart, myS->myBegin, myS->myEnd);
119 template <typename TSegmentComputer>
122 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::initLastMaximalSegment()
125 ConstIterator i(myS->myStop);
127 if (isNotEmpty(myS->myStop,myS->myEnd)) {
129 if ((myS->myMode == "First")||(myS->myMode == "First++")) {
130 DGtal::firstMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
133 if ((myS->myMode == "Last")||(myS->myMode == "Last++")) {
134 DGtal::lastMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
136 else { // (myS->myMode == "MostCentered") or (myS->myMode == "MostCentered++")
137 DGtal::mostCenteredMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
140 DGtal::previousMaximalSegment(mySegmentComputer, myS->myBegin );
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++")) {
146 DGtal::firstMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
149 if ((myS->myMode == "Last")||(myS->myMode == "Last++")) {
150 DGtal::lastMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
152 else { // (myS->myMode == "MostCentered") or (myS->myMode == "MostCentered++")
153 DGtal::mostCenteredMaximalSegment(mySegmentComputer, i, myS->myBegin, myS->myEnd);
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);
163 myLastMaximalSegmentBegin = mySegmentComputer.begin();
164 myLastMaximalSegmentEnd = mySegmentComputer.end();
170 template <typename TSegmentComputer>
173 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::nextMaximalSegment()
176 if ( myFlagIsLast ) { //if end
178 myFlagIsValid = false;
182 myFlagIntersectPrevious = myFlagIntersectNext;
184 DGtal::nextMaximalSegment(mySegmentComputer, myS->myEnd );
186 if ( (mySegmentComputer.begin() == myLastMaximalSegmentBegin)
187 &&(mySegmentComputer.end() == myLastMaximalSegmentEnd) ) { //if only one segment
189 myFlagIntersectNext = doesIntersectNext( mySegmentComputer.end(), myS->myBegin, myS->myEnd );
193 myFlagIntersectNext = doesIntersectNext( mySegmentComputer.end() );
202 //////////////////////////////////////////////////////////////////////////////
203 // ------------------------- Standard services -----------------------
204 //////////////////////////////////////////////////////////////////////////////
207 template <typename TSegmentComputer>
209 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::SegmentComputerIterator (
210 const SaturatedSegmentation<TSegmentComputer> *s,
211 const TSegmentComputer& aSegmentComputer,
212 const bool& aIsValid )
214 mySegmentComputer( aSegmentComputer ),
215 myFlagIsValid( aIsValid ),
216 myFlagIntersectNext( false ),
217 myFlagIntersectPrevious( false ),
218 myFlagIsLast( false )
222 if ( isNotEmpty<ConstIterator>(myS->myStart, myS->myStop) )
223 { //if at least one element
225 this->initLastMaximalSegment();
226 this->initFirstMaximalSegment();
228 myFlagIntersectPrevious = doesIntersectNext( mySegmentComputer.begin(), myS->myBegin, myS->myEnd );
230 if ( (mySegmentComputer.begin() == myLastMaximalSegmentBegin)
231 &&(mySegmentComputer.end() == myLastMaximalSegmentEnd) )
232 { //if only one segment
234 myFlagIntersectNext = doesIntersectNext( mySegmentComputer.end(), myS->myBegin, myS->myEnd );
239 myFlagIntersectNext = doesIntersectNext( mySegmentComputer.end() );
245 myFlagIsValid = false;
250 template <typename TSegmentComputer>
252 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::SegmentComputerIterator
253 ( const SegmentComputerIterator & other )
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 )
266 template <typename TSegmentComputer>
268 typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator&
269 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator=
270 ( const SegmentComputerIterator & other )
272 if ( this != &other )
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;
287 template <typename TSegmentComputer>
289 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::~SegmentComputerIterator()
293 ///////////////////////////////////////////////////////////////////////////////
294 // ------------------------- iteration services -------------------------
295 //////////////////////////////////////////////////////////////////////////////
298 template <typename TSegmentComputer>
300 const TSegmentComputer&
301 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator*() const
303 return mySegmentComputer;
307 template <typename TSegmentComputer>
309 const TSegmentComputer*
310 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator->() const
312 return &mySegmentComputer;
316 template <typename TSegmentComputer>
319 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::get() const
321 return mySegmentComputer;
325 template <typename TSegmentComputer>
327 typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator &
328 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator++()
330 this->nextMaximalSegment();
335 template <typename TSegmentComputer>
338 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator==
339 ( const SegmentComputerIterator & other ) const
342 return ( (other.isValid() ) &&
343 ( mySegmentComputer.begin() == other.mySegmentComputer.begin() ) &&
344 ( mySegmentComputer.end() == other.mySegmentComputer.end() ) );
346 return ( ! other.isValid() );
350 template <typename TSegmentComputer>
353 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::operator!=
354 ( const SegmentComputerIterator & other ) const
356 return !(*this == other);
359 //////////////////////////////////////////////////////////////////////////////
360 // ------------------------- accessors -------------------------
361 //////////////////////////////////////////////////////////////////////////////
363 template <typename TSegmentComputer>
366 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::intersectNext() const
368 return myFlagIntersectNext;
371 template <typename TSegmentComputer>
374 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::intersectPrevious() const
376 return myFlagIntersectPrevious;
381 template <typename TSegmentComputer>
383 const typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::ConstIterator
384 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::begin() const
386 return mySegmentComputer.begin();
389 template <typename TSegmentComputer>
391 const typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::ConstIterator
392 DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator::end() const
394 return mySegmentComputer.end();
399 ///////////////////////////////////////////////////////////////////////////////
400 // class SaturatedSegmentation
401 ///////////////////////////////////////////////////////////////////////////////
403 ///////////////////////////////////////////////////////////////////////////////
404 // Interface - public :
407 template <typename TSegmentComputer>
408 DGtal::SaturatedSegmentation<TSegmentComputer>::SaturatedSegmentation
409 (const ConstIterator& itb, const ConstIterator& ite, const SegmentComputer& aSegmentComputer)
414 myMode("MostCentered"),
415 mySegmentComputer(aSegmentComputer)
420 template <typename TSegmentComputer>
423 DGtal::SaturatedSegmentation<TSegmentComputer>::setSubRange
424 (const ConstIterator& itb, const ConstIterator& ite)
428 myMode = "MostCentered";
431 template <typename TSegmentComputer>
434 DGtal::SaturatedSegmentation<TSegmentComputer>::setMode
435 (const std::string& aMode)
437 if ( (aMode == "First") || (aMode == "Last") || (aMode == "MostCentered")
438 || (aMode == "First++") || (aMode == "Last++") || (aMode == "MostCentered++") )
442 std::cerr << "[DGtal::SaturatedSegmentation<TSegmentComputer>::setMode(const std::string& aMode)]"
443 << " ERROR. Unknown mode." << std::endl;
444 throw InputException();
449 template <typename TSegmentComputer>
451 DGtal::SaturatedSegmentation<TSegmentComputer>::~SaturatedSegmentation()
456 template <typename TSegmentComputer>
458 typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator
459 DGtal::SaturatedSegmentation<TSegmentComputer>::begin() const
461 return SegmentComputerIterator(this, mySegmentComputer, true);
465 template <typename TSegmentComputer>
467 typename DGtal::SaturatedSegmentation<TSegmentComputer>::SegmentComputerIterator
468 DGtal::SaturatedSegmentation<TSegmentComputer>::end() const
470 return SegmentComputerIterator(this, mySegmentComputer, false);
475 template <typename TSegmentComputer>
478 DGtal::SaturatedSegmentation<TSegmentComputer>::selfDisplay ( std::ostream & out ) const
480 out << "[SaturatedSegmentation]";
484 template <typename TSegmentComputer>
487 DGtal::SaturatedSegmentation<TSegmentComputer>::isValid() const
494 ///////////////////////////////////////////////////////////////////////////////
495 // Implementation of inline functions //
497 template <typename TSegmentComputer>
500 DGtal::operator<< ( std::ostream & out,
501 const SaturatedSegmentation<TSegmentComputer> & object )
503 object.selfDisplay( out );
508 ///////////////////////////////////////////////////////////////////////////////