Go to the documentation of this file.00001
00060 #ifndef NARF_KP_H_
00061 #define NARF_KP_H_
00062
00063 namespace cob_3d_registration {
00064
00065
00066 #ifdef PCL_VERSION_COMPARE
00067
00068 struct NarfKPoint
00069 {
00070 PCL_ADD_POINT4D;
00071 pcl::FPFHSignature33 fpfh;
00072 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00073 } EIGEN_ALIGN16;
00074
00075 POINT_CLOUD_REGISTER_POINT_STRUCT (NarfKPoint,
00076 (float, x, x)
00077 (float, y, y)
00078 (float, z, z)
00079 (float[33], fpfh,fpfh)
00080
00081 )
00082 #else
00083 struct EIGEN_ALIGN16 NarfKPoint
00084 {
00085 PCL_ADD_POINT4D;
00086
00087 pcl::FPFHSignature33 fpfh;
00088
00089 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00090 };
00091 #endif
00092
00093 template<typename Point>
00094 class Keypoints_Narf : public RegKeypointCorrespondence<Point, NarfKPoint>
00095 {
00096 float radius_;
00097 float thr_;
00098 float dist_threshold_;
00099
00100 Point keypoint2point(const NarfKPoint &kp) {
00101 Point p;
00102 p.x=kp.x;
00103 p.y=kp.y;
00104 p.z=kp.z;
00105 return p;
00106 }
00107
00108 void extractFeatures(const pcl::PointCloud<Point>& point_cloud, pcl::PointCloud<NarfKPoint> &narf_descriptors);
00109
00110 public:
00111 Keypoints_Narf():
00112 radius_(0.05), thr_(0.1), dist_threshold_(0.1)
00113 {}
00114
00115 void setRadius(float v) {radius_ = v;}
00116 void setThreshold(float v) {thr_ = v;}
00117 void setDisThreshold(float v) {dist_threshold_ = v;}
00118
00119 virtual bool compute(const pcl::PointCloud<Point> &src, const pcl::PointCloud<Point> &tgt) {
00120 ROS_INFO("calc narf for source %d", (int)src.size());
00121 {
00122 extractFeatures(src, this->keypoints_src_);
00123 }
00124
00125 ROS_INFO("calc narf for target %d", (int)tgt.size());
00126 {
00127 extractFeatures(tgt, this->keypoints_tgt_);
00128 }
00129
00130 ROS_INFO("%d %d", (int)this->keypoints_src_.size(), (int)this->keypoints_tgt_.size());
00131
00132 return this->keypoints_src_.size()>0 && this->keypoints_tgt_.size()>0;
00133 }
00134 #ifdef PCL_VERSION_COMPARE
00135 virtual void getCorrespondences(pcl::Correspondences &correspondences) {
00136 #else
00137 virtual void getCorrespondences(std::vector<pcl::registration::Correspondence> &correspondences) {
00138 #endif
00139 pcl::PointCloud<pcl::FPFHSignature33> tsrc, ttgt;
00140
00141 if(this->keypoints_src_.size()<1||this->keypoints_tgt_.size()<1) {
00142 ROS_ERROR("cannot compute 0 correspondences!");
00143 return;
00144 }
00145
00146 for(int i=0; i<(int)this->keypoints_src_.size(); i++)
00147 tsrc.points.push_back(this->keypoints_src_.points[i].fpfh);
00148 for(int i=0; i<(int)this->keypoints_tgt_.size(); i++)
00149 ttgt.points.push_back(this->keypoints_tgt_.points[i].fpfh);
00150 tsrc.height=ttgt.height=1;
00151 ttgt.width=ttgt.size();
00152 tsrc.width=tsrc.size();
00153
00154 {
00155 IndicesPtr indices_;
00156 indices_.reset (new std::vector<int>);
00157 indices_->resize (tsrc.points.size ());
00158 for(int i=0; i<(int)tsrc.size(); i++)
00159 (*indices_)[i]=i;
00160
00161
00162 #ifdef PCL_VERSION_COMPARE
00163 pcl::search::KdTree<pcl::FPFHSignature33> tree_reciprocal;
00164 pcl::search::KdTree<pcl::FPFHSignature33> tree_;
00165 #else
00166 pcl::KdTreeFLANN<pcl::FPFHSignature33> tree_reciprocal;
00167 pcl::KdTreeFLANN<pcl::FPFHSignature33> tree_;
00168 #endif
00169 tree_reciprocal.setInputCloud(tsrc.makeShared(), indices_);
00170 tree_.setInputCloud(ttgt.makeShared());
00171
00172 correspondences.resize(indices_->size());
00173 std::vector<int> index(1);
00174 std::vector<float> distance(1);
00175 std::vector<int> index_reciprocal(1);
00176 std::vector<float> distance_reciprocal(1);
00177 #ifdef PCL_VERSION_COMPARE
00178 pcl::Correspondence corr;
00179 #else
00180 pcl::registration::Correspondence corr;
00181 #endif
00182 unsigned int nr_valid_correspondences = 0;
00183
00184 for (unsigned int i = 0; i < indices_->size(); ++i)
00185 {
00186 tree_.nearestKSearch(tsrc.points[(*indices_)[i]], 1, index, distance);
00187 tree_reciprocal.nearestKSearch(ttgt.points[index[0]], 1, index_reciprocal, distance_reciprocal);
00188
00189 if ( (*indices_)[i] == index_reciprocal[0] )
00190 {
00191 #ifdef PCL_VERSION_COMPARE
00192 corr.index_query = (*indices_)[i];
00193 corr.index_match = index[0];
00194 #else
00195 corr.indexQuery = (*indices_)[i];
00196 corr.indexMatch = index[0];
00197 #endif
00198 corr.distance = (this->keypoints_tgt_[index[0]].getVector3fMap()-this->keypoints_src_[(*indices_)[i]].getVector3fMap()).squaredNorm();
00199 correspondences[nr_valid_correspondences] = corr;
00200 ++nr_valid_correspondences;
00201 }
00202 }
00203 correspondences.resize(nr_valid_correspondences);
00204 }
00205
00206 ROS_INFO("cor found %d",(int)correspondences.size());
00207 }
00208
00209 Point getPointForKeypointSrc(const int ind) {return keypoint2point(this->keypoints_src_[ind]);}
00210 Point getPointForKeypointTgt(const int ind) {return keypoint2point(this->keypoints_tgt_[ind]);}
00211 };
00212
00213 #include "impl/narf_kp.hpp"
00214 }
00215
00216 #endif