struct RGBDCostFunctor
{
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
RGBDCostFunctor
(
const ceres::DepthBiCubicInterpolator<ceres::Grid2D<double, 1>>& kf_depth_interp,
const ceres::BiCubicInterpolator<ceres::Grid2D<double, 1>>& kf_intensity_interp,
const double surfel_intensity,
const Eigen::Matrix3d& intrinsics_mat
):
kf_depth_interp_(kf_depth_interp),
kf_intensity_interp_(kf_intensity_interp),
intrinsics_mat_(intrinsics_mat),
surfel_intensity_(surfel_intensity)
{
}
template<typename T>
bool operator()
(
const T* surfel,
const T* kf_pose_se3_raw,
T* out_residuals
) const
{
Eigen::Map<Eigen::Matrix<T, 3, 1> const> g_surfel(surfel);
Eigen::Map<Sophus::SE3<T> const> kf_pose_se3(kf_pose_se3_raw);
Eigen::Matrix<T, 3, 1> l_surfel = kf_pose_se3 * g_surfel;
Eigen::Matrix<T, 3, 1> pixel_coord = intrinsics_mat_ * l_surfel / l_surfel(2, 0);
T depth_in_kf;
bool is_success = kf_depth_interp_.Evaluate(pixel_coord(1, 0), pixel_coord(0, 0), &depth_in_kf);
if(is_success == false)
{
out_residuals[0] = T(0.0);
out_residuals[1] = T(0.0);
return true;
}
T depth_l_surfel = l_surfel(2, 0);
out_residuals[0] = depth_in_kf - depth_l_surfel;
T intensity_kf;
kf_intensity_interp_.Evaluate(pixel_coord(1, 0), pixel_coord(0, 0), &intensity_kf);
out_residuals[1] = surfel_intensity_ - intensity_kf;
return true;
}
static ceres::CostFunction* Create
(
const ceres::DepthBiCubicInterpolator<ceres::Grid2D<double, 1>>& kf_depth_interp,
const ceres::BiCubicInterpolator<ceres::Grid2D<double, 1>>& kf_intensity_interp,
const double surfel_intensity,
const Eigen::Matrix3d& intrinsics_mat
)
{
return
(
new ceres::AutoDiffCostFunction
<RGBDCostFunctor, 2, 3, Sophus::SE3d::num_parameters>
(new RGBDCostFunctor(kf_depth_interp, kf_intensity_interp, surfel_intensity, intrinsics_mat))
);
}
const ceres::DepthBiCubicInterpolator<ceres::Grid2D<double, 1>>& kf_depth_interp_;
const ceres::BiCubicInterpolator<ceres::Grid2D<double, 1>>& kf_intensity_interp_;
double surfel_intensity_;
Eigen::Matrix3d intrinsics_mat_;
};