7 #ifndef NUKLEI_SPECIALIZED_KERNEL_H
8 #define NUKLEI_SPECIALIZED_KERNEL_H
11 #include <boost/cast.hpp>
12 #include <boost/ptr_container/ptr_array.hpp>
50 typedef NUKLEI_UNIQUE_PTR< kernel::base >
ptr;
53 typedef enum { R3 = 0, R3XS2, R3XS2P, SE3, UNKNOWN }
Type;
61 base() : w_(1.), flag1_(0), bitfield_(0) {}
63 base(
const base& k) : w_(k.w_), flag1_(k.flag1_), bitfield_(k.bitfield_)
65 if (k.hasDescriptor()) desc_ = k.desc_->clone();
68 base& operator=(
const base& k)
72 bitfield_ = k.bitfield_;
74 if (k.hasDescriptor()) desc_ = k.desc_->clone();
82 virtual void assertConsistency()
const = 0;
85 friend std::ostream&
operator<<(std::ostream &out,
const kernel::base &k);
92 virtual std::ostream&
polyPrint(std::ostream &out)
const = 0;
105 virtual Vector3
getLoc()
const = 0;
107 virtual void setLoc(
const Vector3 &v) = 0;
145 virtual NUKLEI_UNIQUE_PTR<kernel::se3>
polySe3Sample()
const = 0;
154 virtual NUKLEI_UNIQUE_PTR<kernel::se3>
polySe3Proj()
const = 0;
185 const coord_t x = .5)
const = 0;
219 bool hasDescriptor()
const {
return desc_.get() != NULL; }
222 const Descriptor& getDescriptor()
const
224 void setDescriptor(
const Descriptor& desc)
225 { desc_ = desc.clone(); }
226 void clearDescriptor() { desc_.reset(); }
229 { bitfield_ |= flag; }
231 { bitfield_ &= ~flag; }
233 {
return (bitfield_ & flag) != 0; }
259 NUKLEI_UNIQUE_PTR<Descriptor> desc_;
261 friend class NUKLEI_SERIALIZATION_FRIEND_CLASSNAME;
262 template<
class Archive>
263 void serialize(Archive &ar,
const unsigned int version)
265 ar & NUKLEI_SERIALIZATION_NVP(w_);
266 ar & NUKLEI_SERIALIZATION_NVP(desc_);
271 inline kernel::base* new_clone(
const kernel::base& k)
282 NUKLEI_TRACE_BEGIN();
283 return base::ptr(
new T(*
static_cast<const T*
>(
this)));
289 NUKLEI_TRACE_BEGIN();
296 NUKLEI_TRACE_BEGIN();
297 return static_cast<const T*
>(
this)->loc_;
303 NUKLEI_TRACE_BEGIN();
304 static_cast<T*
>(
this)->loc_ = v;
310 NUKLEI_TRACE_BEGIN();
311 return static_cast<const T*
>(
this)->print(out);
317 NUKLEI_TRACE_BEGIN();
318 return static_cast<const T*
>(
this)->type();
324 NUKLEI_TRACE_BEGIN();
325 const T& down =
dynamic_cast<const T&
>(k);
326 return static_cast<const T*
>(
this)->eval(down);
332 NUKLEI_TRACE_BEGIN();
333 return static_cast<const T*
>(
this)->cutPoint();
339 NUKLEI_TRACE_BEGIN();
340 base::ptr s(
new T(
static_cast<const T*
>(
this)->sample()) );
347 NUKLEI_UNIQUE_PTR<kernel::se3>
polySe3Proj()
const;
351 NUKLEI_TRACE_BEGIN();
352 base::ptr s(
new T(
static_cast<const T*
>(
this)->projectedOn(k)) );
359 NUKLEI_TRACE_BEGIN();
360 base::ptr s(
new T(
static_cast<const T*
>(
this)->transformedWith(k)) );
367 NUKLEI_TRACE_BEGIN();
368 static_cast<T*
>(
this)->makeTransformWith(k);
375 NUKLEI_TRACE_BEGIN();
376 const T& down =
dynamic_cast<const T&
>(k);
377 base::ptr s(
new T(
static_cast<const T*
>(
this)->linearInterpolation(down, x)) );
385 NUKLEI_TRACE_BEGIN();
386 const T& down =
dynamic_cast<const T&
>(k);
387 static_cast<T*
>(
this)->updateWidth(down, x);
393 NUKLEI_TRACE_BEGIN();
394 const T& down =
dynamic_cast<const T&
>(k);
395 return static_cast<const T*
>(
this)->distanceTo(down);
407 typedef NUKLEI_UNIQUE_PTR<kernel::se3>
ptr;
414 loc_(Vector3::ZERO),
ori_(Quaternion::IDENTITY),
422 void assertConsistency()
const;
424 std::ostream& print(std::ostream &out)
const;
448 inline coord_t cutPoint()
const;
489 friend class NUKLEI_SERIALIZATION_FRIEND_CLASSNAME;
490 template<
class Archive>
491 void serialize(Archive &ar,
const unsigned int version)
493 ar & NUKLEI_SERIALIZATION_MAKE_NVP
495 NUKLEI_SERIALIZATION_BASE(
base) );
496 ar & NUKLEI_SERIALIZATION_NVP(
loc_)
497 & NUKLEI_SERIALIZATION_NVP(
ori_)
498 & NUKLEI_SERIALIZATION_NVP(
loc_h_)
499 & NUKLEI_SERIALIZATION_NVP(
ori_h_);
504 template<
class OriGrp>
508 typedef NUKLEI_UNIQUE_PTR< kernel::r3xs2_base<OriGrp> >
ptr;
513 using Super::hasDescriptor;
514 using Super::getDescriptor;
515 using Super::setDescriptor;
516 using Super::getFlag;
523 loc_(Vector3::ZERO), dir_(Vector3::UNIT_X),
531 void assertConsistency()
const;
533 std::ostream& print(std::ostream &out)
const;
561 inline coord_t cutPoint()
const;
600 friend class NUKLEI_SERIALIZATION_FRIEND_CLASSNAME;
601 template<
class Archive>
602 void serialize(Archive &ar,
const unsigned int version)
604 ar & NUKLEI_SERIALIZATION_MAKE_NVP
606 NUKLEI_SERIALIZATION_BASE(
base) );
607 ar & NUKLEI_SERIALIZATION_NVP(loc_)
608 & NUKLEI_SERIALIZATION_NVP(dir_)
609 & NUKLEI_SERIALIZATION_NVP(loc_h_)
610 & NUKLEI_SERIALIZATION_NVP(dir_h_);
629 typedef NUKLEI_UNIQUE_PTR<kernel::r3>
ptr;
641 { *
this =
dynamic_cast<const kernel::r3&
>(k); }
643 void assertConsistency()
const;
645 std::ostream& print(std::ostream &out)
const;
666 inline coord_t cutPoint()
const;
696 friend class NUKLEI_SERIALIZATION_FRIEND_CLASSNAME;
697 template<
class Archive>
698 void serialize(Archive &ar,
const unsigned int version)
700 ar & NUKLEI_SERIALIZATION_MAKE_NVP
702 NUKLEI_SERIALIZATION_BASE(
base) );
703 ar & NUKLEI_SERIALIZATION_NVP(loc_)
704 & NUKLEI_SERIALIZATION_NVP(loc_h_);
712 if (r3e < FLOATTOL)
return 0;
716 template<
class OriGrp>
719 coord_t r3e = PositionKernel::eval(loc_, loc_h_, k.loc_);
720 if (r3e < FLOATTOL)
return 0;
721 else return r3e * OrientationKernel::eval(dir_, dir_h_, k.dir_);
727 return PositionKernel::eval(loc_, loc_h_, k.loc_);
734 return PositionKernel::cut_point(
loc_h_);
737 template<
class OriGrp>
738 coord_t r3xs2_base<OriGrp>::cutPoint()
const
740 return PositionKernel::cut_point(loc_h_);
746 return PositionKernel::cut_point(loc_h_);
755 template<
class OriGrp>
756 void r3xs2_base<OriGrp>::assertConsistency()
const
758 NUKLEI_TRACE_BEGIN();
767 kernel::r3xs2_base<groupS::s2>::print(std::ostream &out)
const
770 idt <<
"Kernel R^3 x S^2: [ weight = " << w_ <<
" ]" << std::endl;
773 idt2 <<
"Location: " << loc_ << std::endl;
774 idt2 <<
"LocWidth: " << loc_h_ << std::endl;
775 idt2 <<
"Direction: " << dir_ << std::endl;
776 idt2 <<
"DirWidth: " << dir_h_ << std::endl;
783 kernel::r3xs2_base<groupS::s2p>::print(std::ostream &out)
const
786 idt <<
"Kernel R^3 x S^2_+: [ weight = " << w_ <<
" ]" << std::endl;
789 idt2 <<
"Location: " << loc_ << std::endl;
790 idt2 <<
"LocWidth: " << loc_h_ << std::endl;
791 idt2 <<
"Direction: " << dir_ << std::endl;
792 idt2 <<
"DirWidth: " << dir_h_ << std::endl;
813 template<
class OriGrp>
821 s.loc_ = PositionSampler::s(loc_, loc_h_);
822 s.dir_ = OrientationSampler::s(dir_, dir_h_);
824 if (hasDescriptor()) s.setDescriptor(getDescriptor());
828 template<
class OriGrp>
833 se3k.
loc_ = r3xs2pk.loc_;
834 se3k.
ori_ = la::so3FromS2(r3xs2pk.dir_);
835 if (hasDescriptor()) se3k.setDescriptor(getDescriptor());
845 se3k.
loc_ = r3xs2pk.loc_;
846 se3k.
ori_ = la::so3FromS2(r3xs2pk.dir_);
847 if (hasDescriptor()) se3k.setDescriptor(getDescriptor());
853 kernel::r3xs2_base<groupS::s2p>::se3Proj()
const
855 kernel::r3xs2_base<groupS::s2p> r3xs2pk = *
this;
857 se3k.
loc_ = r3xs2pk.loc_;
859 se3k.ori_ = la::so3FromS2(r3xs2pk.dir_);
861 se3k.ori_ = la::so3FromS2(-r3xs2pk.dir_);
862 if (hasDescriptor()) se3k.setDescriptor(getDescriptor());
866 template<
class OriGrp>
867 kernel::r3xs2_base<OriGrp> r3xs2_base<OriGrp>::projectedOn(
const kernel::se3& k)
const
869 kernel::r3xs2_base<OriGrp> p;
870 la::project(p.loc_, p.dir_, k.loc_, k.ori_, loc_, dir_);
871 if (hasDescriptor()) p.setDescriptor(getDescriptor());
875 template<
class OriGrp>
876 kernel::r3xs2_base<OriGrp> r3xs2_base<OriGrp>::transformedWith(
const kernel::se3& k)
const
878 kernel::r3xs2_base<OriGrp> p;
880 if (hasDescriptor()) p.setDescriptor(getDescriptor());
884 template<
class OriGrp>
885 void r3xs2_base<OriGrp>::makeTransformWith(
const kernel::se3& k)
891 kernel::r3xs2_base<groupS::s2>
892 kernel::r3xs2_base<groupS::s2>::linearInterpolation
893 (
const kernel::r3xs2_base<groupS::s2>& k,
897 kernel::r3xs2_base<groupS::s2> i;
898 i.loc_ = (1-x) * loc_ + x * k.loc_;
899 i.dir_ = la::normalized( (1-x) * dir_ + x * i.dir_ );
904 kernel::r3xs2_base<groupS::s2p>
905 kernel::r3xs2_base<groupS::s2p>::linearInterpolation
906 (
const kernel::r3xs2_base<groupS::s2p>& k,
910 kernel::r3xs2_base<groupS::s2p> i;
911 i.loc_ = (1-x) * loc_ + x * k.loc_;
913 if (dir_.Dot(d) < 0) d = - d;
914 i.dir_ = la::normalized( (1-x) * dir_ + x * d );
918 template<
class OriGrp>
920 kernel::r3xs2_base<OriGrp>::updateWidth
921 (
const kernel::r3xs2_base<OriGrp>& k,
924 loc_h_ = std::sqrt( (1-x) * loc_h_*loc_h_ +
925 x * std::pow(dist<groupS::r3>::d(loc_, k.loc_), 2) );
926 dir_h_ = std::sqrt( (1-x) * dir_h_*dir_h_ +
927 x * std::pow(dist<OriGrp>::d(dir_, k.dir_), 2) );
930 template<
class OriGrp>
932 kernel::r3xs2_base<OriGrp>::distanceTo(
const kernel::r3xs2_base<OriGrp>& k)
const
934 return std::make_pair(dist<groupS::r3>::d(loc_, k.loc_),
935 dist<OriGrp>::d(dir_, k.dir_));
940 NUKLEI_UNIQUE_PTR<kernel::se3>
943 NUKLEI_TRACE_BEGIN();
944 NUKLEI_UNIQUE_PTR<se3> p(
new se3(
static_cast<const T*
>(
this)->se3Sample()) );
950 NUKLEI_UNIQUE_PTR<kernel::se3>
953 NUKLEI_TRACE_BEGIN();
954 NUKLEI_UNIQUE_PTR<se3> p(
new se3(
static_cast<const T*
>(
this)->se3Proj()) );
963 #if BOOST_VERSION < 104100
968 NUKLEI_SERIALIZATION_DECLARE_TYPE_WITH_NAME(
nuklei::kernel::
r3xs2, "mdfh_kernel_r3xs2")
969 NUKLEI_SERIALIZATION_DECLARE_TYPE_WITH_NAME(
nuklei::kernel::
r3xs2p, "mdfh_kernel_r3xs2p")
970 NUKLEI_SERIALIZATION_DECLARE_TYPE_WITH_NAME(
nuklei::kernel::r3, "mdfh_kernel_r3")
972 #endif // BOOST_VERSION