C++实现七参数转换法(布尔莎模型)

本文介绍了C++实现七参数转换法,即布尔莎模型,用于坐标转换。通过七个参数(平移、旋转和尺度变化)进行坐标变换,并提供了利用最小二乘法求解参数的步骤。此外,还展示了实例代码,包括数据导入、正向计算、系数求解和精度验证。
摘要由CSDN通过智能技术生成

七参数转换法(布尔莎模型)

七参数法(包括布尔莎模型,一步法模型,海尔曼特等)是解决此问题的比较严密和通用的方法。一般含有7个转换参数:X平移,Y平移,Z平移,X旋转,Y旋转,Z旋转,尺度变化m。通过3个以上的公共点由最小二乘法拟合出相应的转换参数, 然后由求得的转换参数进行坐标转换。

七参数公式如下:

[ X Y Z ] = [ Δ X Δ Y Δ Z ] + ( 1 + m ) [ 1 θ z − θ y − θ z 1 θ x θ y − θ x 1 ] [ X 0 Y 0 Z 0 ] \left[\begin{array}{l} X \\ Y \\ Z \end{array}\right]=\left[\begin{array}{c} \Delta X \\ \Delta Y \\ \Delta Z \end{array}\right]+(1+m)\left[\begin{array}{ccc} 1 & \theta_{z} & -\theta_{y} \\ -\theta_{z} & 1 & \theta_{x} \\ \theta_{y} & -\theta_{x} & 1 \end{array}\right]\left[\begin{array}{l} X_{0} \\ Y_{0} \\ Z_{0} \end{array}\right] XYZ=ΔXΔYΔZ+(1+m)1θzθyθz1θxθyθx1X0Y0Z0

式中, Δ X , Δ Y , Δ Z \Delta X, \Delta Y, \Delta Z ΔX,ΔY,ΔZ为三个平移参数; θ x , θ y , θ z \theta_{x}, \theta_{y}, \theta_{z} θx,θy,θz为3个旋转参数,m为尺度参数。将七参数作为未知数,并且按参数线性化,则可以转换为:

[ X − X ( X 0 ) Y − Y ( Y 0 ) Z − Z ( Z 0 ) ] = [ 1 0 0 0 − ( 1 + m ) Z 0 ( 1 + m ) Y 0 X 0 + θ z Y 0 − θ y Z 0 0 1 0 ( 1 + m ) Z 0 0 − ( 1 + m ) X 0 − θ z X 0 + Y 0 + θ x Z 0 0 0 1 − ( 1 + m ) Y 0 ( 1 + m ) X 0 0 θ y X 0 − θ x Y 0 + Z 0 ] [ Δ X Δ Y Δ Z θ x θ y θ z m ] \left[\begin{array}{c} X-X\left(X_{0}\right) \\ Y-Y\left(Y_{0}\right) \\ Z-Z\left(Z_{0}\right) \end{array}\right]=\left[\begin{array}{ccccccc} 1 & 0 & 0 & 0 & -(1+m) Z_{0} & (1+m) Y_{0} & X_{0}+\theta_{z} Y_{0}-\theta_{y} Z_{0} \\ 0 & 1 & 0 & (1+m) Z_{0} & 0 & -(1+m) X_{0} & -\theta_{z} X_{0}+Y_{0}+\theta_{x} Z_{0} \\ 0 & 0 & 1 & -(1+m) Y_{0} & (1+m) X_{0} & 0 & \theta_{y} X_{0}-\theta_{x} Y_{0}+Z_{0} \end{array}\right]\left[\begin{array}{c} \Delta X \\ \Delta Y \\ \Delta Z \\ \theta_{x} \\ \theta_{y} \\ \theta_{z} \\ m \end{array}\right] XX(X0)YY(Y0)ZZ(Z0)=1000100010(1+m)Z0(1+m)Y0(1+m)Z00(1+m)X0(1+m)Y0(1+m)X00X0+θzY0θyZ0θzX0+Y0+θxZ0θyX0θxY0+Z0ΔXΔYΔZθxθyθzm
其中, X ( X 0 ) , Y ( Y 0 ) , Z ( Z 0 ) X(X_0),Y(Y_0),Z(Z_0) X(X0),Y(Y0),Z(Z0)由七参数公式给出,利用最小二乘法法即可对该线性化的方程进行迭代求解。

