00001 #include <highgui.h>
00002 #include <Eigen/Eigen>
00003 #include <ndt_feature_reg/ndt_frame_proc.h>
00004
00005 namespace ndt_feature_reg
00006 {
00007
00008 void NDTFrameProc::addFrameIncremental (NDTFrame *f, bool skipMatching, bool ndtEstimateDI,
00009 bool match_full, bool match_no_association)
00010 {
00011
00012 if(!match_full)
00013 {
00014 detectKeypoints(f);
00015 }
00016
00017 f->computeNDT(ndtEstimateDI, this->non_mean);
00018
00019 if(!(match_no_association||match_full))
00020 {
00021 f->assignPts();
00022 calcDescriptors(f);
00023 }
00024 frames.push_back(f);
00025
00026 NDTFrameProc::EigenTransform tr;
00027 tr.setIdentity();
00028 if(frames.size() == 1)
00029 {
00030
00031 transformVector.clear();
00032 transformVector.push_back(tr);
00033 return;
00034 }
00035
00036
00037 Eigen::Affine3d transl_transform;
00038 Eigen::Affine3d rot_transform;
00039 std::vector<std::pair<int,int> > corr;
00040
00041 int i = frames.size()-1;
00042
00043 if(!(match_full || match_no_association))
00044 {
00045 pe.estimate(*frames[i-1],*frames[i]);
00046 transl_transform = (Eigen::Affine3d)Eigen::Translation3d(pe.trans);
00047 rot_transform = (Eigen::Affine3d)Eigen::Matrix3d(pe.rot);
00048 tr = transl_transform*rot_transform;
00049 if (!skipMatching)
00050 {
00051 corr.clear();
00052 corr = convertMatches(pe.inliers);
00053 lslgeneric::NDTMatcherFeatureD2D matcher_feat(corr, trim_factor);
00054 matcher_feat.match(frames[i-1]->ndt_map, frames[i]->ndt_map, tr, true);
00055
00056 }
00057 }
00058 else
00059 {
00060 lslgeneric::NDTMatcherD2D matcher;
00061 matcher.current_resolution = frames[i-1]->current_res/2;
00062 matcher.match(frames[i-1]->ndt_map, frames[i]->ndt_map, tr);
00063
00064 }
00065
00066
00067 transformVector.push_back(tr);
00068
00069 }
00070
00071 void NDTFrameProc::trimNbFrames (size_t maxNbFrames)
00072 {
00073 if (frames.size() > maxNbFrames)
00074 {
00075
00076 for(size_t i =0; i<frames.size()-1; i++)
00077 {
00078
00079 delete frames[i];
00080 }
00081 frames.erase(frames.begin(), frames.end() - 1);
00082 transformVector.erase(transformVector.begin(), transformVector.end() - 1);
00083 }
00084 }
00085
00086 void NDTFrameProc::processFrames (bool skipMatching, bool ndtEstimateDI,
00087 bool match_full, bool match_no_association)
00088 {
00089 if(frames.size() < 1) return;
00090
00091 transformVector.clear();
00092 NDTFrameProc::EigenTransform tr;
00093 tr.setIdentity();
00094 transformVector.push_back(tr);
00095
00096 if(!match_full)
00097 {
00098 detectKeypoints(frames[0]);
00099 }
00100 frames[0]->computeNDT(ndtEstimateDI, this->non_mean);
00101
00102 if(!(match_no_association||match_full))
00103 {
00104 frames[0]->assignPts();
00105 calcDescriptors(frames[0]);
00106 }
00107
00108 Eigen::Affine3d transl_transform;
00109 Eigen::Affine3d rot_transform;
00110 std::vector<std::pair<int,int> > corr;
00111
00112 for(size_t i=1; i<frames.size(); i++)
00113 {
00114
00115 if(!match_full)
00116 {
00117 detectKeypoints(frames[i]);
00118 }
00119 frames[i]->computeNDT(ndtEstimateDI, this->non_mean);
00120 if(!(match_no_association||match_full))
00121 {
00122 frames[i]->assignPts();
00123 calcDescriptors(frames[i]);
00124
00125 pe.estimate(*frames[i-1],*frames[i]);
00126 transl_transform = (Eigen::Affine3d)Eigen::Translation3d(pe.trans);
00127 rot_transform = (Eigen::Affine3d)Eigen::Matrix3d(pe.rot);
00128 tr = transl_transform*rot_transform;
00129
00130 if (!skipMatching)
00131 {
00132 corr.clear();
00133 corr = convertMatches(pe.inliers);
00134 lslgeneric::NDTMatcherFeatureD2D matcher_feat(corr, trim_factor);
00135 matcher_feat.match(frames[i-1]->ndt_map, frames[i]->ndt_map, tr, true);
00136
00137 }
00138 }
00139 else
00140 {
00141 lslgeneric::NDTMatcherD2D matcher;
00142 matcher.current_resolution = frames[i-1]->current_res/2;
00143 matcher.match(frames[i-1]->ndt_map, frames[i]->ndt_map, tr);
00144
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 }
00158
00159 }
00160
00161 void
00162 NDTFrameProc::detectKeypoints(NDTFrame *f) const
00163 {
00164 if (img_scale == 1.)
00165 {
00166 detector->detect(f->img, f->kpts);
00167 }
00168 else
00169 {
00170 cv::Mat tmp;
00171 cv::resize(f->img, tmp, cv::Size(), img_scale, img_scale, cv::INTER_LINEAR);
00172 detector->detect(tmp, f->kpts);
00173 float factor = 1./img_scale;
00174 scaleKeyPointPosition(f->kpts, factor);
00175 }
00176 }
00177
00178 void
00179 NDTFrameProc::calcDescriptors(NDTFrame *f) const
00180 {
00181 if (img_scale == 1.)
00182 {
00183 extractor->compute(f->img, f->kpts, f->dtors);
00184 }
00185 else
00186 {
00187 cv::Mat tmp;
00188 cv::resize(f->img, tmp, cv::Size(), img_scale, img_scale, cv::INTER_LINEAR);
00189 float factor = img_scale;
00190 scaleKeyPointPosition(f->kpts, factor);
00191 extractor->compute(tmp, f->kpts, f->dtors);
00192 factor = 1./img_scale;
00193 scaleKeyPointPosition(f->kpts, factor);
00194 }
00195 }
00196
00197 pcl::PointCloud<pcl::PointXYZRGB>::Ptr
00198 NDTFrameProc::createColoredFeaturePC(NDTFrame &f, pcl::PointXYZRGB color)
00199 {
00200 pcl::PointCloud<pcl::PointXYZRGB>::Ptr ret(new pcl::PointCloud<pcl::PointXYZRGB>());
00201 *ret = f.getColoredPointCloud();
00202 size_t w = f.img.size().width;
00203
00204 size_t idx = 0;
00205
00206 for (size_t i = 0; i < f.kpts.size(); i++)
00207 {
00208 int uKey = static_cast<int>(f.kpts[i].pt.x+0.5);
00209 int vKey = static_cast<int>(f.kpts[i].pt.y+0.5);
00210
00211 idx = vKey * w + uKey;
00212 pcl::PointXYZRGB& pt = ret->points[idx];
00213 pt.rgb = color.rgb;
00214 }
00215 return ret;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 }