间接平差——四参数坐标转换模型

目录

  • 一、原理概述
  • 二、代码实现

在这里插入图片描述

爬虫网站自重。

一、原理概述

  如图1所示, x i ′ o y i ′ x_{i}'oy_{i}' xioyi代表原来的旧坐标系, x i o y i x_{i}oy_{i} xioyi代表将要转换的新坐标系, X X X轴平移参数为 x 0 x_0 x0 Y Y Y轴平移参数为 y 0 y_0 y0 ,旋转角为 α \alpha α ,比例(缩放)系数为 λ \lambda λ (图上未表示出来)。
间接平差——四参数坐标转换模型_第1张图片

图1 坐标转换示意图

  由转换示意图,可以得出关系式:
[ x i y i ] = [ x 0 y 0 ] + λ [ c o s α − s i n α s i n α c o s α ] [ x i ′ y i ′ ] (1) \left[ \begin{matrix} x_{i} \\ y_{i} \\ \end{matrix} \right]=\left[ \begin{matrix} x_0 \\ y_0 \\ \end{matrix} \right]+\lambda\left[ \begin{matrix} cos\alpha&-sin\alpha \\ sin\alpha& cos\alpha \\ \end{matrix} \right] \left[ \begin{matrix} x_{i}' \\ y_{i}' \\ \end{matrix} \right] \tag{1} [xiyi]=[x0y0]+λ[cosαsinαsinαcosα][xiyi](1)

  未知参数有四个 ( x 0 , y 0 , λ , α ) (x_0,y_0,\lambda,\alpha) (x0,y0,λ,α) ,根据以上方程组得出:必须具有2个公共点(具有两个坐标系下坐标值的点)列出四个方程式,解算四个参数。当公共点有3个或3个以上时,相当于具备多余观测值,需列立误差方程式用最小二乘原理进行平差求解参数的最或然值。将式(1)变换为纯量的形式如下:
{ x i = x 0 + λ c o s α ⋅ x i ′ − λ s i n α ⋅ y i ′ y i = y 0 + λ s i n α ⋅ x i ′ + λ c o s α ⋅ y i ′ (2) \begin{cases} x_i=x_0+\lambda cos\alpha \cdot x_{i}'-\lambda sin\alpha \cdot y_{i}'\\ y_i=y_0+\lambda sin\alpha \cdot x_{i}'+\lambda cos\alpha \cdot y_{i}'\\ \end{cases} \tag{2} {xi=x0+λcosαxiλsinαyiyi=y0+λsinαxi+λcosαyi(2)

  设两坐标系中有 n n n个公共点 ( x i , y i ) (x_i,y_i) (xi,yi) ( x i ′ , y i ′ ) , i = 1 , 2 , . . . , n (x_{i}',y_{i}'),i=1,2,...,n (xi,yi),i=1,2,...,n ,令新坐标系为观测值,旧坐标系中坐标设为无误差,当 n ≥ 3 n\geq3 n3时,则可列误差方程为:
[ v x 1 v y 1 ⋮ v x n v y n ] = [ 1 0 x 1 ′ − y 1 ′ 0 1 y 1 ′ x 1 ′ ⋮ ⋮ ⋮ ⋮ 1 0 x n ′ − y n ′ 0 1 y n ′ x n ′ ] [ x 0 ^ y 0 ^ λ c o s α ^ ^ λ s i n α ^ ^ ] − [ x 1 y 1 ⋮ x n y n ] (3) \left[ \begin{matrix} v_{x_1} \\ v_{y_1} \\ \vdots\\ v_{x_n} \\ v_{y_n} \\ \end{matrix} \right]=\left[ \begin{matrix} 1&0&x_{1}'&-y_{1}' \\ 0&1&y_{1}'&x_{1}' \\ \vdots&\vdots&\vdots&\vdots\\ 1&0&x_{n}'&-y_{n}' \\ 0&1&y_{n}'&x_{n}' \\ \end{matrix} \right] \left[ \begin{matrix} \hat{x_0} \\ \hat{y_0} \\ \hat{\lambda cos \hat{\alpha}} \\ \hat{\lambda sin \hat{\alpha}} \\ \end{matrix} \right]- \left[ \begin{matrix} x_1 \\ y_1 \\ \vdots \\ x_n \\ y_n \\ \end{matrix} \right] \tag{3} vx1vy1vxnvyn = 10100101x1y1xnyny1x1ynxn x0^y0^λcosα^^λsinα^^ x1y1xnyn (3)


V = B x ^ − l (4) V=B\hat{x}-l\tag{4} V=Bx^l(4)

{ l x = x i − ( x 0 + λ c o s α ⋅ x i ′ − λ s i n α ⋅ y i ′ ) l y = y i − ( y 0 + λ s i n α ⋅ x i ′ + λ c o s α ⋅ y i ′ ) (5) \begin{cases} l_x=x_i-(x_0+\lambda cos\alpha \cdot x_{i}'-\lambda sin\alpha \cdot y_{i}')\\ l_y=y_i-(y_0+\lambda sin\alpha \cdot x_{i}'+\lambda cos\alpha \cdot y_{i}')\\ \end{cases} \tag{5} {lx=xi(x0+λcosαxiλsinαyi)ly=yi(y0+λsinαxi+λcosαyi)(5)

  根据最小二乘原理 V T P V = m i n V^TPV=min VTPV=min 可得法方程:
B T B x ^ − B T l = 0 (6) B^TB\hat{x}-B^Tl=0\tag{6} BTBx^BTl=0(6)

  解法方程:
x ^ = ( B T B ) − 1 B T l = N B B − 1 W (7) \hat{x}=(B^TB)^{-1}B^Tl=N_{BB}^{-1}W\tag{7} x^=(BTB)1BTl=NBB1W(7)
X ^ = X 0 + x ^ (8) \hat{X}=X^0+\hat{x}\tag{8} X^=X0+x^(8)
式中: X 0 = [ x 0 , y 0 , λ c o s α , λ s i n α ] T = [ 0 , 0 , 1 , 0 ] T X^0=[x_0,y_0,\lambda cos \alpha,\lambda sin \alpha]^T=[0,0,1,0]^T X0=[x0,y0,λcosα,λsinα]T=[0,0,1,0]T
可求得参数 x 0 = X ^ [ 1 ] , y 0 = X ^ [ 2 ] , α = a r c t a n X ^ [ 4 ] X ^ [ 3 ] , λ = X ^ [ 3 ] 2 + X ^ [ 4 ] 2 x_0=\hat{X}[1],y_0=\hat{X}[2],\alpha=arctan\frac{\hat{X}[4]}{\hat{X}[3]},\lambda=\sqrt{\hat{X}[3]^2+\hat{X}[4]^2} x0=X^[1]y0=X^[2],α=arctanX^[3]X^[4],λ=X^[3]2+X^[4]2

二、代码实现

import numpy as np


def four_parameter_coordinate_conversion(old_pts, new_pts):
    """
    四参数坐标转换
    :param old_pts: 旧坐标系
    :param new_pts: 新坐标系
    :return: 四参数计算结果
    """
    if old_pts.shape[0] != new_pts.shape[0]:
        return False
    if old_pts.shape[0] < 3:
        return False
    n = old_pts.shape[0]  # 点的个数
    B = np.zeros((n * 2, 4))  # 矩阵B
    L = np.zeros((n * 2, 1))  # 矩阵L
    X = np.ones((4, 1))  # 解X
    deltX = np.ones((4, 1))  # 迭代增量deltX
    # 四参数的初始值
    x0 = 0.0
    y0 = 0.0
    lamda = 1.0
    alpha = 0.0
    X[0] = x0
    X[1] = y0
    X[2] = lamda * np.cos(alpha)
    X[3] = lamda * np.sin(alpha)
    # 构建计算所需矩阵
    for i in range(0, n):
        B[2 * i, 0] = 1
        B[2 * i, 1] = 0
        B[2 * i, 0] = old_pts[i].x
        B[2 * i, 1] = -old_pts[i].y
        B[2 * i + 1, 0] = 0
        B[2 * i + 1, 1] = 1
        B[2 * i + 1, 0] = old_pts[i].y
        B[2 * i + 1, 1] = old_pts[i].x

        L[2 * i] = new_pts[i].x
        L[2 * i + 1] = new_pts[i].y
    # 迭代计算
    count = 0
    while np.linalg.norm(deltX) > 0.0001:
        l = L - B.dot(X)
        NBB = B.T.dot(B)
        W = B.T.dot(l)
        deltX = np.linalg.inv(NBB).dot(W)

        X += deltX
        count += 1
        if count >= 10:
            break
    print("迭代次数:", count)

    return X

你可能感兴趣的:(CloudCompare,开发语言,算法,计算机视觉,矩阵,线性代数,人工智能)