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 "cob_3d_features/invariant_surface_feature.h"
00057 #include <unsupported/Eigen/FFT>
00058 #include <unsupported/Eigen/Polynomials>
00059 
00060 template<typename TSurface, typename Scalar, typename Real, typename TAffine>
00061 void cob_3d_features::InvariantSurfaceFeature<TSurface,Scalar,Real,TAffine>::compute() {
00062   result_.reset(new Result);
00063 
00064   
00065   std::vector<TVector> keypoints;
00066   generateKeypoints(keypoints);
00067   std::cout<<"got "<<keypoints.size()<<" keypoints"<<std::endl;
00068 
00069   result_->resize(keypoints.size());
00070   for(size_t j=0; j<radii_.size(); j++) {
00071         for(size_t i=0; i<keypoints.size(); i++) {              
00072       
00073       std::vector<Triangle> submap;
00074       subsample(keypoints[i], radii_[j], submap);
00075 
00076           
00077           sr_.clear();
00078           
00079           for(size_t s=0; s<submap.size(); s++) {
00080                   std::cout<<s<<std::endl;
00081                   sr_ += submap[s];
00082           }
00083                   
00084           sr_.finish((*result_)[j]);
00085     }
00086   }
00087 }
00088 
00089 template<typename TSurface, typename Scalar, typename Real, typename TAffine>
00090 void cob_3d_features::InvariantSurfaceFeature<TSurface,Scalar,Real,TAffine>::Triangle::compute(const typename S::Samples &samples) {
00091         for(int i=0; i<3; i++) {
00092                 this->p3_[i](0) = p_[i](0);
00093                 this->p3_[i](1) = p_[i](1);
00094                 this->p3_[i](2) = model_->model(p_[i](0), p_[i](1));
00095         }
00096         
00097         
00098         if(area<TSurface::DEGREE>()>0.0001) {
00099 std::cout<<"subdivide "<<area<TSurface::DEGREE>()<<std::endl;
00100                 Eigen::Matrix<Scalar, 2, 1> ps[3];
00101                 for(int i=0; i<3; i++)
00102                         ps[i] = ((p_[i])+(p_[(i+1)%3]))/2;
00103 
00104                 Triangle tris[4];
00105                 for(int i=0; i<3; i++) {
00106                         tris[i].p_[i] = p_[i];
00107                         tris[i].p_[(i+1)%3] = ps[i];
00108                         tris[i].p_[(i+2)%3] = ps[(i+2)%3];
00109                         tris[3].p_[i] = ps[i];
00110                 }
00111                 for(int i=0; i<4; i++) {
00112                         tris[i].model_ = model_;
00113                         tris[i].compute(samples);
00114                         for(size_t j=0; j<this->f_.size(); j++)
00115                                 for(size_t k=0; k<this->f_[j].size(); k++)
00116                                         this->f_[j][k] += ((typename S::Values)tris[i])[j][k];
00117                 }
00118         } else 
00119                 cob_3d_features::invariant_surface_feature::SingleTriangle<Scalar, typename S::Samples, typename S::Values>::compute(samples);
00120 }
00121 
00122 template<typename TSurface, typename Scalar, typename Real, typename TAffine>
00123 void cob_3d_features::InvariantSurfaceFeature<TSurface,Scalar,Real,TAffine>::generateKeypoints(std::vector<TVector> &keypoints) const {
00124   
00125 
00126   
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139   for(size_t i=0; i<input_->size(); i++) {                         
00140     if((*input_)[i].segments_.size()<1) continue;        
00141       for(size_t k=0; k<(*input_)[i].segments_[0].size(); k+=20) {   
00142         TVector v;
00143         v(0) = (*input_)[i].segments_[0][k](0);
00144         v(1) = (*input_)[i].segments_[0][k](1);
00145         v(2) = (*input_)[i].model_.model( v(0), v(1) );
00146         keypoints.push_back(v);
00147         break;
00148       }
00149   }
00150 }
00151 
00152 template<typename TSurface, typename Scalar, typename Real, typename TAffine>
00153 Eigen::Matrix<Scalar, 2, 1>
00154 cob_3d_features::InvariantSurfaceFeature<TSurface,Scalar,Real,TAffine>::Triangle::intersection_on_line(const TVector &at, const Scalar r2, const Eigen::Matrix<Scalar, 2, 1> &a, const Eigen::Matrix<Scalar, 2, 1> &b) const {
00155 
00156 assert((this->at(a)-at).squaredNorm()>r2 || (this->at(b)-at).squaredNorm()>r2);
00157 
00158         Eigen::PolynomialSolver<typename TSurface::Model::VectorU1D::Scalar, 2*TSurface::DEGREE> solver;        
00159         typename TSurface::Model::VectorU1D p = model_->transformation_1D( (b-a).template cast<typename TSurface::Model::VectorU1D::Scalar>(), a.template cast<typename TSurface::Model::VectorU1D::Scalar>(), at.template cast<typename TSurface::Model::VectorU1D::Scalar>());
00160         p(0) -= r2;
00161         solver.compute(p);
00162 
00163 
00164         
00165         std::vector<typename TSurface::Model::VectorU1D::Scalar> r;
00166         solver.realRoots(r);
00167         assert(r.size()>0);
00168         
00169         const typename TSurface::Model::VectorU1D::Scalar mid = 0.5f;
00170         size_t best=0;
00171         for(size_t i=1;i<r.size();++i)
00172         {
00173                 if( (r[best]-mid)*(r[best]-mid)>(r[i]-mid)*(r[i]-mid))
00174                         best=i;
00175         }
00176 
00177         assert(r[best]>=0 && r[best]<=1);
00178         
00179         Eigen::Matrix<Scalar, 2, 1> v;
00180         v(0) = (b(0)-a(0))*r[best]+a(0);
00181         v(1) = (b(1)-a(1))*r[best]+a(1);
00182 
00183         return v;
00184 }
00185         
00186 template<typename TSurface, typename Scalar, typename Real, typename TAffine>
00187 void cob_3d_features::InvariantSurfaceFeature<TSurface,Scalar,Real,TAffine>::Triangle::subsample(const typename S::Samples &samples, const TVector &at, const Scalar r2, std::vector<Triangle> &res) const {
00188         
00189         bool b[3];
00190         int n=0;
00191         for(int j=0; j<3; j++)
00192                 n+= (b[j] = ( (this->p3_[j]-at).squaredNorm()<=r2))?1:0;
00193 
00194         if(n==0)
00195                 return;
00196         else if(n==3)
00197                 res.push_back(*this);
00198         else if(n==2) {
00199                 Triangle tr1 = *this;
00200                 Triangle tr2 = *this;
00201                 const int ind = !b[0]?0:(!b[1]?1:2);
00202 
00203                 
00204 
00205 
00206                 
00207                 tr1.p_[ind] = intersection_on_line(at, r2, p_[ind], p_[ (ind+2)%3 ]);
00208                 tr2.p_[(ind+1)%3] = intersection_on_line(at, r2, p_[ind], p_[ (ind+1)%3 ]);
00209                 tr2.p_[ind] = tr1.p_[ind];
00210                 
00211                 tr1.compute(samples);
00212                 tr2.compute(samples);
00213                 res.push_back(tr1);
00214                 res.push_back(tr2);
00215         }
00216         else if(n==1) {
00217                 Triangle tr = *this;
00218                 const int ind = b[0]?0:(b[1]?1:2);
00219                 
00220                 tr.p_[(ind+1)%3] = intersection_on_line(at, r2, tr.p_[ind], tr.p_[ (ind+1)%3 ]);
00221                 tr.p_[(ind+2)%3] = intersection_on_line(at, r2, tr.p_[ind], tr.p_[ (ind+2)%3 ]);
00222                 
00223                 tr.compute(samples);
00224                 res.push_back(tr);
00225         }
00226 }
00227 
00228 template<typename TSurface, typename Scalar, typename Real, typename TAffine>
00229 void cob_3d_features::InvariantSurfaceFeature<TSurface,Scalar,Real,TAffine>::subsample(const TVector &at, const Scalar r2, std::vector<Triangle> &res) const {
00230         res.clear();
00231         for(size_t i=0; i<triangulated_input_.size(); i++)
00232                 triangulated_input_[i].subsample(samples_, at, r2, res);
00233 }
00234 
00235 template<typename TSurface, typename Scalar, typename Real, typename TAffine>
00236 void cob_3d_features::InvariantSurfaceFeature<TSurface,Scalar,Real,TAffine>::setInput(PTSurfaceList surfs) {
00237         input_=surfs;
00238         triangulated_input_.clear();
00239         
00240         for(size_t indx=0; indx<input_->size(); indx++) {
00241                   TPPLPartition pp;
00242                   list<TPPLPoly> polys,result;
00243 
00244                   
00245                   for(size_t i=0; i<(*input_)[indx].segments_.size(); i++) {
00246 std::cout<<"S "<<indx<<" "<<i<<" "<<(*input_)[indx].segments_[i].size()<<std::endl;
00247                         TPPLPoly poly;
00248                         poly.Init((*input_)[indx].segments_[i].size());
00249                         poly.SetHole(i!=0);
00250                         poly.SetOrientation(i!=0?TPPL_CW:TPPL_CCW);
00251 
00252                         for(size_t j=0; j<(*input_)[indx].segments_[i].size(); j++) {
00253                           poly[j].x = (*input_)[indx].segments_[i][j](0);
00254                           poly[j].y = (*input_)[indx].segments_[i][j](1);
00255                         }
00256                         
00257                         polys.push_back(poly);
00258                         break;
00259                   }
00260 
00261                   pp.Triangulate_EC(&polys,&result);
00262 
00263                 std::cout<<"triangles "<<result.size()<<std::endl;
00264                   Eigen::Vector3f v1,v2,v3;
00265                   for(std::list<TPPLPoly>::iterator it=result.begin(); it!=result.end(); it++) {
00266                         if(it->GetNumPoints()!=3) continue;
00267 
00268                         Triangle tr;
00269                         tr.model_ = &(*input_)[indx].model_;
00270                         for(int j=0; j<3; j++)
00271                                 Triangle::set(tr.p_[j], it->GetPoint(j));
00272                         tr.compute(samples_);
00273                         
00274                         triangulated_input_.push_back(tr);
00275                   }
00276         }
00277 }
00278 
00279