SfM三维点云重建:BA优化--【VS2015+OpenCV3.4+PCL1.8】

前言

SfM多视图三维点云重建–【VS2015+OpenCV3.4+PCL1.8】中实现的增量式SfM三维点云重建,会随着图片数量的增加而导致误差逐渐累积,最后可能无法完成重建。在三维重建中常使用Bundle Adjustment(BA)优化来解决这个问题,BA优化是一种应用广泛的非线性优化方法,其本质属于非线性最小二乘问题,目的是找到使得重投影误差最小的3D点位置和相机参数。这里对BA原理就不再赘述,而是使用Ceres Solver对SfM三维重建后的内外参、点云进行BA优化。

代码

环境:VS2015+OpenCV3.4+PCL1.8+Ceres Solver

首先定义重投影误差作为待优化的代价函数,即计算三维空间点的重投影(世界坐标系到像素坐标系),并计算重投影误差,这部分有很多种形式,但都大同小异。这里ceres::AngleAxisRotatePoint(r, pos3d, pos_proj)将空间点pos3d进行旋转变换(旋转向量r)得到pos_proj,另外,注意添加如下定义和头文件,否则会报错。

#ifndef GLOG_NO_ABBREVIATED_SEVERITIES
#define GLOG_NO_ABBREVIATED_SEVERITIES
#endif
#include <ceres/ceres.h>
#include <ceres/rotation.h>

// 代价函数
struct ReprojectCost
{
   
	cv::Point2d observation;

	ReprojectCost(cv::Point2d& observation) : observation(observation){
   }

	// 参数:内参、外参、三维点、反向投影误差
	template <typename T>
	bool operator()(const T* const intrinsic, const T* const extrinsic, const T* const pos3d, T* residuals) const 
	{
   
		const T* r = extrinsic;
		const T* t = &extrinsic[3];
		
		// 外参数矩阵:转到相机坐标系
		// Apply the camera rotation
		T pos_proj[3];
		ceres::AngleAxisRotatePoint(r, pos3d, pos_proj);

		// Apply the camera translation
		pos_proj[0] += t[0];
		pos_proj[1] += t[1];
		pos_proj[2] += t[2];

		const T x = pos_proj[0] / pos_proj[2]; // 归一化相机坐标
		const T y = pos_proj[1] / pos_proj[2];
		
		// 内参数矩阵:转到像素坐标系
		const T fx = intrinsic[0];
		const T fy = intrinsic[1];
		const T cx = intrinsic[2];
		const T cy = intrinsic[3];

		// Apply intrinsic
		const T u = fx * x + cx;
		const T v = fy * y + cy;
		
		
  • 1
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值