ceres库安装及求解七参数问题(布尔沙七参数转换)

ceres库安装(Mac)

由于笔者使用的是macOS系统,因此只介绍macOS系统下的操作,其他平台上的安装已经有很多教程。

macOS下的安装参考官方网站:Installation — Ceres Solver (ceres-solver.org)

安装包下载:http://ceres-solver.org/ceres-solver-2.2.0.tar.gz,可以下载在任意路径下,确定自己能找到即可。

首先安装ceres库的依赖项目,用homebrew一键搞定,在终端下输入:

brew install ceres-solver

这条命令应该回自动安装其他第三方库(eigen、glog、suite-solver),如果不确定,可以输入以下命令确定:

# CMake
brew install cmake
# google-glog and gflags
brew install glog gflags
# Eigen3
brew install eigen
# SuiteSparse
brew install suite-sparse

安装完成后,通过以下命令查看是否正确安装(出现图上的命令说明ceres库及依赖项安装成功):

brew info ceres-solver

在这里插入图片描述

然后,终端中定位到刚刚的安装包下载路径,输入一下命令:

tar zxf ceres-solver-2.2.0.tar.gz
mkdir ceres-bin
cd ceres-bin
cmake ../ceres-solver-2.2.0
make -j3
make test
sudo make install

这样就安装好了!在安装包的路径下查看,会有图中两个文件夹。(测试文件夹是我自己创建的)

在这里插入图片描述

七参数原解算理

笔者以如下问题为例,用ceres库求解七参数:

已知4个点分别在ITRF和CGCS2000坐标系下的坐标,如下所示。请用上述4个已知点的ITRF和CGCS2000坐标,通过布尔莎模型求解七个转换参数。

在这里插入图片描述

空间中两个不同的参考椭球之间的转换需要 3 个旋转参数、3 个平移参数和 1 个缩放参数,即布尔沙七参数。

通常至少需要三个公共已知点,在两个不同空间直角坐标系中的六对 XYZ 坐标值,才能推算出这七个未知参数。计算出了这七个参数,就可以通过七参数方程组,将一个空间直角坐标系下一个点的 XYZ 坐标值转换为另一个空间直角坐标系下的 XYZ 坐标值。

首先,从一个坐标系到另一个坐标系的转换公式为:
[ X B Y B Z B ] = [ Δ X Δ Y Δ Z ] + ( 1 + k ) R ( ε z ) R ( ε y ) R ( ε x ) [ X A Y A Z A ] \left[\begin{array}{c} X_{B} \\ Y_{B} \\ Z_{B} \end{array}\right]=\left[\begin{array}{c} \Delta X \\ \Delta Y \\ \Delta Z \end{array}\right]+(1+k) R\left(\varepsilon_{z}\right) R\left(\varepsilon_{y}\right) R\left(\varepsilon_{x}\right)\left[\begin{array}{c} X_{A} \\ Y_{A} \\ Z_{A} \end{array}\right] XBYBZB = ΔXΔYΔZ +(1+k)R(εz)R(εy)R(εx) XAYAZA
其中, [ Δ X Δ Y Δ Z ] \begin{bmatrix}\Delta X\\ \Delta Y \\ \Delta Z \end{bmatrix} ΔXΔYΔZ 为平移参数, k k k为尺度变化参数, ε x , ε y , ε z \varepsilon_{x},\varepsilon_{y},\varepsilon_{z} εx,εy,εz​为旋转参数。

R ( ε x ) , R ( ε y ) , R ( ε z ) R(\varepsilon_{x}),R(\varepsilon_{y}),R(\varepsilon_{z}) R(εx),R(εy),R(εz)​为旋转参数矩阵,即:
R ( ε x ) = [ 1 0 0 0 cos ⁡ ε x sin ⁡ ε x 0 − sin ⁡ ε x cos ⁡ ε x ] R(\varepsilon_{x})=\begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos \varepsilon_{x} & \sin \varepsilon_{x} \\ 0 & -\sin \varepsilon_{x} & \cos \varepsilon_{x} \end{bmatrix} R(εx)= 1000cosεxsinεx0sinεxcosεx

R ( ε y ) = [ cos ⁡ ε y 0 − sin ⁡ ε y 0 1 0 sin ⁡ ε y 0 cos ⁡ ε y ] R(\varepsilon_{y})=\begin{bmatrix} \cos \varepsilon_{y} & 0 & -\sin \varepsilon_{y} \\ 0 & 1 & 0 \\ \sin \varepsilon_{y} & 0& \cos \varepsilon_{y} \end{bmatrix} R(εy)= cosεy0sinεy010sinεy0cosεy

