Go to the documentation of this file.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 #ifndef NDTFRAME_HH
00036 #define NDTFRAME_HH
00037 
00038 #include "pcl/point_cloud.h"
00039 #include "pcl/point_types.h"
00040 #include "pcl/io/pcd_io.h"
00041 #include "pcl/features/feature.h"
00042 #include "pcl/registration/icp.h"
00043 #include "pcl/filters/voxel_grid.h"
00044 #include "opencv2/core/core.hpp"
00045 
00046 #include <cell_vector.h>
00047 #include <ndt_map.h>
00048 #include <depth_camera.h>
00049 
00050 #include <ndt_feature_reg/ndt_frame_tools.h>
00051 #include <pointcloud_utils.h>
00052 
00053 namespace ndt_feature_reg
00054 {
00055 inline
00056 double getDoubleTime(struct timeval& time)
00057 {
00058     return time.tv_sec + time.tv_usec * 1e-6;
00059 }
00060 
00061 inline
00062 double getDoubleTime()
00063 {
00064     struct timeval time;
00065     gettimeofday(&time,NULL);
00066     return getDoubleTime(time);
00067 }
00068 
00069 template <typename PointT>
00070 class NDTFrame
00071 {
00072 public:
00073     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00074 public:
00075     NDTFrame() : supportSize(3),maxVar(0.3),current_res(0.2)
00076     {
00077         ndt_map = lslgeneric::NDTMap<PointT>(&idx_prototype);
00078     }
00079     virtual ~NDTFrame()
00080     {
00081     }
00082     NDTFrame(const NDTFrame &other)
00083     {
00084         other.img.copyTo(img);
00085         other.depth_img.copyTo(depth_img);
00086         kpts = other.kpts;
00087         pc_kpts = other.pc_kpts;
00088         pts = other.pts;
00089         idx_prototype = other.idx_prototype;
00090         ndt_map = other.ndt_map;
00091         supportSize = other.supportSize;
00092         cameraParams = other.cameraParams;
00093         maxVar = other.maxVar;
00094         current_res=other.current_res;
00095         other.dtors.copyTo(dtors);
00096     }
00097 
00098     void clear()
00099     {
00100         maxVar = 0;
00101         kpts.resize(0);
00102         pc_kpts.resize(0);
00103         pts.resize(0);
00104         idx_prototype = lslgeneric::CellVector<PointT>();
00105         ndt_map = lslgeneric::NDTMap<PointT>(&idx_prototype);
00106 
00107         
00108         
00109     }
00110 
00111     cv::Mat img;
00112     cv::Mat depth_img;
00113     size_t supportSize;
00114     double maxVar;
00115     double current_res;
00116     lslgeneric::DepthCamera<PointT> cameraParams;
00117     std::vector<cv::KeyPoint> kpts;
00118     pcl::PointCloud<PointT> pc_kpts; 
00120     std::vector<Eigen::Vector4d, Eigen::aligned_allocator<Eigen::Vector4d> > pts;
00121 
00122     lslgeneric::CellVector<PointT> idx_prototype;
00123     lslgeneric::NDTMap<PointT> ndt_map;
00124 
00125     const PointT& getKeyPointCenter(int keyPointIdx)
00126     {
00127         
00128         const PointT &pt = pc_kpts[keyPointIdx]; 
00129         return pt;
00130     }
00131 
00132     void assignPts()
00133     {
00134         if(pc_kpts.size() == 0)
00135             computeNDT();
00136         pts.resize(pc_kpts.size());
00137         for (size_t i = 0; i < pc_kpts.size(); i++)
00138         {
00139             const PointT& pt = pc_kpts[i];
00140             pts[i].head(3) = Eigen::Vector3d(pt.x,pt.y,pt.z);
00141             pts[i](3) = 1.0;
00142             
00143         }
00144     }
00145 
00146     void computeNDT(bool estimateDI = false, bool nonMean = false)
00147     {
00148         if(kpts.size() > 0)
00149         {
00150             
00151             pc_kpts = ndt_map.loadDepthImageFeatures(depth_img,kpts,supportSize,maxVar,cameraParams,estimateDI,nonMean);
00152             
00153             
00154         }
00155         else
00156         {
00157             lslgeneric::LazyGrid<PointT> idx_prototype_grid(current_res);
00158             ndt_map = lslgeneric::NDTMap<PointT>(&idx_prototype_grid);
00159             
00160             ndt_map.loadDepthImage(depth_img,cameraParams);
00161             ndt_map.computeNDTCells();
00162             
00163             
00164 
00165         }
00166         
00167         
00168 
00169         
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182     }
00183     
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207     pcl::PointCloud<pcl::PointXYZRGB> getColoredPointCloud()
00208     {
00209         lslgeneric::DepthCamera<pcl::PointXYZRGB> cameraParamsLocal (cameraParams.fx,cameraParams.fy,cameraParams.cx,
00210                 cameraParams.cy,cameraParams.dist,cameraParams.ds, cameraParams.isFloatImg);
00211         cameraParamsLocal.setupDepthPointCloudLookUpTable(depth_img.size());
00212 
00213         pcl::PointCloud<pcl::PointXYZRGB> cloud; 
00214         cameraParamsLocal.convertDepthImageToPointCloud(depth_img,cloud);
00215 
00216         size_t w = img.size().width;
00217         size_t h = img.size().height;
00218         size_t idx = 0;
00219         cloud.width = w;
00220         cloud.height = h;
00221         cloud.is_dense = true;
00222         const uchar* pimg = img.ptr<uchar>(0);
00223         std::cout<<"img channels "<<img.channels()<<std::endl;
00224         pcl::PointXYZRGB color;
00225         
00226         uint8_t r = 0, g = 0, b = 0;
00227 
00228         for( size_t i =0; i<h; i++)
00229         {
00230             for( size_t j =0; j<w; j++)
00231             {
00232                 if(img.channels() == 3)
00233                 {
00234                     const cv::Vec3b& bgr = img.at<cv::Vec3b>((int)i,(int)j);
00235                     r = bgr[0];
00236                     g = bgr[1];
00237                     b = bgr[2];
00238 
00239                     idx = 3*(i * w + j);
00240                     
00241 
00242 
00243                 }
00244                 else if (img.channels() == 1)
00245                 {
00246                     idx = (i * w + j);
00247                     r = pimg[idx];
00248                     g = pimg[idx];
00249                     b = pimg[idx];
00250                 }
00251 
00252 
00253 
00254                 pcl::PointXYZRGB &color = cloud.points[idx];
00255                 
00256                 color.r = r;
00257                 color.g = g;
00258                 color.b = b;
00259 
00260 
00261 
00262                 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273             }
00274         }
00275         return cloud;
00276     }
00277 
00278     cv::Mat dtors;
00279 
00280     
00281     
00282     
00283     
00284     
00285 
00286     
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 };
00344 
00345 
00346 template <typename PointSource, typename PointTarget>
00347 class PoseEstimator
00348 {
00349 public:
00350     PoseEstimator(int NRansac,
00351                   double maxidx, double maxidd);
00352     size_t estimate(const NDTFrame<PointSource> &f0, const NDTFrame<PointTarget> &f1);
00353     size_t estimate(const NDTFrame<PointSource> &f0, const NDTFrame<PointTarget> &f1, const std::vector<cv::DMatch>& matches);
00354 
00355     const std::vector<cv::DMatch>& getInliers() const
00356     {
00357         return inliers;
00358     }
00359 
00360     void matchFrames(const NDTFrame<PointSource>& f0, const NDTFrame<PointTarget>& f2, std::vector<cv::DMatch>& fwd_matches);
00361 
00362     inline Eigen::Affine3f getTransform()
00363     {
00364         Eigen::Affine3f transl_transform = (Eigen::Affine3f)Eigen::Translation3f(trans[0], trans[1], trans[2]);
00365         Eigen::Affine3f rot_transform = (Eigen::Affine3f)Eigen::Matrix3f(rot.cast<float>());
00366         return transl_transform*rot_transform;
00367     }
00368 
00369     
00370     std::vector<cv::DMatch> matches; 
00371     std::vector<cv::DMatch> inliers; 
00372 
00373     int numRansac;
00374 
00376     bool windowed;
00377 
00379     double maxInlierXDist2, maxInlierDDist2;
00380 
00381     double maxDist;
00382     double minDist;
00383 
00385     cv::Ptr<cv::DescriptorMatcher> matcher;
00386     int wx , wy ;
00387 
00388     
00389     Eigen::Matrix3d rot; 
00390     Eigen::Quaterniond quat;
00391     Eigen::Vector3d trans; 
00392 
00393     bool projectMatches;
00394 };
00395 
00396 
00397 } 
00398 
00399 #include <ndt_feature_reg/impl/ndt_frame.hpp>
00400 
00401 #endif