DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
SegmentComputerEstimators.h
1 
17 #pragma once
18 
36 #if defined(SegmentComputerEstimators_RECURSES)
37 #error Recursive header files inclusion detected in SegmentComputerEstimators.h
38 #else // defined(SegmentComputerEstimators_RECURSES)
39 
40 #define SegmentComputerEstimators_RECURSES
41 
42 #if !defined SegmentComputerEstimators_h
43 
44 #define SegmentComputerEstimators_h
45 
47 // Inclusions
48 #include <cmath>
49 #include "DGtal/base/Common.h"
50 #include "DGtal/helpers/StdDefs.h"
51 #include "boost/utility.hpp"
52 
54 
55 
56 namespace DGtal
57 {
58 
62  namespace detail
63  {
65  // class PosIndepScaleIndepSCEstimator
67 
83  template <typename TSegmentComputer, typename Functor,
84  typename ReturnType = typename Functor::Value>
86  {
87 
88  public:
89 
90  // ----------------------- inner type ------------------------------
91  typedef TSegmentComputer SegmentComputer;
92  typedef typename SegmentComputer::ConstIterator ConstIterator;
93  typedef ReturnType Quantity;
94 
95  // ----------------------- Internal data ------------------------------
96  public:
112  Functor myFunctor;
113 
114  // ----------------------- Standard services ------------------------------
115  public:
116 
121  bool isValid() const
122  {
123  return (mySCPtr != 0);
124  };
125 
126  // ----------------------- Interface --------------------------------------
127  public:
128 
133 
140  void init(const double /*h*/, const ConstIterator& itb, const ConstIterator& ite)
141  {
142  myBegin = itb;
143  myEnd = ite;
144  }
145 
150  void attach(const SegmentComputer& aSC)
151  {
152  mySCPtr = &aSC;
153  };
154 
160  Quantity eval(const ConstIterator& /*it*/) const
161  {
162  ASSERT( mySCPtr );
163  return myFunctor( *mySCPtr );
164  }
165 
175  template <typename OutputIterator>
176  OutputIterator eval(const ConstIterator& itb, const ConstIterator& ite,
177  OutputIterator result) const
178  {
179  ASSERT( mySCPtr );
180 
181  // do-while loop to deal with the case of a whole circular range
182  if (isNotEmpty(itb, ite))
183  {
184  ConstIterator it = itb;
185  do
186  {
187  *result++ = myFunctor( *mySCPtr );
188  ++it;
189  } while (it != ite);
190  }
191 
192  return result;
193  }
194 
195  }; // end of class PosIndepScaleIndepSCEstimator
196 
198  // class PosIndepScaleDepSCEstimator
200 
216  template <typename TSegmentComputer, typename Functor,
217  typename ReturnType = typename Functor::Value>
219  {
220 
221  public:
222 
223  // ----------------------- inner type ------------------------------
224  typedef TSegmentComputer SegmentComputer;
225  typedef typename SegmentComputer::ConstIterator ConstIterator;
226  typedef ReturnType Quantity;
227 
228  // ----------------------- internal data ------------------------------
229  public:
233  double myH;
249  Functor myFunctor;
250 
251  // ----------------------- Standard services ------------------------------
252  public:
253 
259  : myH( 0.0 ), myBegin(), myEnd(), mySCPtr(0), myFunctor()
260  {
261  }
267  : myH( other.myH ), myBegin( other.myBegin ), myEnd( other.myEnd ),
268  mySCPtr( other.mySCPtr ), myFunctor( other.myFunctor )
269  {
270  }
276  {
277  if (this != &other)
278  {
279  myH = other.myH;
280  myBegin = other.myBegin;
281  myEnd = other.myEnd;
282  mySCPtr = other.mySCPtr;
283  myFunctor = other.myFunctor;
284  }
285  return *this;
286  }
291 
296  bool isValid() const
297  {
298  return (myH > 0)&&(mySCPtr != 0);
299  };
300 
301 
302 
303  // ----------------------- Interface --------------------------------------
304  public:
305 
312  void init(const double h, const ConstIterator& itb, const ConstIterator& ite)
313  {
314  myH = h;
315  myBegin = itb;
316  myEnd = ite;
317  ASSERT( myH > 0 );
318  }
319 
324  void attach(const SegmentComputer& aSC)
325  {
326  mySCPtr = &aSC;
327  ASSERT( mySCPtr );
328  };
329 
335  Quantity eval(const ConstIterator& /*it*/) const
336  {
337  ASSERT( isValid() );
338  return myFunctor( *mySCPtr, myH );
339  }
340 
350  template <typename OutputIterator>
351  OutputIterator eval(const ConstIterator& itb, const ConstIterator& ite,
352  OutputIterator result) const
353  {
354  ASSERT( isValid() );
355 
356  // do-while loop to deal with the case of a whole circular range
357  if (isNotEmpty(itb, ite))
358  {
359  ConstIterator it = itb;
360  do
361  {
362  *result++ = myFunctor( *mySCPtr, myH );
363  ++it;
364  } while (it != ite);
365  }
366 
367  return result;
368  }
369 
370  }; // end of class PosIndepScaleDepSCEstimator
371 
373  // class PosDepScaleIndepSCEstimator
375 
390  template <typename TSegmentComputer, typename Functor,
391  typename ReturnType = typename Functor::Value>
393  {
394 
395  public:
396 
397  // ----------------------- inner type ------------------------------
398  typedef TSegmentComputer SegmentComputer;
399  typedef typename SegmentComputer::ConstIterator ConstIterator;
400  typedef ReturnType Quantity;
401 
402  // ----------------------- Internal data ------------------------------
403  public:
419  Functor myFunctor;
420 
421  // ----------------------- Standard services ------------------------------
422  public:
423 
428  bool isValid() const
429  {
430  return (mySCPtr != 0);
431  };
432 
433  // ----------------------- Interface --------------------------------------
434  public:
435 
440 
447  void init(const double /*h*/, const ConstIterator& itb, const ConstIterator& ite)
448  {
449  myBegin = itb;
450  myEnd = ite;
451  }
452 
457  void attach(const SegmentComputer& aSC)
458  {
459  mySCPtr = &aSC;
460  };
461 
467  Quantity eval(const ConstIterator& it) const
468  {
469  ASSERT( mySCPtr );
470  return myFunctor( it, *mySCPtr );
471  }
472 
482  template <typename OutputIterator>
483  OutputIterator eval(const ConstIterator& itb, const ConstIterator& ite,
484  OutputIterator result) const
485  {
486  ASSERT( mySCPtr );
487 
488  // do-while loop to deal with the case of a whole circular range
489  if (isNotEmpty(itb, ite))
490  {
491  ConstIterator it = itb;
492  do
493  {
494  *result++ = myFunctor( it, *mySCPtr );
495  ++it;
496  } while (it != ite);
497  }
498 
499  return result;
500  }
501 
502  }; // end of class PosDepScaleIndepSCEstimator
503 
505  // class PosDepScaleDepSCEstimator
507 
522  template <typename TSegmentComputer, typename Functor,
523  typename ReturnType = typename Functor::Value>
525  {
526 
527  public:
528 
529  // ----------------------- inner type ------------------------------
530  typedef TSegmentComputer SegmentComputer;
531  typedef typename SegmentComputer::ConstIterator ConstIterator;
532  typedef ReturnType Quantity;
533 
534  // ----------------------- internal data ------------------------------
535  public:
539  double myH;
555  Functor myFunctor;
556 
557  // ----------------------- Standard services ------------------------------
558  public:
559 
565  : myH( 0.0 ), myBegin(), myEnd(), mySCPtr(0), myFunctor()
566  {
567  }
573  : myH( other.myH ), myBegin( other.myBegin ), myEnd( other.myEnd ),
574  mySCPtr( other.mySCPtr ), myFunctor( other.myFunctor )
575  {
576  }
582  {
583  if (this != &other)
584  {
585  myH = other.myH;
586  myBegin = other.myBegin;
587  myEnd = other.myEnd;
588  mySCPtr = other.mySCPtr;
589  myFunctor = other.myFunctor;
590  }
591  return *this;
592  }
597 
602  bool isValid() const
603  {
604  return (myH > 0)&&(mySCPtr != 0);
605  };
606 
607 
608 
609  // ----------------------- Interface --------------------------------------
610  public:
611 
618  void init(const double h, const ConstIterator& itb, const ConstIterator& ite)
619  {
620  myH = h;
621  myBegin = itb;
622  myEnd = ite;
623  ASSERT( myH > 0 );
624  }
625 
630  void attach(const SegmentComputer& aSC)
631  {
632  mySCPtr = &aSC;
633  ASSERT( mySCPtr );
634  };
635 
641  Quantity eval(const ConstIterator& it) const
642  {
643  ASSERT( isValid() );
644  return myFunctor( it, *mySCPtr, myH );
645  }
646 
656  template <typename OutputIterator>
657  OutputIterator eval(const ConstIterator& itb, const ConstIterator& ite,
658  OutputIterator result) const
659  {
660  ASSERT( isValid() );
661 
662  // do-while loop to deal with the case of a whole circular range
663  if (isNotEmpty(itb, ite))
664  {
665  ConstIterator it = itb;
666  do
667  {
668  *result++ = myFunctor( it, *mySCPtr, myH );
669  ++it;
670  } while (it != ite);
671  }
672 
673  return result;
674  }
675 
676  }; // end of class PosDepScaleDepSCEstimator
677 
680 
686  {
687  public:
688  typedef double Value;
689 
690 
704  template<typename DSS>
705  Value operator() (const DSS& aDSS) const
706  {
708  ::castToDouble(aDSS.getA());
710  ::castToDouble(aDSS.getB());
711 
712  return std::atan2(a,b);
713  }
714  };
720  {
721  public:
723  typedef RealVector Value;
724 
737  template<typename DSS>
738  Value operator() (const DSS& aDSS) const
739  {
741  ::castToDouble( aDSS.getB() );
743  ::castToDouble( aDSS.getA() );
744  RealVector v(x,y);
745  double norm = v.norm(RealVector::L_2);
746  v /= norm;
747  return v;
748  }
749  };
754  template<typename DSS>
756  {
757  public:
758  typedef typename DSS::Vector Value;
759 
772  Value operator() (const DSS& aDSS) const
773  {
774  return Value(aDSS.getB(), aDSS.getA());
775  }
776  };
789  template<bool isCCW = true>
791  {
792  public:
793  typedef double Value;
794 
808  template<typename DCA>
809  Value operator() (const DCA& aDCA, const double& aH = 1.0) const
810  {
811  if ( aDCA.isStraight() )
812  return 0.0;
813  else
814  return ( aDCA.getSeparatingCircle().getCurvature() / aH );
815  }
816  };
817  template<>
819  {
820  public:
821  typedef double Value;
822 
823  template<typename DCA>
824  Value operator() (const DCA& aDCA, const Value& aH = 1.0) const
825  {
826  if ( aDCA.isStraight() )
827  return 0.0;
828  else
829  return - ( aDCA.getSeparatingCircle().getCurvature() / aH );
830  }
831  };
837  {
838  public:
840 
841 
855  template<typename DCA>
856  Value operator() (const typename DCA::ConstIterator& it,
857  const DCA& aDCA) const
858  {
859  typedef typename DCA::ConstIterator ConstIterator;
860  typedef typename DCA::Pair Pair;
861  typedef typename DCA::Point Point;
862  typedef typename Point::Coordinate Coordinate;
863 
864  if ( !aDCA.isStraight() )
865  {
866  //separating circle center
867  double c0, c1, r;
868  aDCA.getSeparatingCircle().getParameters(c0, c1, r);
869  //point
870  Pair pair = *it;
871  Point i = pair.first;
872  Point o = pair.second;
873  double m0 = NumberTraits<Coordinate>::castToDouble(i[0]+o[0]) / 2.0;
874  double m1 = NumberTraits<Coordinate>::castToDouble(i[1]+o[1]) / 2.0;
875  //normal vector
876  double v0 = m0 - c0;
877  double v1 = m1 - c1;
878  //norm
879  double n = std::sqrt(v0*v0 + v1*v1);
880  return Value( v0/n, v1/n );
881  }
882  else
883  {
884  //separating straight line and normal vector
885  double a, b, c;
886  aDCA.getGeometricalDSSPtr()->getParameters(a, b, c);
887  //norm
888  double n = std::sqrt(a*a + b*b);
889  return Value( a/n, b/n );
890  }
891  }
892  };
893 
899  {
900  public:
902 
918  template<typename DCA>
919  Value operator() (const typename DCA::ConstIterator& it,
920  const DCA& aDCA) const
921  {
923  Value normal = f(it, aDCA);
924  return Value( normal[1], normal[0] );
925  }
926  };
927 
934  {
935  public:
936  typedef std::pair<double,double> Value;
937 
954  template<typename DCA>
955  Value operator() (const typename DCA::ConstIterator& it,
956  const DCA& aDCA, const double& aH) const
957  {
958  typedef typename DCA::ConstIterator ConstIterator;
959  typedef typename DCA::Pair Pair;
960  typedef typename DCA::Point Point;
961  typedef typename Point::Coordinate Coordinate;
962 
963  if ( !aDCA.isStraight() )
964  {
965  //separating circle center
966  double c0, c1, r;
967  aDCA.getSeparatingCircle().getParameters(c0, c1, r);
968  //points
969  Pair pair = *it;
970  Point i = pair.first;
971  Point o = pair.second;
972  //distances
973  double distI0 = NumberTraits<Coordinate>::castToDouble(i[0]) - c0;
974  double distI1 = NumberTraits<Coordinate>::castToDouble(i[1]) - c1;
975  double distI = std::sqrt( distI0*distI0 + distI1*distI1 ) - r;
976  double distO0 = NumberTraits<Coordinate>::castToDouble(o[0]) - c0;
977  double distO1 = NumberTraits<Coordinate>::castToDouble(o[1]) - c1;
978  double distO = std::sqrt( distO0*distO0 + distO1*distO1 ) - r;
979  return Value( distI*aH, distO*aH );
980  }
981  else
982  {
983  //separating straight line
984  double a, b, c;
985  aDCA.getGeometricalDSSPtr()->getParameters(a, b, c);
986  //norm
987  double n = std::sqrt(a*a + b*b);
988  //points
989  Pair pair = *it;
990  Point i = pair.first;
991  Point o = pair.second;
992  //distances
993  double rI = NumberTraits<Coordinate>::castToDouble(i[0])*a +
995  double distI = rI / n;
996  double rO = NumberTraits<Coordinate>::castToDouble(o[0])*a +
998  double distO = rO / n;
999  return Value( distI*aH, distO*aH );
1000  }
1001  }
1002  };
1003 
1004  }//namespace detail
1005 
1006 
1007 
1008  //-------------------------------------------------------------------------------------------
1017  template <typename DSSComputer>
1019  public detail::PosIndepScaleIndepSCEstimator<DSSComputer, detail::NormalizedTangentVectorFromDSS>
1020  {
1021  typedef
1024 
1025  public:
1035  };
1036 
1037  //-------------------------------------------------------------------------------------------
1046  template <typename DSSComputer>
1048  public detail::PosIndepScaleIndepSCEstimator<DSSComputer, detail::TangentVectorFromDSS<DSSComputer> >
1049  {
1050  typedef
1053 
1054  public:
1064  };
1065 
1066  //-------------------------------------------------------------------------------------------
1076  template <typename DSSComputer>
1078  public detail::PosIndepScaleIndepSCEstimator<DSSComputer, detail::TangentAngleFromDSS>
1079  {
1080  typedef
1083 
1084  public:
1094  };
1095 
1096  //-------------------------------------------------------------------------------------------
1114  template <typename DCAComputer, bool isCCW = true>
1116  public detail::PosIndepScaleDepSCEstimator<DCAComputer,
1117  detail::CurvatureFromDCA<isCCW> >
1118  {
1119  typedef
1122 
1123  public:
1133  };
1134 
1135  //-------------------------------------------------------------------------------------------
1144  template <typename DCAComputer>
1146  public detail::PosDepScaleIndepSCEstimator<DCAComputer,
1147  detail::NormalVectorFromDCA>
1148  {
1149  typedef
1152 
1153  public:
1163  };
1164 
1165  //-------------------------------------------------------------------------------------------
1174  template <typename DCAComputer>
1176  public detail::PosDepScaleIndepSCEstimator<DCAComputer,
1177  detail::TangentVectorFromDCA>
1178  {
1179  typedef
1182 
1183  public:
1193  };
1194 
1195  //-------------------------------------------------------------------------------------------
1205  template <typename DCAComputer>
1207  public detail::PosDepScaleDepSCEstimator<DCAComputer,
1208  detail::DistanceFromDCA>
1209  {
1210  typedef
1213 
1214  public:
1224  };
1225 
1229  namespace detail
1230  {
1243  {
1244  public:
1245  typedef double Value;
1246 
1247  template<typename DSS>
1248  Value operator() (const DSS& aDSS) const
1249  {
1250  typedef typename DSS::Vector Vector;
1251  //length
1252  Vector v = ( *aDSS.begin() - *boost::prior(aDSS.end()) );
1253  Value l = v.norm(Vector::L_2);
1254  //result
1255  return 1/( (l*l)/8 + 0.5 );
1256  }
1257  };
1258 
1271  {
1272  public:
1273  typedef double Value;
1274 
1275  template<typename DSS>
1276  Value operator() (const DSS& aDSS) const
1277  {
1278  typedef typename DSS::Vector Vector;
1279  //length
1280  Vector v = ( *aDSS.begin() - *boost::prior(aDSS.end()) );
1281  Value l = v.norm(Vector::L_2);
1282  //width
1283  Vector t( aDSS.getB(), aDSS.getA() );
1284  Value w = 1.0 / v.norm(Vector::L_2);
1285  //result
1286  return 1.0/( (l*l)/(8*w) + w/2 );
1287  }
1288  };
1289 
1291  // class CurvatureFromDSSBaseEstimator
1293 
1308  template <typename DSSComputer, typename Functor = detail::CurvatureFromDSSLength >
1310  {
1311 
1312  public:
1313 
1314  // ----------------------- inner type ------------------------------------
1315  typedef DSSComputer SegmentComputer;
1316  typedef typename DSSComputer::ConstIterator ConstIterator;
1317  typedef double Quantity;
1318 
1320 
1321  // ----------------------- internal data ------------------------------
1322  public:
1326  double myH;
1342  Functor myFunctor;
1343 
1344  // ----------------------- Standard services ------------------------------
1345  public:
1346 
1352  : myH( 0.0 ), myBegin(), myEnd(), mySCPtr(0), myFunctor()
1353  {
1354  }
1360  : myH( other.myH ), myBegin( other.myBegin ), myEnd( other.myEnd ),
1361  mySCPtr( other.mySCPtr ), myFunctor( other.myFunctor )
1362  {
1363  }
1369  {
1370  if (this != &other)
1371  {
1372  myH = other.myH;
1373  myBegin = other.myBegin;
1374  myEnd = other.myEnd;
1375  mySCPtr = other.mySCPtr;
1376  myFunctor = other.myFunctor;
1377  }
1378  return *this;
1379  }
1384 
1389  bool isValid() const
1390  {
1391  return (myH > 0)&&(mySCPtr != 0);
1392  };
1393 
1394  // ----------------------- Interface --------------------------------------
1395  public:
1396 
1403  void init(const double h, const ConstIterator& itb, const ConstIterator& ite)
1404  {
1405  myH = h;
1406  myBegin = itb;
1407  myEnd = ite;
1408  ASSERT( myH > 0 );
1409  }
1410 
1417  {
1418  ASSERT( isValid() );
1419 
1420  //types
1421  typedef typename DSSComputer::Integer Integer;
1422  typedef typename DSSComputer::Vector Vector;
1423 
1424  //curvature value
1425  Quantity k = 0;
1426 
1427 
1428  //begin and end iterators
1429  //(back point on the first point)
1430  //(front point on the last point)
1431  ConstIterator back = mySCPtr->begin();
1432  ConstIterator front = mySCPtr->end();
1433  bool isConnectedAtBack = isNotEmpty(myBegin, back)
1434  &&((*boost::prior(back)-*back).norm(Vector::L1) <= NumberTraits<Integer>::ONE);
1435  bool isConnectedAtFront = isNotEmpty(front, myEnd)
1436  &&((*boost::prior(front)-*front).norm(Vector::L1) <= NumberTraits<Integer>::ONE);
1437 
1438 
1439  if (isConnectedAtBack) {
1440  if (isConnectedAtFront) {
1441 
1442  --back;
1443 
1444  //parameters
1445  Integer mu = mySCPtr->getMu();
1446  Integer omega = mySCPtr->getOmega();
1447 
1448  //cases
1449  if ( (mySCPtr->getRemainder(*back)<=mu-1)&&
1450  (mySCPtr->getRemainder(*front)<=mu-1) ) { //convex
1451  k = myFunctor(*mySCPtr) / myH;
1452  } else if ( (mySCPtr->getRemainder(*back)>=mu+omega)&&
1453  (mySCPtr->getRemainder(*front)>=mu+omega) ) { //concave
1454  k = -myFunctor(*mySCPtr) / myH;
1455  } //else //inflection
1456 
1457  } else {
1458 
1459  --back;
1460 
1461  //parameters
1462  Integer mu = mySCPtr->getMu();
1463  Integer omega = mySCPtr->getOmega();
1464 
1465  //cases
1466  if ( (mySCPtr->getRemainder(*back)<=mu-1) ) { //convex
1467  k = myFunctor(*mySCPtr) / myH;
1468  } else if ( (mySCPtr->getRemainder(*back)>=mu+omega) ) { //concave
1469  k = -myFunctor(*mySCPtr) / myH;
1470  } //else //inflection
1471 
1472  }
1473  } else if (isConnectedAtFront) {
1474 
1475  //parameters
1476  Integer mu = mySCPtr->getMu();
1477  Integer omega = mySCPtr->getOmega();
1478 
1479  //cases
1480  if ( (mySCPtr->getRemainder(*front)<=mu-1) ) { //convex
1481  k = myFunctor(*mySCPtr) / myH;
1482  } else if ( (mySCPtr->getRemainder(*front)>=mu+omega) ) { //concave
1483  k = -myFunctor(*mySCPtr) / myH;
1484  } //else //inflection
1485 
1486  } //else cannot be extended: k is set to 0
1487 
1488  return k;
1489 
1490  }
1491 
1501  template <typename OutputIterator>
1502  OutputIterator eval(const ConstIterator& itb, const ConstIterator& ite,
1503  OutputIterator result)
1504  {
1505  ASSERT( isValid() );
1506 
1507  // do-while loop to deal with the case of a whole circular range
1508  if (isNotEmpty(itb, ite))
1509  {
1510  ConstIterator it = itb;
1511  do
1512  {
1513  *result++ = eval( it );
1514  ++it;
1515  } while (it != ite);
1516  }
1517 
1518  return result;
1519  }
1520 
1525  void attach(const SegmentComputer& aSC)
1526  {
1527  mySCPtr = &aSC;
1528  ASSERT( mySCPtr );
1529  };
1530 
1531 
1532  }; // end of class CurvatureFromDSSBaseEstimator
1533 
1534  }//namespace detail
1535 
1536 
1537 
1538  //-------------------------------------------------------------------------------------------
1560  template <typename DSSComputer>
1562  public detail::CurvatureFromDSSBaseEstimator<DSSComputer, detail::CurvatureFromDSSLength >
1563  {
1564 
1566 
1567  public:
1577  };
1578 
1579  //-------------------------------------------------------------------------------------------
1597  template <typename DSSComputer>
1599  public detail::CurvatureFromDSSBaseEstimator<DSSComputer, detail::CurvatureFromDSSLengthAndWidth >
1600  {
1601 
1603 
1604  public:
1614  };
1615 
1616 
1617 } // namespace DGtal
1618 
1619 // //
1621 
1622 #endif // !defined SegmentComputerEstimators_h
1623 
1624 #undef SegmentComputerEstimators_RECURSES
1625 #endif // else defined(SegmentComputerEstimators_RECURSES)