NASA Astrobee Robot Software  0.19.1
Flight software for the Astrobee robots operating inside the International Space Station.
sparse_map.h
Go to the documentation of this file.
1 /* Copyright (c) 2017, United States Government, as represented by the
2  * Administrator of the National Aeronautics and Space Administration.
3  *
4  * All rights reserved.
5  *
6  * The Astrobee platform is licensed under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations
16  * under the License.
17  */
18 
19 #ifndef SPARSE_MAPPING_SPARSE_MAP_H_
20 #define SPARSE_MAPPING_SPARSE_MAP_H_
21 
27 #include <camera/camera_model.h>
28 #include <camera/camera_params.h>
29 
30 #include <boost/optional.hpp>
31 #include <Eigen/Geometry>
32 #include <opencv2/core/core.hpp>
33 #include <opencv2/imgproc.hpp>
34 
35 #include <map>
36 #include <mutex>
37 #include <numeric>
38 #include <set>
39 #include <string>
40 #include <vector>
41 #include <utility>
42 #include <limits>
43 
44 namespace cv {
45  class Mat;
46  class DMatch;
47 }
48 
49 namespace sparse_mapping {
50 
51 // Non-member function InitializeCidFidToPid() that we will use within
52 // this class and outside of it as well.
53 void InitializeCidFidToPid(int num_cid,
54  std::vector<std::map<int, int> > const& pid_to_cid_fid,
55  std::vector<std::map<int, int> > * cid_fid_to_pid);
56 
63 struct SparseMap {
64  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
65 
72  SparseMap(const std::vector<std::string> & filenames,
73  const std::string & detector,
74  const camera::CameraParameters & params);
75 
80  SparseMap(const std::string & protobuf_file,
81  bool localization = false);
82 
86  SparseMap(const std::vector<Eigen::Affine3d>& cid_to_cam_t,
87  const std::vector<std::string> & filenames,
88  const std::string & detector,
89  const camera::CameraParameters & params);
90 
91 
92  SparseMap(bool bundler_format, std::string const& filename, std::vector<std::string> const& files);
93 
94  // Set default loc params using FLAG values
95  void SetDefaultLocParams();
96 
97  // Set loc params
99  const LocalizationParameters& loc_params() const { return loc_params_; }
101 
102  void SetDetectorParams(int min_features, int max_features, int retries, double min_thresh, double default_thresh,
103  double max_thresh, double too_many_ratio, double too_few_ratio);
104 
108  void DetectFeatures();
109 
113  void Save(const std::string & protobuf_file) const;
114 
118  bool Localize(std::string const& img_file, camera::CameraModel* pose,
119  std::vector<Eigen::Vector3d>* inlier_landmarks = NULL,
120  std::vector<Eigen::Vector2d>* inlier_observations = NULL,
121  std::vector<int> * cid_list = NULL);
122  bool Localize(const cv::Mat & image,
123  camera::CameraModel* pose, std::vector<Eigen::Vector3d>* inlier_landmarks = NULL,
124  std::vector<Eigen::Vector2d>* inlier_observations = NULL,
125  std::vector<int> * cid_list = NULL);
126  bool Localize(cv::Mat const& test_descriptors, Eigen::Matrix2Xd const& test_keypoints, camera::CameraModel* pose,
127  std::vector<Eigen::Vector3d>* inlier_landmarks, std::vector<Eigen::Vector2d>* inlier_observations,
128  std::vector<int>* cid_list = NULL, const cv::Mat& image = cv::Mat());
129 
130  // access map frames
134  size_t GetNumFrames(void) const {return cid_to_filename_.size();}
138  const std::string & GetFrameFilename(int frame) const {return cid_to_filename_[frame];}
142  const Eigen::Affine3d & GetFrameGlobalTransform(int frame) const
143  {return cid_to_cam_t_global_[frame];}
144 
145  void SetFrameGlobalTransform(int frame, const Eigen::Affine3d & transform) {
146  cid_to_cam_t_global_[frame] = transform;
147  }
151  const Eigen::Matrix2Xd & GetFrameKeypoints(int frame) const {return cid_to_keypoint_map_[frame];}
155  cv::Mat GetDescriptor(int frame, int fid) const { return cid_to_descriptor_map_[frame].row(fid);}
159  const std::map<int, int> & GetFrameFidToPidMap(int frame) const {return cid_fid_to_pid_[frame];}
160 
161  // access map landmarks
165  size_t GetNumLandmarks(void) const {return pid_to_xyz_.size();}
169  Eigen::Vector3d GetLandmarkPosition(int landmark) const {return pid_to_xyz_[landmark];}
174  const std::map<int, int> & GetLandmarkCidToFidMap(int landmark) const {return pid_to_cid_fid_[landmark];}
175 
176  // access and modify parameters
181  void SetCameraParameters(camera::CameraParameters camera_params) {camera_params_ = camera_params;}
185  size_t GetNumObservations(void) const {return std::accumulate(pid_to_cid_fid_.begin(),
186  pid_to_cid_fid_.end(),
187  0, [](size_t v, std::map<int, int> const& map)
188  { return v + map.size(); }); }
193 
199  }
200 
201  // Load map. If localization is true, load only the parts of the map
202  // needed for localization.
203  void Load(const std::string & protobuf_file, bool localization = false);
204 
205  // Optionally load keypoints. Call this after loading the map, if for example
206  // the user needs to use the keypoints for visualization or essential matrix
207  // estimation and those params differ from the default FLAG values.
208  void LoadKeypoints(const std::string & protobuf_file);
209 
210  // construct from pid_to_cid_fid
211  void InitializeCidFidToPid();
212 
213  // detect features with opencv
214  void DetectFeaturesFromFile(std::string const& filename,
215  bool multithreaded,
216  cv::Mat* descriptors,
217  Eigen::Matrix2Xd* keypoints);
218  void DetectFeatures(cv::Mat const& image,
219  bool multithreaded,
220  cv::Mat* descriptors,
221  Eigen::Matrix2Xd* keypoints);
222  // delete feature descriptors with no matching landmark
223  void PruneMap(void);
224 
225  std::string GetDetectorName() { return detector_.GetDetectorName(); }
228 
229  // stored in map file
230  std::vector<std::string> cid_to_filename_;
231  // TODO(bcoltin) replace Eigen2Xd everywhere with one keypoint class
232  std::vector<Eigen::Matrix2Xd > cid_to_keypoint_map_;
233  std::vector<std::map<int, int> > pid_to_cid_fid_;
234  std::vector<Eigen::Vector3d> pid_to_xyz_;
235  std::vector<Eigen::Affine3d > cid_to_cam_t_global_;
236  std::vector<cv::Mat> cid_to_descriptor_map_;
237  // generated on load
238  std::vector<std::map<int, int> > cid_fid_to_pid_;
239  std::vector<std::map<int, int>> cid_to_matching_cid_counts_;
240 
243  mutable sparse_mapping::VocabDB vocab_db_; // TODO(oalexan1): Mutable means someone is doing something wrong.
245  std::string protobuf_file_;
246 
247  // e.g, 10th db image is 3rd image in cid_to_filename_
248  std::map<int, int> db_to_cid_map_;
249 
250  // If datastructure is available, match only pairs of cids
251  // that are present in it (this info can come from example from
252  // a map that was built previously with the same images but
253  // a different descriptor.
254  std::map< int, std::set<int> > cid_to_cid_; // TODO(oalexan1): Need not be a member
255 
256  // These are used to register the map to real world coordinates
257  // with information provided by the user.
258  // TODO(oalexan1): These need not be members
260  std::vector<Eigen::Matrix2Xd> user_cid_to_keypoint_map_;
261  std::vector<std::map<int, int> > user_pid_to_cid_fid_;
262  std::vector<Eigen::Vector3d> user_pid_to_xyz_;
263 
264  cv::Ptr<cv::CLAHE> clahe_;
265  boost::optional<int> best_previous_cid_;
266  std::mutex mutex_detector_;
267 
268  private:
269  // Create an empty map. It is strongly recommended to not use this function,
270  // as it requires carefully initializing many members. Hence this is made
271  // private. Consider using the other constructors.
272  SparseMap();
273 
274  // I found out the hard way that sparse maps cannot be copied
275  // correctly, hence prohibit this. The only good way seems to be to
276  // load a copy from disk. (oalexan1)
277  SparseMap(SparseMap &);
278  SparseMap& operator=(const SparseMap&);
279 
280  // Reorder the images in the map and the rest of the data accordingly
281  void reorderMap(std::map<int, int> const& old_cid_to_new_cid);
282 };
283 } // namespace sparse_mapping
284 
285 #endif // SPARSE_MAPPING_SPARSE_MAP_H_
sparse_mapping::SparseMap::GetFrameFidToPidMap
const std::map< int, int > & GetFrameFidToPidMap(int frame) const
Definition: sparse_map.h:159
sparse_mapping::SparseMap::cid_fid_to_pid_
std::vector< std::map< int, int > > cid_fid_to_pid_
Definition: sparse_map.h:238
sparse_mapping::SparseMap::cid_to_keypoint_map_
std::vector< Eigen::Matrix2Xd > cid_to_keypoint_map_
Definition: sparse_map.h:232
sparse_mapping::SparseMap::GetFrameGlobalTransform
const Eigen::Affine3d & GetFrameGlobalTransform(int frame) const
Definition: sparse_map.h:142
sparse_mapping::InitializeCidFidToPid
void InitializeCidFidToPid(int num_cid, std::vector< std::map< int, int > > const &pid_to_cid_fid, std::vector< std::map< int, int > > *cid_fid_to_pid)
Definition: sparse_map.cc:645
sparse_mapping::SparseMap::db_to_cid_map_
std::map< int, int > db_to_cid_map_
Definition: sparse_map.h:248
sparse_mapping::SparseMap::SetDetectorParams
void SetDetectorParams(int min_features, int max_features, int retries, double min_thresh, double default_thresh, double max_thresh, double too_many_ratio, double too_few_ratio)
Definition: sparse_map.cc:509
sparse_mapping::SparseMap::LoadKeypoints
void LoadKeypoints(const std::string &protobuf_file)
Definition: sparse_map.cc:474
sparse_mapping::SparseMap::PruneMap
void PruneMap(void)
Definition: sparse_map.cc:956
sparse_mapping::SparseMap::cid_to_cam_t_global_
std::vector< Eigen::Affine3d > cid_to_cam_t_global_
Definition: sparse_map.h:235
sparse_mapping::SparseMap::GetFrameKeypoints
const Eigen::Matrix2Xd & GetFrameKeypoints(int frame) const
Definition: sparse_map.h:151
sparse_mapping::SparseMap::DetectFeatures
void DetectFeatures()
Definition: sparse_map.cc:272
sparse_mapping
Definition: localization_parameters.h:22
interest_point::FeatureDetector
Definition: matching.h:58
sparse_mapping::SparseMap::cid_to_filename_
std::vector< std::string > cid_to_filename_
Definition: sparse_map.h:230
sparse_mapping::SparseMap::loc_params
const LocalizationParameters & loc_params() const
Definition: sparse_map.h:99
camera::CameraParameters
Definition: camera_params.h:58
sparse_mapping::SparseMap::Save
void Save(const std::string &protobuf_file) const
Definition: sparse_map.cc:518
sparse_mapping::SparseMap::loc_params
LocalizationParameters & loc_params()
Definition: sparse_map.h:100
sparse_mapping::SparseMap::SetDefaultLocParams
void SetDefaultLocParams()
Definition: sparse_map.cc:241
sparse_mapping::SparseMap::detector_
interest_point::FeatureDetector detector_
Definition: sparse_map.h:241
sparse_mapping::SparseMap::SetFrameGlobalTransform
void SetFrameGlobalTransform(int frame, const Eigen::Affine3d &transform)
Definition: sparse_map.h:145
sparse_mapping::SparseMap::world_transform_
Eigen::Affine3d world_transform_
Definition: sparse_map.h:259
sparse_mapping::SparseMap::cid_to_descriptor_map_
std::vector< cv::Mat > cid_to_descriptor_map_
Definition: sparse_map.h:236
sparse_mapping::SparseMap::GetDescriptor
cv::Mat GetDescriptor(int frame, int fid) const
Definition: sparse_map.h:155
camera::CameraModel
Definition: camera_model.h:31
sparse_mapping::SparseMap::best_previous_cid_
boost::optional< int > best_previous_cid_
Definition: sparse_map.h:265
sparse_mapping::SparseMap::GetLandmarkCidToFidMap
const std::map< int, int > & GetLandmarkCidToFidMap(int landmark) const
Definition: sparse_map.h:174
matching.h
sparse_mapping::SparseMap::vocab_db_
sparse_mapping::VocabDB vocab_db_
Definition: sparse_map.h:243
sparse_mapping::SparseMap::camera_params_
camera::CameraParameters camera_params_
Definition: sparse_map.h:242
sparse_mapping::SparseMap::protobuf_file_
std::string protobuf_file_
Definition: sparse_map.h:245
sparse_mapping::SparseMap::loc_params_
LocalizationParameters loc_params_
Definition: sparse_map.h:244
vocab_tree.h
sparse_mapping::SparseMap::Localize
bool Localize(std::string const &img_file, camera::CameraModel *pose, std::vector< Eigen::Vector3d > *inlier_landmarks=NULL, std::vector< Eigen::Vector2d > *inlier_observations=NULL, std::vector< int > *cid_list=NULL)
Definition: sparse_map.cc:940
sparse_mapping::SparseMap::SetLocParams
void SetLocParams(const LocalizationParameters &loc_params)
Definition: sparse_map.cc:263
sparse_mapping::SparseMap::user_pid_to_cid_fid_
std::vector< std::map< int, int > > user_pid_to_cid_fid_
Definition: sparse_map.h:261
sparse_mapping::LocalizationParameters::histogram_equalization
int histogram_equalization
Definition: localization_parameters.h:29
point_cloud_common::Vector3d
Eigen::Vector3d Vector3d(const PointType &point)
Definition: utilities.h:328
sparse_mapping::SparseMap::GetDetectorName
std::string GetDetectorName()
Definition: sparse_map.h:225
sparse_mapping::SparseMap::Load
void Load(const std::string &protobuf_file, bool localization=false)
Definition: sparse_map.cc:305
sparse_mapping::SparseMap::detector
interest_point::FeatureDetector & detector()
Definition: sparse_map.h:226
sparse_mapping::SparseMap::GetWorldTransform
Eigen::Affine3d GetWorldTransform() const
Definition: sparse_map.h:192
sparse_mapping::SparseMap::GetCameraParameters
camera::CameraParameters GetCameraParameters(void) const
Definition: sparse_map.h:180
sparse_mapping::SparseMap::pid_to_cid_fid_
std::vector< std::map< int, int > > pid_to_cid_fid_
Definition: sparse_map.h:233
sparse_mapping::SparseMap::user_pid_to_xyz_
std::vector< Eigen::Vector3d > user_pid_to_xyz_
Definition: sparse_map.h:262
camera_model.h
sparse_mapping::SparseMap::SetCameraParameters
void SetCameraParameters(camera::CameraParameters camera_params)
Definition: sparse_map.h:181
sparse_mapping::VocabDB
Definition: vocab_tree.h:74
sparse_mapping::SparseMap::GetNumLandmarks
size_t GetNumLandmarks(void) const
Definition: sparse_map.h:165
sparse_mapping::SparseMap::GetLandmarkPosition
Eigen::Vector3d GetLandmarkPosition(int landmark) const
Definition: sparse_map.h:169
sparse_mapping::LocalizationParameters
Definition: localization_parameters.h:23
eigen_vectors.h
localization_parameters.h
sparse_mapping::SparseMap::InitializeCidFidToPid
void InitializeCidFidToPid()
Definition: sparse_map.cc:658
sparse_mapping::SparseMap::GetFrameFilename
const std::string & GetFrameFilename(int frame) const
Definition: sparse_map.h:138
sparse_mapping::SparseMap::cid_to_cid_
std::map< int, std::set< int > > cid_to_cid_
Definition: sparse_map.h:254
sparse_mapping::SparseMap::pid_to_xyz_
std::vector< Eigen::Vector3d > pid_to_xyz_
Definition: sparse_map.h:234
sparse_mapping::SparseMap::GetNumObservations
size_t GetNumObservations(void) const
Definition: sparse_map.h:185
sparse_mapping::SparseMap::GetNumFrames
size_t GetNumFrames(void) const
Definition: sparse_map.h:134
sparse_mapping.h
optimization_common::Affine3d
Eigen::Affine3d Affine3d(const Eigen::Matrix< double, 7, 1 > &affine_vector)
Definition: utilities.cc:43
sparse_mapping::TransformCamerasAndPoints
void TransformCamerasAndPoints(Eigen::Affine3d const &A, std::vector< Eigen::Affine3d > *cid_to_cam_t, std::vector< Eigen::Vector3d > *xyz)
Definition: sparse_mapping.cc:992
sparse_mapping::SparseMap::DetectFeaturesFromFile
void DetectFeaturesFromFile(std::string const &filename, bool multithreaded, cv::Mat *descriptors, Eigen::Matrix2Xd *keypoints)
Definition: sparse_map.cc:664
sparse_mapping::SparseMap::mutex_detector_
std::mutex mutex_detector_
Definition: sparse_map.h:266
sparse_mapping::SparseMap::clahe_
cv::Ptr< cv::CLAHE > clahe_
Definition: sparse_map.h:264
sparse_mapping::SparseMap::cid_to_matching_cid_counts_
std::vector< std::map< int, int > > cid_to_matching_cid_counts_
Definition: sparse_map.h:239
sparse_mapping::SparseMap::GetHistogramEqualization
int GetHistogramEqualization()
Definition: sparse_map.h:227
cv
Definition: camera_params.h:31
interest_point::FeatureDetector::GetDetectorName
std::string GetDetectorName() const
Definition: matching.h:81
sparse_mapping::SparseMap
Definition: sparse_map.h:63
camera_params.h
sparse_mapping::SparseMap::user_cid_to_keypoint_map_
std::vector< Eigen::Matrix2Xd > user_cid_to_keypoint_map_
Definition: sparse_map.h:260
sparse_mapping::SparseMap::ApplyTransform
void ApplyTransform(Eigen::Affine3d const &T)
Definition: sparse_map.h:197