347 lines
9.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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