R ( ε z ) = [ cos ⁡ ε z sin ⁡ ε z 0 − sin ⁡ ε z cos ⁡ ε z 0 0 0 1 ] R(\varepsilon_{z})=\begin{bmatrix} \cos \varepsilon_{z} & \sin \varepsilon_{z} & 0 \\ -\sin \varepsilon_{z} & \cos \varepsilon_{z} & 0\\ 0 & 0& 1 \end{bmatrix} R(εz)= cosεzsinεz0sinεzcosεz0001

为了简化计算,当 k , ε x , ε y , ε z k,\varepsilon_{x},\varepsilon_{y},\varepsilon_{z} k,εx,εy,εz为微小量时,忽略期间的互乘项,且 c o s ε ≈ 1 , s i n ε ≈ 1 cos \varepsilon \approx 1,sin \varepsilon \approx 1 cosε1,sinε1​,则转换公式可变为:
[ X B Y B Z B ] = [ Δ X Δ Y Δ Z ] + ( 1 + k ) [ X A Y A Z A ] + [ 0 ε z − ε y − ε z 0 ε x ε y − ε x 0 ] [ X A Y A Z A ] \left[\begin{array}{c} X_{B} \\ Y_{B} \\ Z_{B} \end{array}\right]=\left[\begin{array}{c} \Delta X \\ \Delta Y \\ \Delta Z \end{array}\right]+(1+k)\left[\begin{array}{c} X_{A} \\ Y_{A} \\ Z_{A} \end{array}\right]+\left[\begin{array}{ccc} 0 & \varepsilon_{z} & -\varepsilon_{y} \\ -\varepsilon_{z} & 0 & \varepsilon_{x} \\ \varepsilon_{y} & -\varepsilon_{x} & 0 \end{array}\right]\left[\begin{array}{c} X_{A} \\ Y_{A} \\ Z_{A} \end{array}\right] XBYBZB = ΔXΔYΔZ +(1+k) XAYAZA + 0εzεyεz0εxεyεx0 XAYAZA

[ X B Y B Z B ] = [ X A Y A Z A ] + [ 1 0 0 0 − Z A Y A X A 0 1 0 Z A 0 − X A Y A 0 0 1 − Y A X A 0 Z A ] [ Δ X Δ Y Δ Z ε 1 ε 2 ε 3 k ] \begin{bmatrix} X_{B} \\ Y_{B} \\ Z_{B} \end{bmatrix}=\left[\begin{array}{c} X_{A} \\ Y_{A} \\ Z_{A} \end{array}\right]+\left[\begin{array}{ccccccc} 1 & 0 & 0 & 0 & -Z_{A} & Y_{A} & X_{A} \\ 0 & 1 & 0 & Z_{A} & 0 & -X_{A} & Y_{A} \\ 0 & 0 & 1 & -Y_{A} & X_{A} & 0 & Z_{A} \end{array}\right] \begin{bmatrix}\Delta X \\ \Delta Y \\ \Delta Z \\ \varepsilon_{1} \\ \varepsilon_{2} \\ \varepsilon_{3} \\ k \end{bmatrix} XBYBZB = XAYAZA + 1000100010ZAYAZA0XAYAXA0XAYAZA ΔXΔYΔZε1ε2ε3k


A = [ 1 0 0 0 − Z A Y A X A 0 1 0 Z A 0 − X A Y A 0 0 1 − Y A X A 0 Z A ] , L = [ X B Y B Z B ] − [ X A Y A Z A ] A=\left[\begin{array}{ccccccc} 1 & 0 & 0 & 0 & -Z_{A} & Y_{A} & X_{A} \\ 0 & 1 & 0 & Z_{A} & 0 & -X_{A} & Y_{A} \\ 0 & 0 & 1 & -Y_{A} & X_{A} & 0 & Z_{A} \end{array}\right], L=\left[\begin{array}{c} X_{B} \\ Y_{B} \\ Z_{B} \end{array}\right]-\left[\begin{array}{c} X_{A} \\ Y_{A} \\ Z_{A} \end{array}\right] A= 1000100010ZAYAZA0XAYAXA0XAYAZA ,L= XBYBZB XAYAZA

X = [ Δ X , Δ Y , Δ Z , ε 1 , ε 2 , ε 3 , k ] T X=\left[\Delta X, \Delta Y, \Delta Z, \varepsilon_{1}, \varepsilon_{2}, \varepsilon_{3}, k\right]^{T} \\ X=[ΔX,ΔY,ΔZ,ε1,ε2,ε3,k]T

