18 #ifndef OPTIMIZATION_COMMON_RESIDUALS_H_
19 #define OPTIMIZATION_COMMON_RESIDUALS_H_
25 #include <ceres/problem.h>
26 #include <ceres/jet.h>
27 #include <ceres/ceres.h>
28 #include <ceres/solver.h>
29 #include <ceres/cost_function.h>
30 #include <ceres/loss_function.h>
31 #include <ceres/autodiff_cost_function.h>
37 : source_t_point_(source_t_point), target_t_point_(target_t_point) {}
40 bool operator()(
const T* target_T_source_data, T* point_to_point_error)
const {
41 const auto target_T_source = Isometry3<T>(target_T_source_data);
43 const Eigen::Matrix<T, 3, 1> estimated_target_t_point = target_T_source * source_t_point_.cast<T>();
44 point_to_point_error[0] = estimated_target_t_point[0] - target_t_point_[0];
45 point_to_point_error[1] = estimated_target_t_point[1] - target_t_point_[1];
46 point_to_point_error[2] = estimated_target_t_point[2] - target_t_point_[2];
51 Eigen::Matrix<double, 6, 1>& target_T_source, ceres::Problem& problem) {
52 ceres::LossFunction* huber_loss =
new ceres::HuberLoss(1.345);
53 ceres::CostFunction* point_to_point_cost_function =
54 new ceres::AutoDiffCostFunction<PointToPointError, 3, 6>(
new PointToPointError(source_t_point, target_t_point));
55 problem.AddResidualBlock(point_to_point_cost_function, huber_loss, target_T_source.data());
67 : source_t_point_(source_t_point), target_t_point_(target_t_point), target_normal_(target_normal) {}
70 bool operator()(
const T* target_T_source_data, T* point_to_plane_error)
const {
71 const auto target_T_source = Isometry3<T>(target_T_source_data);
73 const Eigen::Matrix<T, 3, 1> estimated_target_t_point = target_T_source * source_t_point_.cast<T>();
74 const Eigen::Matrix<T, 3, 1> target_F_point_t_estimated_point =
75 estimated_target_t_point - target_t_point_.cast<T>();
76 point_to_plane_error[0] = target_F_point_t_estimated_point.dot(target_normal_.cast<T>());
81 const Eigen::Vector3d& target_normal, Eigen::Matrix<double, 6, 1>& target_T_source,
82 ceres::Problem& problem) {
83 ceres::LossFunction* huber_loss =
new ceres::HuberLoss(1.345);
84 ceres::CostFunction* point_to_plane_cost_function =
new ceres::AutoDiffCostFunction<PointToPlaneError, 1, 6>(
86 problem.AddResidualBlock(point_to_plane_cost_function, huber_loss, target_T_source.data());
99 : source_t_point_(source_t_point),
100 target_t_point_(target_t_point),
101 source_normal_(source_normal),
102 target_normal_(target_normal) {}
104 template <
typename T>
105 bool operator()(
const T* target_T_source_data, T* symmetric_point_to_plane_error)
const {
106 const auto target_T_source = Isometry3<T>(target_T_source_data);
108 const Eigen::Matrix<T, 3, 1> estimated_target_t_point = target_T_source * source_t_point_.cast<T>();
109 const Eigen::Matrix<T, 3, 1> target_F_point_t_estimated_point =
110 estimated_target_t_point - target_t_point_.cast<T>();
111 const Eigen::Matrix<T, 3, 1> estimated_source_t_point = target_T_source.inverse() * target_t_point_.cast<T>();
112 const Eigen::Matrix<T, 3, 1> source_F_point_t_estimated_point =
113 estimated_source_t_point - source_t_point_.cast<T>();
114 symmetric_point_to_plane_error[0] = source_F_point_t_estimated_point.dot(source_normal_.cast<T>());
115 symmetric_point_to_plane_error[1] = target_F_point_t_estimated_point.dot(target_normal_.cast<T>());
121 Eigen::Matrix<double, 6, 1>& target_T_source, ceres::Problem& problem) {
122 ceres::LossFunction* huber_loss =
new ceres::HuberLoss(1.345);
123 ceres::CostFunction* symmetric_point_to_plane_cost_function =
124 new ceres::AutoDiffCostFunction<SymmetricPointToPlaneError, 2, 6>(
126 problem.AddResidualBlock(symmetric_point_to_plane_cost_function, huber_loss, target_T_source.data());
136 template <
typename DISTORTER>
140 : image_point_(image_point), depth_cloud_F_point_3d_(depth_cloud_F_point_3d) {}
142 template <
typename T>
143 bool operator()(
const T* depth_image_A_depth_cloud_data,
const T* intrinsics_data,
const T* distortion_data,
144 T* reprojection_error)
const {
146 const auto intrinsics = Intrinsics<T>(intrinsics_data);
147 const auto depth_image_A_depth_cloud = Affine3<T>(depth_image_A_depth_cloud_data);
150 const Eigen::Matrix<T, 3, 1> depth_image_F_point_3d = depth_image_A_depth_cloud * depth_cloud_F_point_3d_.cast<T>();
151 const Eigen::Matrix<T, 2, 1> undistorted_reprojected_point_3d = (intrinsics * depth_image_F_point_3d).hnormalized();
152 const Eigen::Matrix<T, 2, 1> distorted_reprojected_point_3d =
153 distorter_.Distort(distortion_data, intrinsics, undistorted_reprojected_point_3d);
155 reprojection_error[0] = image_point_[0] - distorted_reprojected_point_3d[0];
156 reprojection_error[1] = image_point_[1] - distorted_reprojected_point_3d[1];
161 Eigen::Matrix<double, 7, 1>& depth_image_A_depth_cloud_vector,
162 Eigen::Matrix<double, 4, 1>& intrinsics_vector, Eigen::VectorXd& distortion,
163 ceres::Problem& problem) {
164 ceres::LossFunction* huber_loss =
new ceres::HuberLoss(1.345);
165 ceres::CostFunction* reprojection_cost_function =
166 new ceres::AutoDiffCostFunction<AffineReprojectionError<DISTORTER>, 2, 7, 4, DISTORTER::kNumParams>(
168 problem.AddResidualBlock(reprojection_cost_function, huber_loss, depth_image_A_depth_cloud_vector.data(),
169 intrinsics_vector.data(), distortion.data());
173 Eigen::Vector2d image_point_;
175 DISTORTER distorter_;
178 template <
typename DISTORTER>
182 : image_point_(image_point), target_t_point_3d_(target_t_point_3d) {}
184 template <
typename T>
185 bool operator()(
const T* camera_T_target_data,
const T* focal_lengths_data,
const T* principal_points_data,
186 const T* distortion_data, T* reprojection_error)
const {
188 const auto intrinsics = Intrinsics<T>(focal_lengths_data, principal_points_data);
189 const auto camera_T_target = Isometry3<T>(camera_T_target_data);
191 const Eigen::Matrix<T, 3, 1> camera_t_point_3d = camera_T_target * target_t_point_3d_.cast<T>();
192 const Eigen::Matrix<T, 2, 1> undistorted_reprojected_point_3d = (intrinsics * camera_t_point_3d).hnormalized();
193 const Eigen::Matrix<T, 2, 1> distorted_reprojected_point_3d =
194 distorter_.Distort(distortion_data, intrinsics, undistorted_reprojected_point_3d);
196 reprojection_error[0] = image_point_[0] - distorted_reprojected_point_3d[0];
197 reprojection_error[1] = image_point_[1] - distorted_reprojected_point_3d[1];
202 Eigen::Matrix<double, 6, 1>& camera_T_target, Eigen::Vector2d& focal_lengths,
203 Eigen::Vector2d& principal_points, Eigen::VectorXd& distortion, ceres::Problem& problem,
204 const double scale_factor = 1,
const double huber_threshold = 1.345) {
205 ceres::LossFunction* huber_loss =
new ceres::HuberLoss(huber_threshold);
206 ceres::LossFunction* scaled_huber_loss =
new ceres::ScaledLoss(huber_loss, scale_factor, ceres::TAKE_OWNERSHIP);
207 ceres::CostFunction* reprojection_cost_function =
208 new ceres::AutoDiffCostFunction<ReprojectionError<DISTORTER>, 2, 6, 2, 2, DISTORTER::kNumParams>(
210 problem.AddResidualBlock(reprojection_cost_function, scaled_huber_loss, camera_T_target.data(),
211 focal_lengths.data(), principal_points.data(), distortion.data());
215 Eigen::Vector2d image_point_;
217 DISTORTER distorter_;
221 #endif // OPTIMIZATION_COMMON_RESIDUALS_H_