DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FMM.ih
1 
33 
34 #include <cstdlib>
36 
37 #include "DGtal/topology/SCellsFunctors.h"
38 
40 // IMPLEMENTATION of inline methods.
42 
44 // ----------------------- Standard services ------------------------------
45 
46 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
47 inline
50  const PointPredicate& aPointPredicate)
51  : myImage( aImg ), myAcceptedPoints( aSet ),
52  myPointFunctorPtr( new PointFunctor(aImg, aSet) ),
53  myFlagIsOwning( true ),
54  myPointPredicate( aPointPredicate ),
55  myAreaThreshold( std::numeric_limits<Area>::max() ),
56  myValueThreshold( std::numeric_limits<Value>::max() )
57 {
58  if (myAcceptedPoints.size() == 0) throw InputException();
59  init();
60 }
61 
62 
63 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
64 inline
67  const PointPredicate& aPointPredicate,
68  const Area& aAreaThreshold,
69  const Value& aValueThreshold)
70  : myImage( aImg ), myAcceptedPoints( aSet ),
71  myPointFunctorPtr( new PointFunctor(aImg, aSet) ),
72  myFlagIsOwning( true ),
73  myPointPredicate( aPointPredicate ),
74  myAreaThreshold( aAreaThreshold ),
75  myValueThreshold( aValueThreshold )
76 {
77  if (myAcceptedPoints.size() == 0) throw InputException();
78  init();
79 }
80 
81 
82 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
83 inline
86  const PointPredicate& aPointPredicate,
87  PointFunctor& aPointFunctor)
88  : myImage( aImg ), myAcceptedPoints( aSet ),
89  myPointFunctorPtr( &aPointFunctor ),
90  myFlagIsOwning( false ),
91  myPointPredicate( aPointPredicate ),
92  myAreaThreshold( std::numeric_limits<Area>::max() ),
93  myValueThreshold( std::numeric_limits<Value>::max() )
94 {
95  if (myAcceptedPoints.size() == 0) throw InputException();
96  init();
97 }
98 
99 
100 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
101 inline
104  const PointPredicate& aPointPredicate,
105  const Area& aAreaThreshold,
106  const Value& aValueThreshold,
107  PointFunctor& aPointFunctor)
108  : myImage( aImg ), myAcceptedPoints( aSet ),
109  myPointFunctorPtr( &aPointFunctor ),
110  myFlagIsOwning( false ),
111  myPointPredicate( aPointPredicate ),
112  myAreaThreshold( aAreaThreshold ),
113  myValueThreshold( aValueThreshold )
114 {
115  if (myAcceptedPoints.size() == 0) throw InputException();
116  init();
117 }
118 
119 
120 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
121 inline
123 {
124  if (myFlagIsOwning)
125  delete myPointFunctorPtr;
126 }
127 
129 // Static functions :
130 
131 
132 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
133 template <typename TIteratorOnPoints>
134 void
136 ::initFromPointsRange(const TIteratorOnPoints& itb, const TIteratorOnPoints& ite,
137  Image& aImg, AcceptedPointSet& aSet,
138  const Value& aValue)
139 {
140 
141  aSet.clear();
142  for (TIteratorOnPoints it = itb; it != ite; ++it)
143  {
144  insertAndAlwaysSetValue( aImg, aSet, *it, aValue );
145  }
146 }
147 
148 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
149 template <typename KSpace, typename TIteratorOnBels>
150 void
152 ::initFromBelsRange(const KSpace& aK,
153  const TIteratorOnBels& itb, const TIteratorOnBels& ite,
154  Image& aImg, AcceptedPointSet& aSet,
155  const Value& aValue,
156  bool aFlagIsPositive)
157 {
158  Value k = -1;
159  if (aFlagIsPositive) k = 1;
160 
161  aSet.clear();
162  for (TIteratorOnBels it = itb; it != ite; ++it)
163  {
164  //getting incident points
165  SCellToIncidentPoints<KSpace> func( aK );
166  typename SCellToIncidentPoints<KSpace>::Output points = func( *it );
167  //assignement
168  insertAndAlwaysSetValue( aImg, aSet, points.first, k*aValue );
169  insertAndAlwaysSetValue( aImg, aSet, points.second, -k*aValue );
170  }
171 }
172 
173 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
174 template <typename KSpace, typename TIteratorOnBels, typename TImplicitFunction>
175 void
177 ::initFromBelsRange(const KSpace& aK,
178  const TIteratorOnBels& itb, const TIteratorOnBels& ite,
179  const TImplicitFunction& aF,
180  Image& aImg, AcceptedPointSet& aSet,
181  bool aFlagIsPositive)
182 {
183  Value k = -1;
184  if (aFlagIsPositive) k = 1;
185 
187  typedef typename KSpace::Cell Bel;
188  typedef typename TImplicitFunction::Value Value;
189  typedef std::pair<const Bel, Value> BelValue;
190  typedef std::map<Bel, Value> Buffer;
191 
192  typedef typename SCellToIncidentPoints<KSpace>::Output Pair;
193  typedef std::vector<Pair> IncidentPoints;
194  SCellToIncidentPoints<KSpace> getIncidentPoints( aK );
195 
198  IncidentPoints incidentPoints;
199  Buffer buffer;
200  for (TIteratorOnBels it = itb; it != ite; ++it)
201  {
202  //getting incident points
203  Pair points = getIncidentPoints( *it );
204  incidentPoints.push_back( points );
205 
206  //getting values
207  Value vin = aF( points.first );
208  Value vout = aF( points.second );
209 
210  //computing/storing the new value
211  Value e = std::max(vin, vout) - std::min(vin, vout);
212  Value v = (std::abs(vin)/e);
213  ASSERT( v >= 0 );
214  buffer.insert( BelValue( aK.unsigns( *it ), v ) );
215  }
216 
217  aSet.clear();
222  Computer4InnerPts computerIn(aK, buffer);
223  Computer4OuterPts computerOut(aK, buffer);
224  for (typename IncidentPoints::const_iterator it = incidentPoints.begin();
225  it != incidentPoints.end(); ++it)
226  {
227  //computing the values
228  Value vin = computerIn( it->first );
229  Value vout = computerOut( it->second );
230 
231  //assignement
232  insertAndAlwaysSetValue( aImg, aSet, it->first, k*vin );
233  insertAndAlwaysSetValue( aImg, aSet, it->second, -k*vout );
234  }
235 }
236 
237 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
238 template <typename TIteratorOnPairs>
239 void
241 ::initFromIncidentPointsRange(const TIteratorOnPairs& itb, const TIteratorOnPairs& ite,
242  Image& aImg, AcceptedPointSet& aSet,
243  const Value& aValue,
244  bool aFlagIsPositive)
245 {
246  Value k = -1;
247  if (aFlagIsPositive) k = 1;
248 
249  aSet.clear();
250  for (TIteratorOnPairs it = itb; it != ite; ++it)
251  {
252  insertAndAlwaysSetValue( aImg, aSet, it->first, k*aValue );
253  insertAndAlwaysSetValue( aImg, aSet, it->second, -k*aValue );
254  }
255 }
256 
258 // Interface - public :
259 
260 
261 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
262 inline
263 void
265 {
266  Point p = Point::diagonal(0);
267  Value d = 0;
268  while ( addNewAcceptedPoint( p, d ) )
269  { }
270 }
271 
272 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
273 inline
274 bool
276 ::computeOneStep(Point& aPoint, Value& aValue)
277 {
278  return addNewAcceptedPoint(aPoint, aValue);
279 }
280 
281 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
282 inline
285 {
286  return myMinValue;
287 }
288 
289 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
290 inline
293 {
294  return myMaxValue;
295 }
296 
297 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
298 inline
301 {
302  const AcceptedPointSet& set = myAcceptedPoints;
303  ASSERT( set.size() >= 1 );
304 
305  typename AcceptedPointSet::ConstIterator it = set.begin();
306  typename AcceptedPointSet::ConstIterator itEnd = set.end();
307  Value vmin = myImage( *it );
308  for (++it; it != itEnd; ++it)
309  {
310  Value v = myImage( *it );
311  if (v < vmin) vmin = v;
312  }
313  return vmin;
314 }
315 
316 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
317 inline
320 {
321  const AcceptedPointSet& set = myAcceptedPoints;
322  ASSERT( set.size() >= 1 );
323 
324  typename AcceptedPointSet::ConstIterator it = set.begin();
325  typename AcceptedPointSet::ConstIterator itEnd = set.end();
326  Value vmax = myImage( *it );
327  for (++it; it != itEnd; ++it)
328  {
329  Value v = myImage( *it );
330  if (v > vmax) vmax = v;
331  }
332  return vmax;
333 }
334 
335 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
336 inline
337 bool
339 {
340  //area threshold
341  if ( (myAcceptedPoints.size() <= 0)
342  || (myAcceptedPoints.size() >= myAreaThreshold) ) return false;
343 
344  //distance threshold
345  if ( ( getMin() != min() ) || ( getMax() != max() ) ) return false;
346  if ( (std::abs(getMin()) >= myValueThreshold)
347  || (getMax() >= myValueThreshold) ) return false;
348 
349  //point predicate
350  bool flagIsOk = true;
351  const AcceptedPointSet& set = myAcceptedPoints;
352  typename AcceptedPointSet::ConstIterator it = set.begin();
353  typename AcceptedPointSet::ConstIterator itEnd = set.end();
354  for ( ; ( (it != itEnd)&&(flagIsOk == true) ); ++it)
355  {
356  if (myPointPredicate( *it ) == false) flagIsOk = false;
357  }
358  if (!flagIsOk) return false;
359 
360  return true;
361 }
362 
363 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
364 inline
365 void
367 {
368  out << "[FMM " << dimension << "d] ";
369  out << myAcceptedPoints.size() << " accepted points (< " << myAreaThreshold << ")";
370  out << " and " << myCandidatePoints.size() << " candidates. ";
371  out << "dmin: " << min() << ", dmax: " << max();
372  out << " (abs < " << myValueThreshold << ")";
373 }
374 
375 
377 // Internals
378 
379 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
380 inline
381 void
383 {
384 
385  myCandidatePoints.clear();
386 
387  typename AcceptedPointSet::Iterator it = myAcceptedPoints.begin();
388  typename AcceptedPointSet::Iterator itEnd = myAcceptedPoints.end();
389  for ( ; it != itEnd; ++it)
390  {
391  update( *it );
392  }
393 
394  myMinValue = getMin();
395  myMaxValue = getMax();
396 
397 }
398 
399 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
400 inline
401 bool
404 {
405 
406  if ( (myAcceptedPoints.size()+1) < myAreaThreshold )
407  {//if a new point can be accepted
408 
409  bool flagStop = false;
410  typename CandidatePointSet::iterator it = myCandidatePoints.begin();
411  typename CandidatePointSet::iterator itEnd = myCandidatePoints.end();
412  while ( (it != itEnd) && (!flagStop) )
413  { //while there are candidates and no point has been accepted
414 
415  //pair of min distance
416  PointValue minPair = *it;
417 
418  if ( std::abs(minPair.second) < myValueThreshold )
419  { //if distance below a given threshold
420 
421  //the point of min distance is removed from the set of candidates
422  myCandidatePoints.erase(*it);
423  //it can be inserted into the set of accepted points
424  if ( insertAndSetValue( myImage, myAcceptedPoints,
425  minPair.first, minPair.second ) )
426  { //if it does not belong to the set
427  //the set of candidates is updated with
428  //the neighbors of the new accepted point
429  aPoint = minPair.first;
430  aValue = minPair.second;
431  if (aValue > myMaxValue) myMaxValue = aValue;
432  if (aValue < myMinValue) myMinValue = aValue;
433  update( aPoint );
434  flagStop = true;
435  }
436  else
437  { //otherwise it has already been accepted
438  //with a smaller distance and the next candidate
439  //should be considered
440  it = myCandidatePoints.begin();
441  }
442 
443  }//end if distance below a given threshold
444  else return false;
445 
446  } //end while there are candidates
447 
448  return flagStop; //true if a point has been accepted
449 
450  } //end if a new point can be accepted
451  else return false;
452 }
453 
454 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
455 inline
456 void
458 {
459 
460  //neigbors
461  Point neighbor = aPoint;
462  for (Dimension k = 0; k < dimension; ++k)
463  {
464  typename Point::Coordinate c = neighbor.at(k);
465  neighbor.at(k) = (c+1);
466  addNewCandidate(neighbor);
467  neighbor.at(k) = (c-1);
468  addNewCandidate(neighbor);
469  neighbor.at(k) = c;
470  }
471 }
472 
473 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
474 inline
475 bool
477 {
478 
479  //if it lies within the computation domain
480  //and if it is not already accepted
481  if ( (myPointPredicate(aPoint) )
482  && ( myAcceptedPoints.find(aPoint) == myAcceptedPoints.end() ) )
483  {
484  ASSERT( myPointFunctorPtr );
485  Value d = myPointFunctorPtr->operator()( aPoint );
486  PointValue newPair( aPoint, d );
487  //insert the new candidate with its distance
488  myCandidatePoints.insert(newPair);
489  return true;
490  }
491  else return false;
492 }
493 
494 
496 // Implementation of inline functions //
497 
498 template <typename TImage, typename TSet, typename TPointPredicate, typename TPointFunctor >
499 inline
500 std::ostream&
501 DGtal::operator<< ( std::ostream & out,
503 {
504  object.selfDisplay( out );
505  return out;
506 }
507 
508 // //
510 
511