​ 为了求解7个转换参数,至少需要3个公共点,当多于3个公共点时,可按照最小二乘法求得7个参数的最或然值。符合间接平差,依照最小二乘法求解:
V = A ∗ X − L V=A*X-L V=AXL

X = ( A T A ) − 1 A T L X=(A^{T}A)^{-1}A^{T}L X=(ATA)1ATL

ceres库求解七参数

终端进入ceres-bin文件夹,新建两个文件。

第一个是ceres_example.cpp文件(名字任意),将下面代码复制粘贴即可。

#include <ceres/ceres.h>
#include <iomanip>

struct BursaWolfModel {
    BursaWolfModel(double X_s, double Y_s, double Z_s,
        double X_t, double Y_t, double Z_t)
        : X_s(X_s), Y_s(Y_s), Z_s(Z_s), X_t(X_t), Y_t(Y_t), Z_t(Z_t) {}

    template <typename T>
    bool operator()(const T* const params, T* residuals) const {
        // 假设params包含七个参数:三个平移参数(dx, dy, dz),三个旋转参数(rx, ry, rz)和一个尺度因子(m)
        T dx = params[0];
        T dy = params[1];
        T dz = params[2];
        T rx = params[3];
        T ry = params[4];
        T rz = params[5];
        T m = params[6];

        // 计算转换后的坐标
        T X_c = X_s + dx - Z_s * ry + Y_s * rz + X_s * m;
        T Y_c = Y_s + dy + Z_s * rx - X_s * rz + Y_s * m;
        T Z_c = Z_s + dz - Y_s * rx + X_s * ry + Z_s * m;

        // 计算残差
        residuals[0] = -X_t + X_c;
        residuals[1] = -Y_t + Y_c;
        residuals[2] = -Z_t + Z_c;

        return true;
    }

private:
    const double X_s, Y_s, Z_s, X_t, Y_t, Z_t;
};


int main(int argc, char const* argv[])
{
    double source_coordinates[4][3] = { {-2358683.2015, 5153007.9355, 2916777.1882}, {-2476191.1223, 5220545.6468, 2692588.9666},
                                        {-2366980.0034, 5241954.8314, 2748152.9313}, {-2479709.4985, 5074389.1912, 2953715.9067} };
    double target_coordinates[4][3] = { {-2358682.9205, 5153007.9970, 2916777.2489}, {-2476190.8413, 5220545.7090, 2692589.0279}, 
                                        {-2366979.7223, 5241954.8932, 2748152.9923}, {-2479709.2174, 5074389.2528, 2953715.9674} };
    double params[7] = { 0, 0, 0, 0, 0, 0, 0 };

    ceres::Problem problem;

    // 我们有4组源坐标和目标坐标
    for (int i = 0; i < 4; ++i) {
        problem.AddResidualBlock(
            new ceres::AutoDiffCostFunction<BursaWolfModel, 3, 7>(
                new BursaWolfModel(source_coordinates[i][0], source_coordinates[i][1], source_coordinates[i][2],
                    target_coordinates[i][0], target_coordinates[i][1], target_coordinates[i][2])),
            nullptr,  // 没有核函数
            params);  // 七个参数(dx, dy, dz, rx, ry, rz, m)
    }

    ceres::Solver::Options options;
    // 设置求解器选项

    ceres::Solver::Summary summary;
    ceres::Solve(options, &problem, &summary);

    // 输出求解结果
    std::cout << std::fixed << std::setprecision(20);
    std::cout << summary.FullReport() << "\n";
    std::cout << "dx = " << params[0] << "\n";
    std::cout << "dy = " << params[1] << "\n";
    std::cout << "dz = " << params[2] << "\n";
    std::cout << "rx = " << params[3] << "\n";
    std::cout << "ry = " << params[4] << "\n";
    std::cout << "rz = " << params[5] << "\n";
    std::cout << "m = " << params[6] << "\n";

    return 0;
}

第二个是CMakeLists.txt,复制一下内容(记得将add_executable后改为自己创建的cpp名字):

cmake_minimum_required(VERSION 3.8.0)
 
project(ceres_example)
 
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
find_package(Ceres REQUIRED)
 
include_directories(
  ${CERES_INCLUDE_DIRS}
)
 
add_executable(ceres_example
ceres_example.cpp)
 
target_link_libraries(ceres_example
    ${CERES_LIBRARIES}
)

输入以下命令:

mkdir build           
cd build
cmake ..
make

文件夹中的内容应该如下图所示:

在这里插入图片描述

最后输入

./ceres_example

终端界面上出现以下内容,最下面即为求出的七参数:

在这里插入图片描述

解算成功!

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值