keyframe.cpp
Go to the documentation of this file.
00001 /*
00002  *  This file is part of ucl_drone 2016.
00003  *  For more information, please refer
00004  *  to the corresponding header file.
00005  *
00006  *  \author Arnaud Jacques & Alexandre Leclere
00007  *  \date 2016
00008  *
00009  */
00010 
00011 #include <ucl_drone/map/map_keyframe_based.h>
00012 
00013 std::vector< KeyFrame* > KeyFrame::instances_list;
00014 
00015 KeyFrame::KeyFrame() : cloud(new pcl::PointCloud< pcl::PointXYZRGBSIFT >())
00016 {
00017 }
00018 
00019 KeyFrame::KeyFrame(ucl_drone::Pose3D& pose) : cloud(new pcl::PointCloud< pcl::PointXYZRGBSIFT >())
00020 {
00021   // add the current keyframe to the list of all existing keyframes
00022   this->instances_list.push_back(this);
00023   // fill the identification number
00024   this->ID = instances_list.size() - 1;
00025   // fill the pose
00026   this->pose = pose;
00027 }
00028 
00029 KeyFrame::~KeyFrame()
00030 {
00031 }
00032 
00033 void KeyFrame::resetList()
00034 {
00035   for (int i = 0; i < KeyFrame::instances_list.size(); i++)
00036   {
00037     delete KeyFrame::instances_list[i];  // this line calls keyframe destructor
00038   }
00039   KeyFrame::instances_list.clear();
00040 }
00041 
00042 void KeyFrame::addPoints(pcl::PointCloud< pcl::PointXYZRGBSIFT >::Ptr& pointcloud,
00043                          std::vector< int >& new_points)
00044 {
00045   *(this->cloud) += *pointcloud;
00046   this->points.insert(this->points.end(), new_points.begin(), new_points.end());
00047   this->convertDescriptors();
00048 }
00049 
00050 void KeyFrame::addPoints(pcl::PointCloud< pcl::PointXYZRGBSIFT >::Ptr& pointcloud)
00051 {
00052   *(this->cloud) += *pointcloud;
00053   this->convertDescriptors();
00054 }
00055 
00056 KeyFrame* KeyFrame::getKeyFrame(const int i)
00057 {
00058   if (i < 0 || i >= instances_list.size())
00059   {
00060     ROS_ERROR("You try to access a keyframe with invalid ID");
00061   }
00062   // ROS_DEBUG("getKeyFrame %d", i);
00063   return instances_list[i];
00064 }
00065 
00066 int KeyFrame::getID()
00067 {
00068   return this->ID;
00069 }
00070 
00071 int KeyFrame::size()
00072 {
00073   return this->cloud->size();
00074 }
00075 
00076 ucl_drone::Pose3D KeyFrame::getPose()
00077 {
00078   return this->pose;
00079 }
00080 
00081 void KeyFrame::getDescriptors(cv::Mat& descriptors)
00082 {
00083   if (this->descriptors.rows == 0)
00084   {
00085     this->convertDescriptors();
00086   }
00087   descriptors = this->descriptors;
00088 }
00089 
00090 void KeyFrame::convertDescriptors()
00091 {
00092   this->descriptors = cv::Mat_< float >(this->cloud->points.size(), DESCRIPTOR_SIZE);
00093   for (unsigned i = 0; i < this->cloud->points.size(); ++i)
00094   {
00095     for (unsigned j = 0; j < DESCRIPTOR_SIZE; ++j)
00096     {
00097       this->descriptors.at< float >(i, j) = cloud->points[i].descriptor[j];
00098     }
00099   }
00100 }
00101 
00102 void KeyFrame::matchWithFrame(Frame& frame, std::vector< std::vector< int > >& idx_matching_points,
00103                               std::vector< cv::Point3f >& keyframe_matching_points,
00104                               std::vector< cv::Point2f >& frame_matching_points)
00105 {
00106   bool use_ratio_test = false;  // if true, the second best match is also computed and the ratio
00107   // between the descriptors distance of the firt best match and the second best match must be less
00108   // than a defined treshold, otherwise the best match is discarded
00109   // but in pracice it doesn't work so well
00110 
00111   if (frame.descriptors.rows == 0)
00112   {
00113     // ROS_DEBUG("KeyFrame::matchWithFrame frame.descriptors.rows == 0");
00114     return;
00115   }
00116 
00117   if (this->descriptors.rows == 0)
00118   {
00119     // ROS_DEBUG("KeyFrame::matchWithFrame this->descriptors.rows == 0");
00120     return;
00121   }
00122   else
00123   {
00124     if (use_ratio_test)
00125     {
00126       std::vector< std::vector< cv::DMatch > > knn_matches;
00127       matcher.knnMatch(frame.descriptors, this->descriptors, knn_matches, 2);
00128 
00129       // ratio_test + threshold test
00130       for (unsigned k = 0; k < knn_matches.size(); k++)
00131       {
00132         if (knn_matches[k][0].distance / knn_matches[k][1].distance < 0.9)
00133         {
00134           if (knn_matches[k][0].distance < DIST_THRESHOLD)
00135           {
00136             std::vector< int > v(2);
00137             v[0] = knn_matches[k][0].trainIdx;
00138             v[1] = knn_matches[k][0].queryIdx;
00139             idx_matching_points.push_back(v);
00140 
00141             cv::Point3f keyframe_point;
00142             pcl::PointXYZRGBSIFT pcl_point = this->cloud->points[knn_matches[k][0].trainIdx];
00143             keyframe_point.x = pcl_point.x;
00144             keyframe_point.y = pcl_point.y;
00145             keyframe_point.z = pcl_point.z;
00146             keyframe_matching_points.push_back(keyframe_point);
00147             frame_matching_points.push_back(frame.imgPoints[knn_matches[k][0].queryIdx]);
00148           }
00149         }
00150       }
00151     }
00152     else
00153     {
00154       std::vector< cv::DMatch > simple_matches;
00155       matcher.match(frame.descriptors, this->descriptors, simple_matches);
00156 
00157       // threshold test
00158       for (unsigned k = 0; k < simple_matches.size(); k++)
00159       {
00160         if (simple_matches[k].distance < DIST_THRESHOLD)
00161         {
00162           std::vector< int > v(2);
00163           v[0] = simple_matches[k].trainIdx;
00164           v[1] = simple_matches[k].queryIdx;
00165           idx_matching_points.push_back(v);
00166 
00167           cv::Point3f keyframe_point;
00168           pcl::PointXYZRGBSIFT pcl_point = this->cloud->points[simple_matches[k].trainIdx];
00169           keyframe_point.x = pcl_point.x;
00170           keyframe_point.y = pcl_point.y;
00171           keyframe_point.z = pcl_point.z;
00172           keyframe_matching_points.push_back(keyframe_point);
00173           frame_matching_points.push_back(frame.imgPoints[simple_matches[k].queryIdx]);
00174         }
00175       }
00176     }
00177   }
00178 }


ucl_drone
Author(s): dronesinma
autogenerated on Sat Jun 8 2019 20:51:53