七参数转换法实例

下面以C++代码为例,利用已有四个控制点坐标,根据最小二乘来求解七参数模型的参数,并利用一个检查点来验证其转换精度。

1.导入数据

使用4个同名点的原坐标(x, y, z)和目标坐标(x’, y’, z’)来求解七参数

2.正向计算

根据坐标转换公式来列立系数方程定义函数返回系数矩阵。使用4个同名点的坐标转换公式作为误差方程进行最小二乘平差,根据坐标转换公式来列立系数方程 W x = b W x=b Wx=b

3.系数求解

组成法方程 $(W’W) x = (W’b) 并 利 用 最 小 二 乘 求 解 并利用最小二乘求解 x$

4.模型精度评定和结果验证

评定最小二乘模型的精度结果,并使用预留的已知坐标同名点来验证七参数模型的效果

C++代码:
#include <arrayfire.h>
#include <iostream>

using namespace af;

array point2matrix(double& x, double& y, double& z, array& args)
{
    /*
    定义函数返回系数矩阵 B, l
        定义函数: point2matrix,
        通过给定的同名点坐标列立误差方程B系数阵的部分
        x, y, z: 原坐标值
        args: 七参数误差值[Delta_X, Delta_Y, Delta_Z, theta_x, theta_y, theta_z, m]
        返回值: W系数阵的部分
    */
    array W = constant(0,3,7,f64);
    W(seq(3), seq(3))= identity(3, 3);
    W(0, 4) = -(1 + args(6)) * z;
    W(0, 5) = (1 + args(6)) * y;
    W(0, 6) = x + args(5) * y - args(4) * z;

    W(1, 3) = (1 + args(6)) * z;
    W(1, 5) = -(1 + args(6)) * x;
    W(1, 6) = -(args(5) * x) + y + args(3) * z;

    W(2, 3) = -(1 + args(6)) * y;
    W(2, 4) = (1 + args(6)) * x;
    W(2, 6) = args(4) * x - args(3) * y + z;
    return W;
}


array points2W(array &points, array &args)
{
    /*
    定义函数: points2W
        通过同名点序列列立误差方程B系数阵的整体
        x, y, z: 同名点序列
        args: 七参数误差值[Delta_X, Delta_Y, Delta_Z, theta_x, theta_y, theta_z, m]
        返回值: W系数阵
    */
    array big_mat;
    double x, y, z;
    for(int i =0;i<points.dims(0);++i)
    {
        array p = points(i, span);
        x = p(0).scalar<double>();
        y = p(1).scalar<double>();
        z = p(2).scalar<double>();
        array mat = point2matrix(x, y, z, args);
        if (big_mat.elements() == 0)
        {
            big_mat = mat;
        }
        else
        {
            big_mat = join(0,big_mat, mat);
        }
    }
    return big_mat;
}

array ordinationConvert(double& x1, double& y1, double& z1, array& args)
{
    array p = constant(0,1,3,f64);
    p(0) = args(0) + (1 + args(6)) * (x1 + args(5) * y1 - args(4) * z1);
    p(1) = args(1) + (1 + args(6)) * (-(args(5) * x1) + y1 + args(3) * z1);
    p(2) = args(2) + (1 + args(6)) * (args(4) * x1 - (args(3) * y1) + z1);
    return p;
}

array points2b(array &source_points, array &target_points, array &args)
{
    /*
    定义函数: points2b
          通过同名点坐标转换关系列立误差方程B系数阵的整体
          x, y, z: 同名点的原坐标和目标坐标对组成的序列
          args: 七参数误差值[Delta_X, Delta_Y, Delta_Z, theta_x, theta_y, theta_z, m]
          返回值: b系数阵
    */

    int len = source_points.dims(0);
    array big_mat = constant(0,len,3,f64);
    //array p0, p1, p2;
    double x1, y1, z1;
    for(int i=0;i<len;++i)
    {
        array p1 = source_points(i, span);
        x1 = p1(0).scalar<double>(); y1 = p1(1).scalar<double>(); z1 = p1(2).scalar<double>();
        array p2 = target_points(i, span);
        array p0 = ordinationConvert(x1, y1, z1, args);
        big_mat(i, span) = p2 - p0;
    }
    return flat(big_mat.T());
}

