libfovis
motion_estimation.hpp
1 #ifndef __fovis_motion_estimation_hpp__
2 #define __fovis_motion_estimation_hpp__
3 
4 #include <stdint.h>
5 
6 #include <Eigen/Dense>
7 #include <Eigen/Geometry>
8 
9 #include "keypoint.hpp"
10 #include "frame.hpp"
11 #include "camera_intrinsics.hpp"
12 #include "feature_match.hpp"
13 #include "feature_matcher.hpp"
14 #include "rectification.hpp"
15 #include "options.hpp"
16 
17 namespace fovis
18 {
19 
20 enum MotionEstimateStatusCode
21 {
22  NO_DATA,
23  SUCCESS,
24  INSUFFICIENT_INLIERS,
25  OPTIMIZATION_FAILURE,
26  REPROJECTION_ERROR
27 };
28 
29 extern const char* MotionEstimateStatusCodeStrings[];
30 
38 {
39  public:
40  MotionEstimator(const Rectification* rectification, const VisualOdometryOptions& options);
41  ~MotionEstimator();
42 
43  void estimateMotion(OdometryFrame* reference_frame,
44  OdometryFrame* target_frame,
45  DepthSource* depth_source,
46  const Eigen::Isometry3d &init_motion_est,
47  const Eigen::MatrixXd &init_motion_cov);
48 
49  bool isMotionEstimateValid() const {
50  return _estimate_status == SUCCESS;
51  }
52 
53  MotionEstimateStatusCode getMotionEstimateStatus() const {
54  return _estimate_status;
55  }
56 
57  const Eigen::Isometry3d& getMotionEstimate() const {
58  return *_motion_estimate;
59  }
60 
61  const Eigen::MatrixXd& getMotionEstimateCov() const {
62  return *_motion_estimate_covariance;
63  }
64 
65  const FeatureMatch* getMatches() const {
66  return _matches;
67  }
68 
69  int getNumMatches() const {
70  return _num_matches;
71  }
72 
73  int getNumInliers() const {
74  return _num_inliers;
75  }
76 
77  int getNumReprojectionFailures() const {
78  return _num_reprojection_failures;
79  }
80 
81  double getMeanInlierReprojectionError() const {
82  return _mean_reprojection_error;
83  }
84 
85  void sanityCheck() const;
86 
87  private:
88  void matchFeatures(PyramidLevel* ref_level, PyramidLevel* target_level);
89  void computeMaximallyConsistentClique();
90  void estimateRigidBodyTransform();
91  void refineMotionEstimate();
92  void computeReprojectionError();
93 
94  // convenience variable
95  DepthSource* _depth_source;
96 
97  FeatureMatcher _matcher;
98 
99  // for each feature in the target frame,
100  FeatureMatch* _matches;
101  int _num_matches;
102  int _matches_capacity;
103 
104  // total number of feature tracks we've seen
105  int _num_tracks;
106 
107  // total number of frames processed
108  int _num_frames;
109 
110  // inlier count
111  int _num_inliers;
112 
113  // mean inlier feature reprojection error, in pixels.
114  double _mean_reprojection_error;
115 
116  // how many feature matches failed the reprojection test
117  int _num_reprojection_failures;
118 
119  const Rectification* _rectification;
120 
121  OdometryFrame* _ref_frame;
122  OdometryFrame* _target_frame;
123 
124  // the motion estimate.
125  // Can also be interpreted as the coordinate transformation to bring
126  // coordinates in the target frame to the reference frame.
127  Eigen::Isometry3d* _motion_estimate;
128  // the 6x6 estimate of the covriance [x-y-z, roll-pitch-yaw];
129  Eigen::MatrixXd* _motion_estimate_covariance;
130 
131  // maximum mean pixel reprojection error across inliers for a motion
132  // estimate to be considered valid
133  double _max_mean_reprojection_error;
134 
135  // maximum pixel reprojection error for a feature match to be
136  // considered part of the inlier set
137  double _inlier_max_reprojection_error;
138 
139  // maximum distance discrepancy for two feature matches to be
140  // considered compatible (for inlier clique computation)
141  double _clique_inlier_threshold;
142 
143  // at least this many features in the inlier set for a motion
144  // estimate to be considered valid
145  int _min_features_for_valid_motion_estimate;
146 
147  // initial motion estimate confidence bound (in pixels)
148  // assume that a feature's image space location will not deviate
149  // from the location predicted by the initial motion estimate
150  // by more than this much
151  double _max_feature_motion;
152 
153  // refine feature matches to subpixel resolution?
154  int _use_subpixel_refinement;
155 
156  // after each frame is processed, should we update feature locations in the
157  // target frame with the subpixel-refined locations estimated during the
158  // featurea matching?
159  bool _update_target_features_with_refined;
160 
161  MotionEstimateStatusCode _estimate_status;
162 };
163 
164 }
165 
166 #endif
Matches features between a reference and a target image.
Definition: feature_matcher.hpp:12
One level of a Gaussian image pyramid.
Definition: pyramid_level.hpp:21
Stores data specific to an input frame.
Definition: frame.hpp:33
Provides depth estimates for input image pixels.
Definition: depth_source.hpp:29
Represents a single image feature matched between two camera images taken at different times...
Definition: feature_match.hpp:41
Does the heavy lifting for frame-to-frame motion estimation.
Definition: motion_estimation.hpp:37
std::map< std::string, std::string > VisualOdometryOptions
Options.
Definition: options.hpp:106
Maps image coordinates from an input image to image coordinates on a rectified camera.
Definition: rectification.hpp:41
quick and dirty profiling tool.inspired by the matlab tic/toc command
Definition: camera_intrinsics.hpp:6
Options.