invariant_surface_feature.hpp
Go to the documentation of this file.
00001 /****************************************************************
00002  *
00003  * Copyright (c) 2011
00004  *
00005  * Fraunhofer Institute for Manufacturing Engineering
00006  * and Automation (IPA)
00007  *
00008  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00009  *
00010  * Project name: care-o-bot
00011  * ROS stack name: cob_environment_perception_intern
00012  * ROS package name: cob_3d_features
00013  * Description:
00014  *
00015  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00016  *
00017  * Author: Joshua Hampp, email:joshua.hampp@ipa.fraunhofer.de
00018  *
00019  * Date of creation: 03/2014
00020  * ToDo:
00021  *
00022  *
00023  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00024  *
00025  * Redistribution and use in source and binary forms, with or without
00026  * modification, are permitted provided that the following conditions are met:
00027  *
00028  *     * Redistributions of source code must retain the above copyright
00029  *       notice, this list of conditions and the following disclaimer.
00030  *     * Redistributions in binary form must reproduce the above copyright
00031  *       notice, this list of conditions and the following disclaimer in the
00032  *       documentation and/or other materials provided with the distribution.
00033  *     * Neither the name of the Fraunhofer Institute for Manufacturing
00034  *       Engineering and Automation (IPA) nor the names of its
00035  *       contributors may be used to endorse or promote products derived from
00036  *       this software without specific prior written permission.
00037  *
00038  * This program is free software: you can redistribute it and/or modify
00039  * it under the terms of the GNU Lesser General Public License LGPL as
00040  * published by the Free Software Foundation, either version 3 of the
00041  * License, or (at your option) any later version.
00042  *
00043  * This program is distributed in the hope that it will be useful,
00044  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00045  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00046  * GNU Lesser General Public License LGPL for more details.
00047  *
00048  * You should have received a copy of the GNU Lesser General Public
00049  * License LGPL along with this program.
00050  * If not, see <http://www.gnu.org/licenses/>.
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   //generate keypoints (e.g. reduce number of points by area)
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       //generate sub map
00073       std::vector<Triangle> submap;
00074       subsample(keypoints[i], radii_[j], submap);
00075 
00076           //calc. rotation invariant feature
00077           sr_.clear();
00078           //sum features
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         //check if further sub-sampling is necessary?
00098         if(area<TSurface::DEGREE>()>0.0001/*||rand()%13==0||depth<4*/) {
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   //TODO: reduce points
00125 
00126   /*for(size_t i=0; i<input_->size(); i++) {                         //surfaces
00127     for(size_t j=0; j<(*input_)[i].segments_.size(); j++) {        //outline/holes
00128       for(size_t k=0; k<(*input_)[i].segments_[j].size(); k++) {   //points
00129         TVector v;
00130         v(0) = (*input_)[i].segments_[j][k](0);
00131         v(1) = (*input_)[i].segments_[j][k](1);
00132         v(2) = (*input_)[i].model_.model( v(0), v(1) );
00133         keypoints.push_back(v);
00134       }
00135     }
00136   }*/
00137 
00138 
00139   for(size_t i=0; i<input_->size(); i++) {                         //surfaces
00140     if((*input_)[i].segments_.size()<1) continue;        //outline/holes
00141       for(size_t k=0; k<(*input_)[i].segments_[0].size(); k+=20) {   //points
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 //std::cout<<"p "<<p.transpose()<<std::endl;
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         //brute force (for the start)
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                 /*print();
00204                 std::cout<<"I "<<b[0]<<" "<<b[1]<<" "<<b[2]<<std::endl;
00205                 std::cout<<"ind "<<ind<<" "<<(ind+2)%3<<std::endl;*/
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                   //fill polys
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 //#define PCL_INSTANTIATE_OrganizedCurvatureEstimationOMP(T,NT,LabelT,OutT) template class PCL_EXPORTS cob_3d_features::OrganizedCurvatureEstimationOMP<T,NT,LabelT,OutT>;
00279 


cob_3d_features
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:02:26