int main()
{
    try {
        /*int device = 2;
        setDevice(device);*/
        array Args = constant(0, 7,f64);
        array parameters = constant(1,7,f64);
        // 原坐标(x, y, z)
        double h_source_points[12] = {
            3381400.980, 395422.030, 32.956,
            3381404.344, 395844.239, 32.207,
            3382149.810, 396003.592, 33.290,
            3382537.793, 395985.359, 33.412 };
        // 目标坐标(x’, y’, z’)  
        double h_target_points[12] = {
            3380968.194, 539468.888, 13.875,
            3380977.154, 539890.934, 13.179,
            3381724.612, 540040.47, 14.273,
            3381724.636, 540040.485, 14.282 };

        array source_points = array(3, 4, h_source_points).T();
        array target_points = array(3, 4, h_target_points).T();

        //归一化处理便于模型的快速迭代
        array ave_src = mean(source_points,0);
        array ave_tar = mean(target_points,0);
        source_points -= tile(ave_src,4,1,1,1);
        target_points -= tile(ave_tar,4,1,1,1);

        timer::start();
        // 当七参数的误差值之和大于1e - 10时,迭代运算得到更精确的结果
        array W, b, qxx;
        while ((sum)(abs(parameters)).scalar<double>() > 1e-10)
        {
            W = points2W(source_points, Args);
            b = points2b(source_points, target_points, Args);
            qxx = inverse(matmul(W.T(), W));
            parameters = matmul(matmul(qxx, W.T()), b);
            Args += parameters;
        }

        //af_print(parameters); 
        std::cout << "七参数输出: " << std::endl;
        af_print(Args);

        // 检查点坐标
        double hsource_test_points[3] = { 3381402.058, 395657.940, 32.728 };
        double htarget_test_points[3] = { 3380972.424, 539704.811, 13.665 };

        array source_test_points(1, 3, hsource_test_points);
        array target_test_points(1, 3, htarget_test_points);

        // 归一化处理
        source_test_points = source_test_points - ave_src;

        // 单位权标准差,即所得模型的坐标精度
        double sigma0 = (sqrt)(sum(b * b) / 2).scalar<double>();
        // 参数标准差,即所得模型的七参数精度
        array sigmax = sigma0 * (sqrt)(diag(qxx));
 
        double x, y, z;
        x = source_test_points(0).scalar<double>(); 
        y = source_test_points(1).scalar<double>(); 
        z = source_test_points(2).scalar<double>();
        array p_test = ordinationConvert(x, y, z, Args) + ave_tar;

        std::cout << "单位权中误差: " << sigma0 << std::endl;

        std::cout << "参数中误差:" << std::endl;
        af_print(sigmax);
        std::cout << "模型预测结果: " << std::endl;
        af_print(p_test);
        std::cout << "真实结果: " << std::endl;
        af_print(target_test_points);
        std::cout << "消耗时间: " << timer::stop() <<" s" << std::endl;
    }
    catch (af::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
}

结果:

七参数输出:
Args
[7 1 1 1]
    0.0000
    0.0000
    0.0000
   -0.0000
    0.0002
   -0.0717
   -0.2149

单位权中误差: 162.711
参数中误差:
sigmax
[7 1 1 1]
   81.3557
   81.3557
   81.3557
    0.6505
    0.3111
    0.1912
    0.1497

模型预测结果:
p_test
[1 3 1 1]
3380987.5078 539711.3111    13.6542
真实结果:
target_test_points
[1 3 1 1]
3380972.4240 539704.8110    13.6650
消耗时间: 1.39431 s

参考资料:

空间坐标与投影系统系列(四):七参数转换实例 | 武汉大学CVEO小组(张晓东教授团队) (whu-cveo.com)

https://mp.weixin.qq.com/s/1VcDLRTKuAX5W-dme6nX3Q

陈宇,白征东,罗腾.基于改进的布尔沙模型的坐标转换方法[J].大地测量与地球动力学,2010,30(03):71-73+78.

### 回答1: 布尔七参数转换是一种常用的地理坐标转换方法,用于将一个地理坐标系下的点转换到另一个地理坐标系下。该转换方法是基于七个参数的线性转换模型,通过对原始坐标进行平移、旋转、尺度变换和偏移等操作实现坐标系的转换。 这七个参数包括三个平移参数(Tx、Ty和Tz)、三个旋转参数(Rx、Ry和Rz)和一个尺度参数(S)。平移参数表示原坐标系与目标坐标系之间的平移差异,旋转参数表示两个坐标系之间的旋转差异,尺度参数表示两个坐标系之间的尺度差异。 转换的过程可以表示为: X' = S(Rx(X - X0) - Ry(Y - Y0)) + Tx Y' = S(Ry(X - X0) + Rx(Y - Y0)) + Ty Z' = S(Z - Z0) + Tz 其中,(X, Y, Z)表示原始地理坐标系下的点坐标,(X', Y', Z')表示目标地理坐标系下的点坐标,(X0, Y0, Z0)表示两个坐标系之间的参考点的坐标。 布尔七参数转换c是指该转换方法的一种变种,其中的参数可以通过计算和观测得到,用于实现不同地理坐标系之间的准确转换。该转换方法广泛应用于GIS、测绘和大地测量等领域,可以有效解决坐标系统不一致导致的数据整合和分析问题。 ### 回答2: 布尔七参数转换是一种地理坐标转换方法,用于将一个椭球坐标系统中的坐标点转换到另一个椭球坐标系统中的坐标点。这个方法常用于测量地球表面的物理量,比如大地水准面、地磁场和地球形状等。 布尔七参数包括三个平移参数、三个旋转参数和一个尺度参数。平移参数表示两个椭球坐标系统之间的平移关系,旋转参数表示两个椭球坐标系统之间的旋转关系,尺度参数表示两个椭球坐标系统之间的尺度关系。 布尔七参数转换c是在六参数转换基础上增加了一个常数项,用于进一步纠正两个椭球坐标系统之间的误差。这个方法能够提高地理坐标的准确性和精度,对于需要高精度的地理测量任务非常重要。 在实际应用中,布尔七参数转换c通常通过建立一个数学模型来计算转换系数,并通过测量得到的数据进行参数求解。然后,将这些求解得到的参数应用于坐标转换公式,从而实现椭球坐标的转换。 总之,布尔七参数转换c是一种用于地理坐标转换的方法,可以提高地理坐标的准确性和精度。它在测量地球表面物理量和进行地理测量任务中有着重要的应用价值。 ### 回答3: 布尔七参数转换是一种地理坐标系统转换方法,用于将一个坐标系统的坐标转换为另一个坐标系统的坐标。这个方法主要用于测量和测绘领域。 布尔七参数转换C是基于布尔模型的一种常用转换参数,该模型通过七个参数来描述两个坐标系统之间的转换关系。这七个参数分别是平移参数dx、dy、dz,旋转参数rx、ry、rz,以及尺度参数k。 在进行布尔七参数转换时,首先需要确定两个坐标系统之间的对应关系。然后,通过获取这两个坐标系统中一系列共同的控制点的坐标值,结合计算方法,可以求得这七个参数的值。最后,利用这些参数,就可以将一个坐标系统中的坐标值转换为另一个坐标系统中的坐标值。 布尔七参数转换C广泛应用于地理信息系统、卫星定位、测绘和地形分析等领域。通过利用这种转换方法,可以实现不同坐标系统之间的数据互通和坐标转换。这对于地理信息数据的整合和分析具有重要意义,并且可以提高数据的可靠性和精准度。 总而言之,布尔七参数转换C是一种重要的地理坐标系统转换方法,通过七个参数的计算和应用,可以实现不同坐标系统之间的坐标转换,为测绘和地理信息相关领域的工作提供支持和便利。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陨星落云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值