19 #ifndef VISION_COMMON_INVERSE_DEPTH_MEASUREMENT_H_
20 #define VISION_COMMON_INVERSE_DEPTH_MEASUREMENT_H_
24 #include <gtsam/base/Lie.h>
25 #include <gtsam/base/Manifold.h>
26 #include <gtsam/base/Matrix.h>
27 #include <gtsam/geometry/Pose3.h>
46 const Eigen::Matrix3d& intrinsics,
const gtsam::Pose3& body_T_sensor)
48 image_coordinates_(image_coordinates),
49 intrinsics_(intrinsics),
50 body_T_sensor_(body_T_sensor) {}
59 const gtsam::Pose3& world_T_source_body,
const gtsam::Pose3& world_T_target_body,
60 boost::optional<gtsam::Matrix&> d_projected_point_d_world_T_source_body = boost::none,
61 boost::optional<gtsam::Matrix&> d_projected_point_d_world_T_target_body = boost::none,
62 boost::optional<gtsam::Matrix&> d_projected_point_d_inverse_depth = boost::none)
const {
63 if (d_projected_point_d_world_T_source_body || d_projected_point_d_world_T_target_body ||
64 d_projected_point_d_inverse_depth) {
89 gtsam::Matrix d_source_sensor_t_point_d_depth;
90 gtsam::Matrix d_target_sensor_T_world_d_world_T_target_sensor;
91 gtsam::Matrix d_target_sensor_T_source_sensor_d_world_T_source_sensor;
92 gtsam::Matrix d_target_sensor_T_source_sensor_d_target_sensor_T_world;
93 gtsam::Matrix d_target_sensor_t_point_d_target_sensor_T_source_sensor;
94 gtsam::Matrix d_target_sensor_t_point_d_source_sensor_t_point;
95 gtsam::Matrix d_projected_point_d_target_sensor_t_point;
96 gtsam::Matrix d_world_T_source_sensor_d_world_T_source_body;
97 gtsam::Matrix d_world_T_target_sensor_d_world_T_target_body;
98 const auto projeced_point =
99 ProjectHelper(world_T_source_body, world_T_target_body, d_world_T_source_sensor_d_world_T_source_body,
100 d_world_T_target_sensor_d_world_T_target_body, d_target_sensor_T_world_d_world_T_target_sensor,
101 d_source_sensor_t_point_d_depth, d_target_sensor_T_source_sensor_d_target_sensor_T_world,
102 d_target_sensor_T_source_sensor_d_world_T_source_sensor,
103 d_target_sensor_t_point_d_target_sensor_T_source_sensor,
104 d_target_sensor_t_point_d_source_sensor_t_point, d_projected_point_d_target_sensor_t_point);
106 const gtsam::Matrix d_target_sensor_T_source_sensor_d_world_T_target_sensor =
107 d_target_sensor_T_source_sensor_d_target_sensor_T_world * d_target_sensor_T_world_d_world_T_target_sensor;
108 const gtsam::Matrix d_target_sensor_t_point_d_world_T_source_sensor =
109 d_target_sensor_t_point_d_target_sensor_T_source_sensor *
110 d_target_sensor_T_source_sensor_d_world_T_source_sensor;
111 const gtsam::Matrix d_target_sensor_t_point_d_world_T_target_sensor =
112 d_target_sensor_t_point_d_target_sensor_T_source_sensor *
113 d_target_sensor_T_source_sensor_d_world_T_target_sensor;
114 if (d_projected_point_d_world_T_source_body)
115 *d_projected_point_d_world_T_source_body = d_projected_point_d_target_sensor_t_point *
116 d_target_sensor_t_point_d_world_T_source_sensor *
117 d_world_T_source_sensor_d_world_T_source_body;
118 if (d_projected_point_d_world_T_target_body)
119 *d_projected_point_d_world_T_target_body = d_projected_point_d_target_sensor_t_point *
120 d_target_sensor_t_point_d_world_T_target_sensor *
121 d_world_T_target_sensor_d_world_T_target_body;
123 const double d_depth_d_inverse_depth = -1.0 / (inverse_depth_ * inverse_depth_);
124 const gtsam::Matrix d_target_sensor_t_point_d_depth =
125 d_target_sensor_t_point_d_source_sensor_t_point * d_source_sensor_t_point_d_depth;
126 if (d_projected_point_d_inverse_depth)
127 *d_projected_point_d_inverse_depth =
128 d_projected_point_d_target_sensor_t_point * d_target_sensor_t_point_d_depth * d_depth_d_inverse_depth;
129 return projeced_point;
133 return ProjectHelper(world_T_source_body, world_T_target_body);
136 double depth()
const {
return 1.0 / inverse_depth_; }
155 void print(
const std::string& s = std::string())
const {
156 std::cout <<
"inverse depth: " << inverse_depth_ << std::endl;
160 return intrinsics_.isApprox(s.intrinsics_, tol) && body_T_sensor_.equals(s.body_T_sensor_, 1e-9) &&
161 std::abs(inverse_depth_ - s.inverse_depth_) < 1e-9 &&
162 image_coordinates_.isApprox(s.image_coordinates_, 1e-9);
168 boost::optional<Eigen::Vector2d> ProjectHelper(
169 const gtsam::Pose3& world_T_source_body,
const gtsam::Pose3& world_T_target_body,
170 boost::optional<gtsam::Matrix&> d_world_T_source_sensor_d_world_T_source_body = boost::none,
171 boost::optional<gtsam::Matrix&> d_world_T_target_sensor_d_world_T_target_body = boost::none,
172 boost::optional<gtsam::Matrix&> d_target_sensor_T_world_d_world_T_target_sensor = boost::none,
173 boost::optional<gtsam::Matrix&> d_source_sensor_t_point_d_depth = boost::none,
174 boost::optional<gtsam::Matrix&> d_target_sensor_T_source_sensor_d_target_sensor_T_world = boost::none,
175 boost::optional<gtsam::Matrix&> d_target_sensor_T_source_sensor_d_world_T_source_sensor = boost::none,
176 boost::optional<gtsam::Matrix&> d_target_sensor_t_point_d_target_sensor_T_source_sensor = boost::none,
177 boost::optional<gtsam::Matrix&> d_target_sensor_t_point_d_source_sensor_t_point = boost::none,
178 boost::optional<gtsam::Matrix&> d_projected_point_d_target_sensor_t_point = boost::none)
const {
179 const gtsam::Pose3 world_T_source_sensor =
180 world_T_source_body.compose(body_T_sensor_, d_world_T_source_sensor_d_world_T_source_body);
181 const gtsam::Pose3 world_T_target_sensor =
182 world_T_target_body.compose(body_T_sensor_, d_world_T_target_sensor_d_world_T_target_body);
184 const gtsam::Pose3 target_sensor_T_world =
185 world_T_target_sensor.inverse(d_target_sensor_T_world_d_world_T_target_sensor);
186 const gtsam::Pose3 target_sensor_T_source_sensor =
187 target_sensor_T_world.compose(world_T_source_sensor, d_target_sensor_T_source_sensor_d_target_sensor_T_world,
188 d_target_sensor_T_source_sensor_d_world_T_source_sensor);
189 const Eigen::Vector3d target_sensor_t_point = target_sensor_T_source_sensor.transformFrom(
190 source_sensor_t_point, d_target_sensor_t_point_d_target_sensor_T_source_sensor,
191 d_target_sensor_t_point_d_source_sensor_t_point);
192 if (target_sensor_t_point.z() < 0)
return boost::none;
193 return vision_common::Project(target_sensor_t_point, intrinsics_, d_projected_point_d_target_sensor_t_point);
196 Eigen::Vector2d image_coordinates_;
197 Eigen::Matrix3d intrinsics_;
198 gtsam::Pose3 body_T_sensor_;
199 double inverse_depth_;
206 :
public internal::Manifold<vision_common::InverseDepthMeasurement> {};
210 :
public internal::Manifold<vision_common::InverseDepthMeasurement> {};
213 #endif // VISION_COMMON_INVERSE_DEPTH_MEASUREMENT_H_