NASA Astrobee Robot Software  0.19.1
Flight software for the Astrobee robots operating inside the International Space Station.
sparse_mapping.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_MAPPING_H_
20 #define SPARSE_MAPPING_SPARSE_MAPPING_H_
21 
22 #include <camera/camera_params.h>
24 
25 #include <Eigen/Geometry>
26 
27 #include <vector>
28 #include <map>
29 #include <string>
30 
31 // Forward declare opencv keypoint
32 namespace cv {
33 class KeyPoint;
34 class Mat;
35 class DMatch;
36 }
37 
38 namespace common {
39  class CameraParameters;
40 }
41 
42 namespace google {
43  namespace protobuf {
44  class MessageLite;
45  namespace io {
46  class ZeroCopyInputStream;
47  class ZeroCopyOutputStream;
48  }
49  }
50 }
51 
52 namespace sparse_mapping {
53 
54 
55  // Terminology used in this code:
56 
57  // CID = Camera ID. A unique ID for each camera
58  // PID = Point ID. A unique ID for each point. Can be observed by
59  // multiple cameras.
60  // FID = Feature ID. A unique ID for each pixel viewing of a
61  // PID. FID only make sense in the context of a CID. FID
62  // values are reused for each image.
63 
64  // cid_to_keypoint_map - Indexed first on CID and then on FID.
65  // cid_to_filename - Indexed on CID.
66  // pid_to_cid_fid - Index on PID. Then returns map index on CID that
67  // shows FID observing this PID.
68  // pid_to_xyz - Index on PID. Gives the XYZ position of each point.
69  // cid_to_camera_transform - Index on CID. Contains affine transform
70  // representing camera_t_global.
71 
73 
74 Eigen::Quaternion<double> slerp_n(std::vector<double> const& W, std::vector<Eigen::Quaternion<double> > const& Q);
75 
76 bool IsBinaryDescriptor(std::string const& descriptor);
77 
78 // Logic for implementing if two histogram equalization flags are compatible
79 bool HistogramEqualizationCheck(int histogram_equalization1, int histogram_equalization2, bool fatal_failure = true);
80 
81 // Writes the NVM control network format.
82 void WriteNVM(std::vector<Eigen::Matrix2Xd> const& cid_to_keypoint_map, std::vector<std::string> const& cid_to_filename,
83  std::vector<std::map<int, int> > const& pid_to_cid_fid, std::vector<Eigen::Vector3d> const& pid_to_xyz,
84  std::vector<Eigen::Affine3d> const& cid_to_cam_t_global, double focal_length,
85  std::string const& output_filename);
86 // Reads the NVM control network format.
87 void ReadNVM(std::string const& input_filename, std::vector<Eigen::Matrix2Xd>* cid_to_keypoint_map,
88  std::vector<std::string>* cid_to_filename, std::vector<std::map<int, int> >* pid_to_cid_fid,
89  std::vector<Eigen::Vector3d>* pid_to_xyz, std::vector<Eigen::Affine3d>* cid_to_cam_t_global);
90 
91 // Adds yaml.gz or .txt extension, depending on descriptor
92 std::string ImageToFeatureFile(std::string const& image_file, std::string const& detector_name);
93 
94 // The name of the file storing the list of images
95 std::string DBImagesFile(std::string const& db_name);
96 
97 // The name of the matches file
98 std::string MatchesFile(std::string const& map_file);
99 
100 // The name of the essential file
101 std::string EssentialFile(std::string const& map_file);
102 
103 // Write features yaml file
104 void WriteFeatures(std::string const& detector_name, std::vector<cv::KeyPoint> const& keypoints,
105  cv::Mat const& descriptors, std::string const& output_filename);
106 
107 // Read features yaml file
108 bool ReadFeatures(std::string const& input_filename, std::string const& detector_name,
109  std::vector<cv::KeyPoint>* keypoints, cv::Mat* descriptors);
110 
111 // Read SIFT features in Lowe's format
112 int ReadFeaturesSIFT(std::string const& filename, cv::Mat* descriptors, std::vector<cv::KeyPoint>* keypoints);
113 
114 // Triangulate metric camera point
115 // unnormalized point means that the point is:
116 // [px (image loc) - cx (optical center), py - cy, f (f length in px)]
117 Eigen::Vector3d TriangulatePoint(Eigen::Vector3d const& unnormalized_pt1, Eigen::Vector3d const& unnormalized_pt2,
118  Eigen::Matrix3d const& cam2_r_cam1, Eigen::Vector3d const& cam2_t_cam1, double* error);
119 
120 // Decompose Fundamental Matrix into Essential Matrix given known
121 // Intrinsics Matrix.
122 void DecomposeFMatIntoEMat(Eigen::Matrix3d const& fundamental, Eigen::Matrix3d const& intrinsics,
123  Eigen::Matrix3d* essential);
124 
125 // Decompose Essential Matrix into R and T
126 void DecomposeEMatIntoRT(Eigen::Matrix3d const& essential, Eigen::Matrix2Xd const& unnormalized_pts1,
127  Eigen::Matrix2Xd const& unnormalized_pts2, std::vector<cv::DMatch> const& matches,
128  double focal_length1, // Camera 1
129  double focal_length2, // Camera 2
130  Eigen::Matrix3d* cam2_r_cam1, Eigen::Vector3d* cam2_t_cam1);
131 
132 // Utility to return the type of entries in a given matrix
133 std::string CvMatTypeStr(cv::Mat const& Mat);
134 
135 void ListToListMap(std::vector<std::string> const& big_list, std::vector<std::string> const& small_list,
136  std::map<int, int>* map);
137 
138 void MergePids(int repeat_index, int num_unique, std::vector<std::map<int, int> >* pid_to_cid_fid);
139 
140 void PrintPidStats(std::vector<std::map<int, int> > const& pid_to_cid_fid);
141 
142 // Extract control points and the images they correspond to from
143 // a hugin project file
144 void ParseHuginControlPoints(std::string const& hugin_file, std::vector<std::string>* images, Eigen::MatrixXd* points);
145 
146 // Parse a file having on each line xyz coordinates
147 void ParseXYZ(std::string const& xyz_file, Eigen::MatrixXd* xyz);
148 
149 // Parse a CSV file, with the first line having column names. Return
150 // the results as columns in an std::map, with the column name being
151 // the key. We assume all values are numbers (non-numbers are set to
152 // 0).
153 void ParseCSV(std::string const& csv_file, std::map<std::string, std::vector<double> >* cols);
154 
155 // save size before protbuf, to save multiple protobufs in one file
156 bool WriteProtobufTo(const google::protobuf::MessageLite& message,
157  google::protobuf::io::ZeroCopyOutputStream* rawOutput);
158 
159 // save size before file, then write file into rawOutput
160 bool WriteFileTo(const char* filename, google::protobuf::io::ZeroCopyOutputStream* rawOutput);
161 
162 // read size before protbuf, to save multiple protobufs in one file
163 bool ReadProtobufFrom(google::protobuf::io::ZeroCopyInputStream* rawInput, google::protobuf::MessageLite* message);
164 
165 // read a size before protobuf, then read a file and write it to filename
166 bool ReadFileFrom(google::protobuf::io::ZeroCopyInputStream* rawInput, const char* filename);
167 
168 // Apply a given transform to the specified xyz points, and adjust
169 // accordingly the cameras for consistency.
170 void TransformCamerasAndPoints(Eigen::Affine3d const& A, std::vector<Eigen::Affine3d>* cid_to_cam_t,
171  std::vector<Eigen::Vector3d>* xyz);
172 
173 // Get the error threshold based on a multiple of a percentile
174 double GetErrThresh(const std::vector<double>& errors, double factor);
175 
176 // Find the maximum angle between n rays intersecting at given
177 // point. Must compute the camera centers in the global coordinate
178 // system before calling this function.
179 double ComputeRaysAngle(int pid, std::vector<std::map<int, int> > const& pid_to_cid_fid,
180  std::vector<Eigen::Vector3d> const& cam_ctrs, std::vector<Eigen::Vector3d> const& pid_to_xyz);
181 
182 // Filter points by reprojection error and other criteria
183 void FilterPID(double reproj_thresh, camera::CameraParameters const& camera_params,
184  std::vector<Eigen::Affine3d> const& cid_to_cam_t_global,
185  std::vector<Eigen::Matrix2Xd> const& cid_to_keypoint_map,
186  std::vector<std::map<int, int> >* pid_to_cid_fid, std::vector<Eigen::Vector3d>* pid_to_xyz,
187  bool print_stats = true, double multiple_of_median = 3.0);
188 
189 // Write the BAL format.
190 bool WriteBAL(const std::string& filename, camera::CameraParameters const& camera_params,
191  std::vector<std::map<int, int> > const& pid_to_cid_fid, std::vector<Eigen::Vector3d> const& pid_to_xyz,
192  std::vector<Eigen::Affine3d> const& cid_to_cam_t_global,
193  std::vector<Eigen::Matrix2Xd> const& cid_to_keypoint_map);
194 
195 // Given a data sequence having camera pose information for
196 // a set of timestamps, interpolate those poses at the timestamps
197 // given in out_time. We assume timestamps are always in increasing values.
198 void PoseInterpolation(std::vector<std::string> const& images, std::vector<double> const& out_time,
199  std::map<std::string, std::vector<double> > const& data,
200  std::vector<Eigen::Affine3d>* cid_to_cam_t, std::vector<std::string>* good_images);
201 
202 } // namespace sparse_mapping
203 
204 #endif // SPARSE_MAPPING_SPARSE_MAPPING_H_
sparse_mapping::TriangulatePoint
Eigen::Vector3d TriangulatePoint(Eigen::Vector3d const &unnormalized_pt1, Eigen::Vector3d const &unnormalized_pt2, Eigen::Matrix3d const &cam2_r_cam1, Eigen::Vector3d const &cam2_t_cam1, double *error)
Definition: sparse_mapping.cc:418
sparse_mapping::kUnknown
@ kUnknown
Definition: sparse_mapping.h:72
sparse_mapping::HistogramEqualizationType
HistogramEqualizationType
Definition: sparse_mapping.h:72
sparse_mapping::ComputeRaysAngle
double ComputeRaysAngle(int pid, std::vector< std::map< int, int > > const &pid_to_cid_fid, std::vector< Eigen::Vector3d > const &cam_ctrs, std::vector< Eigen::Vector3d > const &pid_to_xyz)
Definition: sparse_mapping.cc:1026
sparse_mapping
Definition: localization_parameters.h:22
sparse_mapping::CvMatTypeStr
std::string CvMatTypeStr(cv::Mat const &Mat)
Definition: sparse_mapping.cc:522
sparse_mapping::IsBinaryDescriptor
bool IsBinaryDescriptor(std::string const &descriptor)
Definition: sparse_mapping.cc:135
camera::CameraParameters
Definition: camera_params.h:58
sparse_mapping::WriteProtobufTo
bool WriteProtobufTo(const google::protobuf::MessageLite &message, google::protobuf::io::ZeroCopyOutputStream *rawOutput)
Definition: sparse_mapping.cc:873
sparse_mapping::MatchesFile
std::string MatchesFile(std::string const &map_file)
Definition: sparse_mapping.cc:296
sparse_mapping::WriteBAL
bool WriteBAL(const std::string &filename, camera::CameraParameters const &camera_params, std::vector< std::map< int, int > > const &pid_to_cid_fid, std::vector< Eigen::Vector3d > const &pid_to_xyz, std::vector< Eigen::Affine3d > const &cid_to_cam_t_global, std::vector< Eigen::Matrix2Xd > const &cid_to_keypoint_map)
Definition: sparse_mapping.cc:1169
sparse_mapping::ReadFileFrom
bool ReadFileFrom(google::protobuf::io::ZeroCopyInputStream *rawInput, const char *filename)
Definition: sparse_mapping.cc:951
sparse_mapping::ParseHuginControlPoints
void ParseHuginControlPoints(std::string const &hugin_file, std::vector< std::string > *images, Eigen::MatrixXd *points)
Definition: sparse_mapping.cc:709
sparse_mapping::GetErrThresh
double GetErrThresh(const std::vector< double > &errors, double factor)
Definition: sparse_mapping.cc:1010
sparse_mapping::PoseInterpolation
void PoseInterpolation(std::vector< std::string > const &images, std::vector< double > const &out_time, std::map< std::string, std::vector< double > > const &data, std::vector< Eigen::Affine3d > *cid_to_cam_t, std::vector< std::string > *good_images)
Definition: sparse_mapping.cc:1244
sparse_mapping::ReadProtobufFrom
bool ReadProtobufFrom(google::protobuf::io::ZeroCopyInputStream *rawInput, google::protobuf::MessageLite *message)
Definition: sparse_mapping.cc:929
sparse_mapping::ParseXYZ
void ParseXYZ(std::string const &xyz_file, Eigen::MatrixXd *xyz)
Definition: sparse_mapping.cc:780
sparse_mapping::FilterPID
void FilterPID(double reproj_thresh, camera::CameraParameters const &camera_params, std::vector< Eigen::Affine3d > const &cid_to_cam_t_global, std::vector< Eigen::Matrix2Xd > const &cid_to_keypoint_map, std::vector< std::map< int, int > > *pid_to_cid_fid, std::vector< Eigen::Vector3d > *pid_to_xyz, bool print_stats=true, double multiple_of_median=3.0)
Definition: sparse_mapping.cc:1056
sparse_mapping::kNone
@ kNone
Definition: sparse_mapping.h:72
point_cloud_common::Vector3d
Eigen::Vector3d Vector3d(const PointType &point)
Definition: utilities.h:328
sparse_mapping::HistogramEqualizationCheck
bool HistogramEqualizationCheck(int histogram_equalization1, int histogram_equalization2, bool fatal_failure=true)
Definition: sparse_mapping.cc:118
sparse_mapping::DecomposeFMatIntoEMat
void DecomposeFMatIntoEMat(Eigen::Matrix3d const &fundamental, Eigen::Matrix3d const &intrinsics, Eigen::Matrix3d *essential)
Definition: sparse_mapping.cc:442
sparse_mapping::WriteNVM
void WriteNVM(std::vector< Eigen::Matrix2Xd > const &cid_to_keypoint_map, std::vector< std::string > const &cid_to_filename, std::vector< std::map< int, int > > const &pid_to_cid_fid, std::vector< Eigen::Vector3d > const &pid_to_xyz, std::vector< Eigen::Affine3d > const &cid_to_cam_t_global, double focal_length, std::string const &output_filename)
sparse_mapping::ImageToFeatureFile
std::string ImageToFeatureFile(std::string const &image_file, std::string const &detector_name)
Definition: sparse_mapping.cc:287
sparse_mapping::EssentialFile
std::string EssentialFile(std::string const &map_file)
Definition: sparse_mapping.cc:300
sparse_mapping::MergePids
void MergePids(int repeat_index, int num_unique, std::vector< std::map< int, int > > *pid_to_cid_fid)
Definition: sparse_mapping.cc:566
sparse_mapping::ReadNVM
void ReadNVM(std::string const &input_filename, std::vector< Eigen::Matrix2Xd > *cid_to_keypoint_map, std::vector< std::string > *cid_to_filename, std::vector< std::map< int, int > > *pid_to_cid_fid, std::vector< Eigen::Vector3d > *pid_to_xyz, std::vector< Eigen::Affine3d > *cid_to_cam_t_global)
Definition: sparse_mapping.cc:204
sparse_mapping::PrintPidStats
void PrintPidStats(std::vector< std::map< int, int > > const &pid_to_cid_fid)
Definition: sparse_mapping.cc:691
eigen_vectors.h
error
uint8_t error
Definition: signal_lights.h:89
optimization_common::Affine3d
Eigen::Affine3d Affine3d(const Eigen::Matrix< double, 7, 1 > &affine_vector)
Definition: utilities.cc:43
sparse_mapping::DBImagesFile
std::string DBImagesFile(std::string const &db_name)
Definition: sparse_mapping.cc:292
sparse_mapping::ReadFeatures
bool ReadFeatures(std::string const &input_filename, std::string const &detector_name, std::vector< cv::KeyPoint > *keypoints, cv::Mat *descriptors)
Definition: sparse_mapping.cc:395
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::slerp_n
Eigen::Quaternion< double > slerp_n(std::vector< double > const &W, std::vector< Eigen::Quaternion< double > > const &Q)
Definition: sparse_mapping.cc:54
sparse_mapping::DecomposeEMatIntoRT
void DecomposeEMatIntoRT(Eigen::Matrix3d const &essential, Eigen::Matrix2Xd const &unnormalized_pts1, Eigen::Matrix2Xd const &unnormalized_pts2, std::vector< cv::DMatch > const &matches, double focal_length1, double focal_length2, Eigen::Matrix3d *cam2_r_cam1, Eigen::Vector3d *cam2_t_cam1)
Definition: sparse_mapping.cc:453
sparse_mapping::ParseCSV
void ParseCSV(std::string const &csv_file, std::map< std::string, std::vector< double > > *cols)
Definition: sparse_mapping.cc:816
cv
Definition: camera_params.h:31
sparse_mapping::kCLAHE
@ kCLAHE
Definition: sparse_mapping.h:72
sparse_mapping::WriteFileTo
bool WriteFileTo(const char *filename, google::protobuf::io::ZeroCopyOutputStream *rawOutput)
Definition: sparse_mapping.cc:895
sparse_mapping::ReadFeaturesSIFT
int ReadFeaturesSIFT(std::string const &filename, cv::Mat *descriptors, std::vector< cv::KeyPoint > *keypoints)
Definition: sparse_mapping.cc:304
sparse_mapping::WriteFeatures
void WriteFeatures(std::string const &detector_name, std::vector< cv::KeyPoint > const &keypoints, cv::Mat const &descriptors, std::string const &output_filename)
Definition: sparse_mapping.cc:384
camera_params.h
sparse_mapping::ListToListMap
void ListToListMap(std::vector< std::string > const &big_list, std::vector< std::string > const &small_list, std::map< int, int > *map)
Definition: sparse_mapping.cc:545
google
Definition: sparse_mapping.h:42
sparse_mapping::kEqualizeHist
@ kEqualizeHist
Definition: sparse_mapping.h:72
common
Definition: sparse_mapping.h:38