00001 /* 00002 * This file is part of ucl_drone 2016. 00003 * For more information, 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 Frame::Frame() 00014 { 00015 } 00016 00017 Frame::Frame(ucl_drone::ProcessedImageMsg::ConstPtr msg) 00018 { 00019 this->msg = *msg; 00020 00021 // convert msg to opencv format 00022 this->imgPoints.resize(msg->keypoints.size()); 00023 this->descriptors = cv::Mat_< float >(msg->keypoints.size(), DESCRIPTOR_SIZE); 00024 00025 for (unsigned i = 0; i < msg->keypoints.size(); ++i) 00026 { 00027 this->imgPoints[i].x = (double)msg->keypoints[i].point.x; 00028 this->imgPoints[i].y = (double)msg->keypoints[i].point.y; 00029 00030 // ROS_DEBUG("POINT[%d] (%f;%f) vs (%f;%f)", i, this->imgPoints[i].x, this->imgPoints[i].y, 00031 // msg->keypoints[i].point.x, msg->keypoints[i].point.y); 00032 00033 for (unsigned j = 0; j < DESCRIPTOR_SIZE; ++j) 00034 { 00035 this->descriptors.at< float >(i, j) = (float)msg->keypoints[i].descriptor[j]; 00036 } 00037 } 00038 } 00039 00040 Frame::~Frame() 00041 { 00042 } 00043 00044 // OLD CODE, NOW IN KEYFRAME 00045 // //! \param[in] map Map to compare 00046 // //! \param[out] idx_matching_points vector of pairs of indexes: (i,j) with i the index in the 00047 // map, j 00048 // //! the index in the frame 00049 // //! \param[out] idx_unknown_points vector of indexes in the frame 00050 // //! \param[out] map_matching_points 00051 // //! \param[out] frame_matching_points 00052 // //! \param[out] frame_unknown_points 00053 // void Frame::matchWithMap(Map& map, std::vector< std::pair< int, int > >& idx_matching_points, 00054 // std::vector< int >& idx_unknown_points, 00055 // std::vector< cv::Point3f >& map_matching_points, 00056 // std::vector< cv::Point2f >& frame_matching_points, 00057 // std::vector< cv::Point2f >& frame_unknown_points) 00058 // { 00059 // bool use_ratio_test = false; 00060 // 00061 // std::vector< int > idx; 00062 // if (this->descriptors.rows == 0) 00063 // { 00064 // return; 00065 // } 00066 // 00067 // cv::Mat map_descriptors; 00068 // std::vector< int > map_idx; 00069 // map.getDescriptors(this->msg.pose, map_descriptors, map_idx); 00070 // if (map_descriptors.rows == 0) 00071 // { 00072 // idx_unknown_points.resize(this->imgPoints.size()); 00073 // frame_unknown_points.resize(this->imgPoints.size()); 00074 // for (unsigned k = 0; k < this->imgPoints.size(); k++) 00075 // { 00076 // idx_unknown_points[k] = k; 00077 // frame_unknown_points[k] = this->imgPoints[k]; 00078 // } 00079 // return; 00080 // } 00081 // else 00082 // { 00083 // cv::FlannBasedMatcher matcher; 00084 // if (use_ratio_test) 00085 // { 00086 // std::vector< std::vector< cv::DMatch > > knn_matches; 00087 // matcher.knnMatch(this->descriptors, map_descriptors, knn_matches, 2); 00088 // 00089 // // ratio_test + threshold test 00090 // for (unsigned k = 0; k < knn_matches.size(); k++) 00091 // { 00092 // if (knn_matches[k][0].distance / knn_matches[k][1].distance < 0.9) 00093 // { 00094 // if (knn_matches[k][0].distance < DIST_THRESHOLD) 00095 // { 00096 // std::pair< int, int > p(map_idx[knn_matches[k][0].trainIdx], 00097 // knn_matches[k][0].queryIdx); 00098 // idx_matching_points.push_back(p); 00099 // 00100 // cv::Point3f map_point; 00101 // pcl::PointXYZRGBSIFT pcl_point = 00102 // map.cloud->points[map_idx[knn_matches[k][0].trainIdx]]; 00103 // map_point.x = pcl_point.x; 00104 // map_point.y = pcl_point.y; 00105 // map_point.z = pcl_point.z; 00106 // map_matching_points.push_back(map_point); 00107 // frame_matching_points.push_back(this->imgPoints[knn_matches[k][0].queryIdx]); 00108 // } 00109 // else 00110 // { 00111 // idx_unknown_points.push_back(knn_matches[k][0].queryIdx); 00112 // frame_unknown_points.push_back(this->imgPoints[knn_matches[k][0].queryIdx]); 00113 // } 00114 // } 00115 // } 00116 // } 00117 // else 00118 // { 00119 // std::vector< cv::DMatch > simple_matches; 00120 // matcher.match(this->descriptors, map_descriptors, simple_matches); 00121 // 00122 // // threshold test 00123 // for (unsigned k = 0; k < simple_matches.size(); k++) 00124 // { 00125 // if (simple_matches[k].distance < DIST_THRESHOLD) 00126 // { 00127 // std::pair< int, int > p(map_idx[simple_matches[k].trainIdx], 00128 // simple_matches[k].queryIdx); 00129 // idx_matching_points.push_back(p); 00130 // 00131 // cv::Point3f map_point; 00132 // pcl::PointXYZRGBSIFT pcl_point = 00133 // map.cloud->points[map_idx[simple_matches[k].trainIdx]]; 00134 // map_point.x = pcl_point.x; 00135 // map_point.y = pcl_point.y; 00136 // map_point.z = pcl_point.z; 00137 // map_matching_points.push_back(map_point); 00138 // frame_matching_points.push_back(this->imgPoints[simple_matches[k].queryIdx]); 00139 // } 00140 // else 00141 // { 00142 // idx_unknown_points.push_back(simple_matches[k].queryIdx); 00143 // frame_unknown_points.push_back(this->imgPoints[simple_matches[k].queryIdx]); 00144 // } 00145 // } 00146 // } 00147 // } 00148 // } 00149 00150 // \param[in] idx_points index of points in this->imgPoints to convert 00151 // \param[out] pointcloud points converted to PointXYZRGBSIFT 00152 void Frame::convertToPcl(std::vector< int >& idx_points, std::vector< cv::Point3f > points_out, 00153 int keyframe_ID, pcl::PointCloud< pcl::PointXYZRGBSIFT >::Ptr& pointcloud) 00154 { 00155 pointcloud->points.resize(idx_points.size()); // prepares output structure 00156 // for each points selected by idx_points 00157 for (unsigned i = 0; i < idx_points.size(); i++) 00158 { 00159 int j = idx_points[i]; 00160 00161 pcl::PointXYZRGBSIFT point; // initialize a new PCL point 00162 00163 // Fill coordinates 00164 point.x = points_out[i].x; 00165 point.y = points_out[i].y; 00166 point.z = points_out[i].z; 00167 00168 // Other fields 00169 point.view_count = 1; 00170 point.keyframe_ID = keyframe_ID; 00171 00172 int rgb_ = 255 << 16 | 0 << 8 | 0; // red by default 00173 point.rgb = *reinterpret_cast< float* >(&rgb_); 00174 00175 // Fill the corresponding description 00176 for (int k = 0; k < DESCRIPTOR_SIZE; k++) 00177 { 00178 point.descriptor[k] = this->descriptors.at< float >(j, k); 00179 } 00180 00181 // add the PCL point to the output 00182 pointcloud->points[i] = point; 00183 } 00184 } 00185 00186 void Frame::convertToPcl(std::vector< cv::Point3f > points_out, int keyframe_id, 00187 pcl::PointCloud< pcl::PointXYZRGBSIFT >::Ptr& pointcloud) 00188 { 00189 // call the other definition of Frame::convertToPcl 00190 std::vector< int > idx_points; 00191 idx_points.resize(this->imgPoints.size()); 00192 for (unsigned k = 0; k < this->imgPoints.size(); k++) 00193 { 00194 idx_points[k] = k; 00195 } 00196 convertToPcl(idx_points, points_out, keyframe_id, pointcloud); 00197 }