347 lines
9.7 KiB
Python
Raw Normal View History

import numpy as np
import math
from touying.ImageReproject_python.common_types import POS, ImgEO
# from common_types import POS, ImgEO
class DPAL:
"""数字摄影测量算法库(Digital Photogrammetry Algorithm Library)"""
@staticmethod
def convert_pos_r2_map_r(pos, north_angle, r=None):
"""将导航坐标系下的旋转矩阵转换为投影坐标系下的旋转矩阵
Args:
pos: POS对象包含位置和姿态信息
north_angle: 子午线收敛角(弧度)
r: 输出旋转矩阵
Returns:
旋转矩阵
"""
# 计算导航坐标系下的旋转矩阵
r_pos = DPAL.computing_r_mat_pos(pos)
# 子午线收敛角旋转矩阵
mt = np.array([
[math.cos(-north_angle), math.sin(-north_angle), 0.0],
[-math.sin(-north_angle), math.cos(-north_angle), 0.0],
[0.0, 0.0, 1.0]
])
# 应用子午线收敛角旋转
r_pos = np.matmul(r_pos, mt)
# 坐标系转换矩阵
t = np.array([
[0.0, 1.0, 0.0],
[1.0, 0.0, 0.0],
[0.0, 0.0, -1.0]
])
# 计算最终旋转矩阵
if r is None:
r = np.matmul(t, np.matmul(r_pos, t))
else:
r[:] = np.matmul(t, np.matmul(r_pos, t))
return r
@staticmethod
def pos2map_eo(pos, north_angle, sys_er_r, eo, angle_type=0):
"""将POS转换为投影坐标系下的EO
Args:
pos: POS对象包含位置和姿态信息
north_angle: 子午线收敛角(弧度)
sys_er_r: 系统误差旋转矩阵
eo: 输出的EO对象
angle_type: 角度类型0为国际转角1为中国转角
Returns:
None
"""
eo.name = pos.name
eo.Xs = pos.L
eo.Ys = pos.B
eo.Zs = pos.H
# 计算旋转矩阵
r = DPAL.convert_pos_r2_map_r(pos, north_angle)
# 应用系统误差
r = np.matmul(sys_er_r, r)
# 根据角度类型计算外方位元素
if angle_type == 0:
DPAL.rotation2_angle(eo, r)
else:
DPAL.rotation2_angle_cn(eo, r)
@staticmethod
def rotation2_angle(eo, r):
"""从旋转矩阵分解出外方位角元素(国际转角系统)
Args:
eo: 输出的EO对象
r: 旋转矩阵
Returns:
None
"""
eo.omega = math.atan2(-r[2, 1], r[2, 2])
eo.phi = math.asin(r[2, 0])
eo.kappa = math.atan2(-r[1, 0], r[0, 0])
@staticmethod
def rotation2_angle_cn(eo_cn, r):
"""从旋转矩阵分解出外方位角元素(中国转角系统)
Args:
eo_cn: 输出的EO对象
r: 旋转矩阵
Returns:
None
"""
eo_cn.phi = math.atan2(-r[2, 0], r[2, 2])
eo_cn.omega = math.asin(-r[2, 1])
eo_cn.kappa = math.atan2(r[0, 1], r[1, 1])
@staticmethod
def eo2eo_cn(eo, eo_cn):
"""国际转角系统的EO转换为中国转角系统的EO
Args:
eo: 国际转角系统的EO对象
eo_cn: 输出的中国转角系统的EO对象
Returns:
None
"""
eo_cn.Xs = eo.Xs
eo_cn.Ys = eo.Ys
eo_cn.Zs = eo.Zs
# 计算旋转矩阵
r = DPAL.computing_r_mat(eo)
# 分解为中国转角
DPAL.rotation2_angle_cn(eo_cn, r)
@staticmethod
def eo_cn2eo(eo_cn, eo):
"""中国转角系统的EO转换为国际转角系统的EO
Args:
eo_cn: 中国转角系统的EO对象
eo: 输出的国际转角系统的EO对象
Returns:
None
"""
eo.Xs = eo_cn.Xs
eo.Ys = eo_cn.Ys
eo.Zs = eo_cn.Zs
# 计算旋转矩阵
r = DPAL.computing_r_mat_cn(eo_cn)
# 分解为国际转角
DPAL.rotation2_angle(eo, r)
@staticmethod
def eo_cn2eo_zyx(eo_cn, eo_zyx):
"""中国转角系统的EO转换为顺序为zyx转角的EO
Args:
eo_cn: 中国转角系统的EO对象
eo_zyx: 输出的zyx转角系统的EO对象
Returns:
None
"""
eo_zyx.Xs = eo_cn.Xs
eo_zyx.Ys = eo_cn.Ys
eo_zyx.Zs = eo_cn.Zs
# 计算旋转矩阵
r = DPAL.computing_r_mat_cn(eo_cn)
rt = r.T
# 分解为zyx转角
eo_temp = ImgEO()
DPAL.rotation2_angle(eo_temp, rt)
eo_zyx.kappa = -eo_temp.kappa
eo_zyx.phi = -eo_temp.phi
eo_zyx.omega = -eo_temp.omega
@staticmethod
def eo2eo_zyx(eo, eo_zyx):
"""国际转角系统的EO转换为顺序为zyx转角的EO
Args:
eo: 国际转角系统的EO对象
eo_zyx: 输出的zyx转角系统的EO对象
Returns:
None
"""
eo_zyx.Xs = eo.Xs
eo_zyx.Ys = eo.Ys
eo_zyx.Zs = eo.Zs
# 计算旋转矩阵
r = DPAL.computing_r_mat(eo)
rt = r.T
# 分解为zyx转角
eo_temp = ImgEO()
DPAL.rotation2_angle(eo_temp, rt)
eo_zyx.kappa = -eo_temp.kappa
eo_zyx.phi = -eo_temp.phi
eo_zyx.omega = -eo_temp.omega
@staticmethod
def computing_k_mat(io, k=None, k_type=0):
"""根据内方位元素计算内参矩阵
Args:
io: 内方位元素对象
k: 输出内参矩阵
k_type: 内参类型0为左上角为原点向右X向下Y非0为中心为原点向右X向下Y
Returns:
内参矩阵
"""
if k_type != 0:
k_mat = np.array([
[-io.f, 0.0, 0.0],
[0.0, -io.f, 0.0],
[0.0, 0.0, 1.0]
])
else:
k_mat = np.array([
[-io.f, 0.0, io.cx],
[0.0, io.f, io.cy],
[0.0, 0.0, 1.0]
])
if k is None:
return k_mat
else:
k[:] = k_mat
return k
@staticmethod
def computing_r_mat_pos(pos, r_pos=None):
"""根据POS元素计算导航坐标系下的旋转矩阵
Args:
pos: POS对象
r_pos: 输出旋转矩阵
Returns:
旋转矩阵
"""
# 计算各轴旋转矩阵
r_roll = np.array([
[1.0, 0.0, 0.0],
[0.0, math.cos(pos.roll), math.sin(pos.roll)],
[0.0, -math.sin(pos.roll), math.cos(pos.roll)]
])
r_pitch = np.array([
[math.cos(pos.pitch), 0.0, -math.sin(pos.pitch)],
[0.0, 1.0, 0.0],
[math.sin(pos.pitch), 0.0, math.cos(pos.pitch)]
])
r_yaw = np.array([
[math.cos(pos.yaw), math.sin(pos.yaw), 0.0],
[-math.sin(pos.yaw), math.cos(pos.yaw), 0.0],
[0.0, 0.0, 1.0]
])
# 计算最终旋转矩阵
if r_pos is None:
return np.matmul(r_roll, np.matmul(r_pitch, r_yaw))
else:
r_pos[:] = np.matmul(r_roll, np.matmul(r_pitch, r_yaw))
return r_pos
@staticmethod
def computing_r_mat(eo, r=None):
"""根据外方位元素(国际转角)计算旋转矩阵
Args:
eo: 外方位元素对象
r: 输出旋转矩阵
Returns:
旋转矩阵
"""
# 计算各轴旋转矩阵
r_omega = np.array([
[1.0, 0.0, 0.0],
[0.0, math.cos(eo.omega), math.sin(eo.omega)],
[0.0, -math.sin(eo.omega), math.cos(eo.omega)]
])
r_phi = np.array([
[math.cos(eo.phi), 0.0, -math.sin(eo.phi)],
[0.0, 1.0, 0.0],
[math.sin(eo.phi), 0.0, math.cos(eo.phi)]
])
r_kappa = np.array([
[math.cos(eo.kappa), math.sin(eo.kappa), 0.0],
[-math.sin(eo.kappa), math.cos(eo.kappa), 0.0],
[0.0, 0.0, 1.0]
])
# 计算最终旋转矩阵
if r is None:
return np.matmul(r_kappa, np.matmul(r_phi, r_omega))
else:
r[:] = np.matmul(r_kappa, np.matmul(r_phi, r_omega))
return r
@staticmethod
def computing_r_mat_cn(eo_cn, r=None):
"""根据外方位元素(中国转角)计算旋转矩阵
Args:
eo_cn: 外方位元素对象
r: 输出旋转矩阵
Returns:
旋转矩阵
"""
# 计算各轴旋转矩阵
r_phi = np.array([
[math.cos(eo_cn.phi), 0.0, math.sin(eo_cn.phi)],
[0.0, 1.0, 0.0],
[-math.sin(eo_cn.phi), 0.0, math.cos(eo_cn.phi)]
])
r_omega = np.array([
[1.0, 0.0, 0.0],
[0.0, math.cos(eo_cn.omega), math.sin(eo_cn.omega)],
[0.0, -math.sin(eo_cn.omega), math.cos(eo_cn.omega)]
])
r_kappa = np.array([
[math.cos(eo_cn.kappa), math.sin(eo_cn.kappa), 0.0],
[-math.sin(eo_cn.kappa), math.cos(eo_cn.kappa), 0.0],
[0.0, 0.0, 1.0]
])
# 计算最终旋转矩阵
if r is None:
return np.matmul(r_kappa, np.matmul(r_omega, r_phi))
else:
r[:] = np.matmul(r_kappa, np.matmul(r_omega, r_phi))
return r