00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #pragma once
00055
00056 #include <complex>
00057 #include <vector>
00058 #include <boost/shared_ptr.hpp>
00059 #include <Eigen/Geometry>
00060 #include <cob_3d_mapping_common/polypartition.h>
00061 #include <pcl/PolygonMesh.h>
00062
00063 #include "ShapeSPH/Util/Signature.h"
00064 #include "ShapeSPH/Util/SphereSampler.h"
00065 #include "ShapeSPH/Util/lineqn.h"
00066 #include "ShapeSPH/Util/SphericalPolynomials.h"
00067 #include "invariant_surface_feature/triangle.hpp"
00068
00069 namespace cob_3d_features
00070 {
00072 template<typename TSurface, typename Scalar=double, typename Real=float, typename TAffine=Eigen::Affine3f>
00073 class InvariantSurfaceFeature
00074 {
00075 typedef Sampler<Real, Scalar> S;
00076
00077 const int num_radius_, num_angle_;
00078 S sr_;
00079 typename S::Samples samples_;
00080 public:
00081
00082 typedef Eigen::Matrix<Scalar, 3, 1> TVector;
00083 typedef std::vector<TSurface> TSurfaceList;
00084 typedef boost::shared_ptr<TSurfaceList> PTSurfaceList;
00085
00086 typedef std::vector<Signature< Real > > Result;
00087 typedef boost::shared_ptr<Result> PResult;
00088 typedef boost::shared_ptr<const Result> PResultConst;
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 typedef enum {
00114 INVARAINCE_X=1, INVARAINCE_Y=2, INVARAINCE_Z=4,
00115 INVARAINCE_INCLINATION=8, INVARAINCE_AZIMUTH=16,
00116 INVARAINCE_ALL=0x1f
00117 } EINVARAINCE;
00118
00120 InvariantSurfaceFeature(const int num_radius, const int num_angle) :
00121 num_radius_(num_radius), num_angle_(num_angle),
00122 sr_((Real)num_radius, num_radius, num_angle),
00123 invariance_(INVARAINCE_ALL)
00124 {
00125 sr_.getSamples(samples_);
00126
00127 }
00128
00130 virtual ~InvariantSurfaceFeature() {}
00131
00132
00133 void setInput(PTSurfaceList surfs);
00134 void compute();
00135
00136 PResultConst getResult() const {return result_;}
00137
00138 const TAffine &getTransformation() const {return transform_;}
00139 void setTransformation(const TAffine &t) {transform_=t;}
00140
00141 const EINVARAINCE &getInvarianceSettings() const {return invariance_;}
00142 void setInvarianceSettings(const EINVARAINCE &t) {invariance_=t;}
00143
00144 const std::vector<float> &getRadii() const {return radii_;}
00145 void addRadius(const float r) {
00146 std::vector<float>::iterator it = radii_.begin();
00147 while(it!=radii_.end() && *it>r) ++it;
00148 radii_.insert(it, r);
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158 bool test_singleTriangle(const int num) const;
00159 pcl::PolygonMesh::Ptr test_subsampling_of_Map(const int num, const Scalar r2);
00160 void test_addOffset(const Scalar off_x, const Scalar off_y, const Scalar off_z);
00161 void test_rotate(const Scalar angle);
00162
00163
00164 void dbg_mesh_of_subsamp(const TVector &at, const Scalar radius, std::vector<TVector> &pts, std::vector<int> &inds) const;
00165 void dbg_keypoints(std::vector<TVector> &keypoints) const {generateKeypoints(keypoints);}
00166 pcl::PolygonMesh::Ptr dbg_Mesh_of_Map() const {return dbg_triangles2mesh(triangulated_input_);}
00167
00168 protected:
00169 struct Triangle : public cob_3d_features::invariant_surface_feature::SingleTriangle<Scalar, typename S::Samples, typename S::Values> {
00170
00171
00172
00173
00174 Eigen::Matrix<Scalar, 2, 1> p_[3];
00175 typename TSurface::Model *model_;
00176
00177 inline static void set(Eigen::Matrix<Scalar, 2, 1> &p, const TPPLPoint &tp) {
00178 p(0) = tp.x;
00179 p(1) = tp.y;
00180 }
00181
00182 void compute(const typename S::Samples &samples);
00183 void subsample(const typename S::Samples &samples, const TVector &at, const Scalar r2, std::vector<Triangle> &res) const;
00184 std::complex<Scalar> kernel(const Scalar m, const Scalar n, const Scalar p) const;
00185
00186 void print() const;
00187 private:
00188 Eigen::Matrix<Scalar, 2, 1> intersection_on_line(const TVector &at, const Scalar r2, const Eigen::Matrix<Scalar, 2, 1> &a, const Eigen::Matrix<Scalar, 2, 1> &b) const;
00189
00190 std::complex<Scalar> kernel_lin(const Scalar m, const Scalar n, const Scalar p, const Scalar x0, const Scalar y0, const Scalar y1, const Scalar d1, const Scalar d2) const;
00191
00192
00193 inline Eigen::Matrix<Scalar, 3, 1> at(const Scalar x, const Scalar y) const {
00194 Eigen::Matrix<Scalar, 2, 1> p;
00195 p(0)=x;p(1)=y;
00196 return at(p);
00197 }
00198
00199 inline Eigen::Matrix<Scalar, 3, 1> at(const Eigen::Matrix<Scalar, 2, 1> &p) const {
00200 Eigen::Matrix<Scalar, 3, 1> v;
00201 v(0) = p(0); v(1) = p(1);
00202 v(2) = model_->model(p(0),p(1));
00203 return v;
00204 }
00205
00206 template<const int Degree>
00207 Scalar area() const {
00208
00209 const Eigen::Matrix<Scalar, 2, 1> mid2 = ((p_[0])+(p_[1])+(p_[2]))/3;
00210 Eigen::Matrix<Scalar, 3, 1> mid23, mid3, v1,v2,v3;
00211
00212 v1.template head<2>() = p_[0];
00213 v2.template head<2>() = p_[1];
00214 v3.template head<2>() = p_[2];
00215 v1(2) = model_->model((p_[0])(0), (p_[0])(1));
00216 v2(2) = model_->model((p_[1])(0), (p_[1])(1));
00217 v3(2) = model_->model((p_[2])(0), (p_[2])(1));
00218
00219 mid23(0) = mid2(0);
00220 mid23(1) = mid2(1);
00221 mid3 = mid23;
00222 mid3(2) = (v1(2)+v2(2)+v3(2))/3;
00223 mid23(2) = model_->model(mid2(0),mid2(1));
00224
00225
00226 return (mid3 - mid23).norm()*(v1-v2).cross(v3-v2).norm();
00227 }
00228 };
00229
00230 struct VectorWithParams {
00231 TVector v_;
00232 typename TSurface::TParam::VectorU *param_;
00233 };
00234
00235 PTSurfaceList input_;
00236 std::vector<Triangle> triangulated_input_;
00237
00238 TAffine transform_;
00239 EINVARAINCE invariance_;
00240 std::vector<float> radii_;
00241 PResult result_;
00242
00243 void generateKeypoints(std::vector<TVector> &keypoints) const;
00244 void subsample(const TVector &at, const Scalar r2, std::vector<Triangle> &res) const;
00245
00246
00247 pcl::PolygonMesh::Ptr dbg_triangles2mesh(const std::vector<Triangle> &res) const;
00248 };
00249 }