Go to the documentation of this file.00001
00065 #include <pcl/common/transformation_from_correspondences.h>
00066
00067
00068 template <typename Point>
00069 void TransformationEstimationMultipleCorrespondences<Point>::computeTransformation
00070 (PointCloudSource &output)
00071 {
00072 final_transformation_ = findTF_fast(*target_, output, rmax_, tmax_);
00073 converged_ = true;
00074 }
00075
00076 template <typename Point>
00077 Eigen::Matrix4f TransformationEstimationMultipleCorrespondences<Point>::compute(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new)
00078 {
00079 return findTF_fast(pc_old, pc_new, rmax_, tmax_);
00080 }
00081
00082 template <typename Point>
00083 Eigen::Matrix4f TransformationEstimationMultipleCorrespondences<Point>::findTF_fast
00084 (const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new,
00085 const float rmax, const float tmax, Eigen::Matrix4f tf)
00086 {
00087 std::vector<SORT_S2> tv;
00088 std::vector<COR_S> cors;
00089
00090 for(size_t i=0; i<pc_new.size(); i++) {
00091 SORT_S2 s;
00092 s.dis=pc_new.points[i].getVector3fMap().norm();
00093 s.ind=(int)i;
00094 tv.push_back(s);
00095 }
00096
00097 SORT_S2 _s_;
00098 std::sort(tv.begin(),tv.end(), _s_);
00099
00100 std::vector<int> weight_o, weight_n;
00101
00102 weight_o.resize(pc_old.size(), 0);
00103 weight_n.resize(pc_new.size(), 0);
00104
00105 float rmax_ = sinf(rmax);
00106 rmax_*=rmax_;
00107
00108 weight_o.resize(pc_old.size(), 0);
00109 weight_n.resize(pc_new.size(), 0);
00110
00111
00112 COR_S c;
00113 for(size_t i=0; i<pc_old.size(); i++) {
00114 float t = pc_old.points[i].getVector3fMap().norm();
00115 Eigen::Vector3f vo = pc_old.points[i].getVector3fMap();
00116
00117
00118 for(int j=search_sorted_vector(tv,t-tmax); j<(int)tv.size(); j++) {
00119
00120 float dT = std::abs(tv[j].dis-t);
00121 if( dT < tmax) {
00122 Eigen::Vector3f vn = pc_new.points[tv[j].ind].getVector3fMap();
00123
00124 float dA = (((vn-vo).squaredNorm()/vo.squaredNorm()));
00125
00126 if(dA>=rmax_) continue;
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 c.ind_o = (int)i;
00140 c.ind_n = tv[j].ind;
00141 cors.push_back(c);
00142
00143 weight_o[i]++;
00144 weight_n[c.ind_n]++;
00145 }
00146 else if(tv[j].dis-t > tmax)
00147 break;
00148 }
00149
00150 }
00151
00152
00153 pcl::TransformationFromCorrespondences transFromCorr;
00154 for(size_t i=0; i<cors.size(); i++) {
00155 transFromCorr.add(pc_old[cors[i].ind_o].getVector3fMap(), pc_new[cors[i].ind_n].getVector3fMap(), 1./std::min(weight_o[cors[i].ind_o],weight_n[cors[i].ind_n]));
00156 }
00157 Eigen::Matrix4f tf2 = transFromCorr.getTransformation().matrix();
00158
00159
00160 if(tmax<0.01)
00161 return tf*tf2;
00162
00163 pcl::PointCloud<Point> tpc;
00164 pcl::transformPointCloud(pc_old,tpc,tf2);
00165
00166 return findTF_fast(tpc,pc_new, rmax*0.5, tmax*0.5, tf*tf2);
00167 }
00168
00169
00170 template <typename Point>
00171 int TransformationEstimationMultipleCorrespondences<Point>::search_sorted_vector(const std::vector<SORT_S2> &tv, const float val) {
00172 int i=tv.size()-1;
00173 int step=tv.size()/2-1;
00174 while(i&&step&&i<(int)tv.size()) {
00175 if(tv[i].dis>=val) {
00176 i-=step;
00177 }
00178 else if(tv[i].dis<val)
00179 i+=step;
00180 else
00181 break;
00182 step/=2;
00183 }
00184 return i;
00185 }