//这里姿态又用欧拉角表示
map_poses[indexPose] = {angleAxis[0], angleAxis[1], angleAxis[2], t(0), t(1), t(2)};
double * parameter_block = &map_poses.at(indexPose)[0];
problem.AddParameterBlock(parameter_block, 6);
std::vector<int> vec_constant_extrinsic;
vec_constant_extrinsic.insert(vec_constant_extrinsic.end(), {3,4,5});
if (!vec_constant_extrinsic.empty())
{
// 主要用到ceres的SubsetParameterization函数
ceres::SubsetParameterization *subset_parameterization =
new ceres::SubsetParameterization(6, vec_constant_extrinsic);
problem.SetParameterization(parameter_block, subset_parameterization);
}
• 优化相机内参及畸变系数,pose subset parameterization(pose 信息部分参数优化)和3D landmark,当 只优化位置信息时候,problem需要添加的代码如下(同上面代码,只需修改一行):
//这里姿态又用欧拉角表示
map_poses[indexPose] = {angleAxis[0], angleAxis[1], angleAxis[2], t(0), t(1), t(2)};
double * parameter_block = &map_poses.at(indexPose)[0];
problem.AddParameterBlock(parameter_block, 6);
std::vector<int> vec_constant_extrinsic;
vec_constant_extrinsic.insert(vec_constant_extrinsic.end(), {1,2,3});
if (!vec_constant_extrinsic.empty())
{
ceres::SubsetParameterization *subset_parameterization =
new ceres::SubsetParameterization(6, vec_constant_extrinsic);
problem.SetParameterization(parameter_block, subset_parameterization);
}
• 优化相机内参及畸变系数,pose 是常量不优化 和3D landmark. 代价函数写法如下:
//相机模型
template <typename CameraModel>
class BundleAdjustmentConstantPoseCostFunction {
public:
BundleAdjustmentConstantPoseCostFunction(const Eigen::Vector4d& qvec,
const Eigen::Vector3d& tvec,
const Eigen::Vector2d& point2D)
: qw_(qvec(0)),
qx_(qvec(1)),
qy_(qvec(2)),
qz_(qvec(3)),
tx_(tvec(0)),
ty_(tvec(1)),
tz_(tvec(2)),
observed_x_(point2D(0)),
observed_y_(point2D(1)) {}
static ceres::CostFunction* Create(const Eigen::Vector4d& qvec,
const Eigen::Vector3d& tvec,
const Eigen::Vector2d& point2D) {
return (new ceres::AutoDiffCostFunction<
BundleAdjustmentConstantPoseCostFunction<CameraModel>, 2, 3,
CameraModel::kNumParams>(
new BundleAdjustmentConstantPoseCostFunction(qvec, tvec, point2D)));
}
template <typename T>
bool operator()(const T* const point3D, const T* const camera_params,
T* residuals) const {
const T qvec[4] = {T(qw_), T(qx_), T(qy_), T(qz_)};
// Rotate and translate.
T projection[3];
ceres::UnitQuaternionRotatePoint(qvec, point3D, projection);
projection[0] += T(tx_);
projection[1] += T(ty_);
projection[2] += T(tz_);
// Project to image plane.
projection[0] /= projection[2];
projection[1] /= projection[2];
// Distort and transform to pixel space.
CameraModel::WorldToImage(camera_params, projection[0], projection[1],
&residuals[0], &residuals[1]);
// Re-projection error.
residuals[0] -= T(observed_x_);
residuals[1] -= T(observed_y_);
return true;
}
private:
const double qw_;
const double qx_;
const double qy_;
const double qz_;
const double tx_;
const double ty_;
const double tz_;
const double observed_x_;
const double observed_y_;
};