设为首页 收藏本站
查看: 1319|回复: 0

[经验分享] 计算仿射变换六参数(Python)

[复制链接]
累计签到:2 天
连续签到:1 天
发表于 2017-5-5 06:47:46 | 显示全部楼层 |阅读模式
  做保密处理或者坐标系转换的时候经常会用到关于空间配准的问题,那么如何根据已知点对求得坐标转换的参数是一个值得研究的问题。这里用到的编程技巧不多,关键是要用到线性代数和数值分析的知识。纵观当前地图坐标保密处理或者坐标系转换的实例,其无外乎采用旋转、平移、拉伸等方式,于是数值的计算无外乎于解n个n元一次方程组,最后通过误差分析进行拟合。
  下面就是一个形如 x' = Ax + by +C; y' = Dx + Ey +F 的六参数仿射变换的数值解法,采用Python2语言。

__author__ = 'Lee'
# -*- coding: utf-8 -*-
def affine_fit(from_pts, to_pts):
q = from_pts
p = to_pts
if len(q) != len(p) or len(q) < 1:
print "原始点和目标点的个数必须相同."
return False
dim = len(q[0])  # 维度
if len(q) < dim:
print "点数小于维度."
return False
# 新建一个空的 维度 x (维度+1) 矩阵 并填满
c = [[0.0 for a in range(dim)] for i in range(dim+1)]
for j in range(dim):
for k in range(dim+1):
for i in range(len(q)):
qt = list(q) + [1]
c[k][j] += qt[k] * p[j]
# 新建一个空的 (维度+1) x (维度+1) 矩阵 并填满
Q = [[0.0 for a in range(dim)] + [0] for i in range(dim+1)]
for qi in q:
qt = list(qi) + [1]
for i in range(dim+1):
for j in range(dim+1):
Q[j] += qt * qt[j]
# 判断原始点和目标点是否共线,共线则无解. 耗时计算,如果追求效率可以不用。
# 其实就是解n个三元一次方程组
def gauss_jordan(m, eps=1.0/(10**10)):
(h, w) = (len(m), len(m[0]))
for y in range(0, h):
maxrow = y
for y2 in range(y+1, h):   
if abs(m[y2][y]) > abs(m[maxrow][y]):
maxrow = y2
(m[y], m[maxrow]) = (m[maxrow], m[y])
if abs(m[y][y]) <= eps:     
return False
for y2 in range(y+1, h):   
c = m[y2][y] / m[y][y]
for x in range(y, w):
m[y2][x] -= m[y][x] * c
for y in range(h-1, 0-1, -1):  
c = m[y][y]
for y2 in range(0, y):
for x in range(w-1, y-1, -1):
m[y2][x] -= m[y][x] * m[y2][y] / c
m[y][y] /= c
for x in range(h, w):      
m[y][x] /= c
return True

M = [Q + c for i in range(dim+1)]
if not gauss_jordan(M):
print "错误,原始点和目标点也许是共线的."
return False

class transformation:
"""对象化仿射变换."""
def To_Str(self):
res = ""
for j in range(dim):
str = "x%d' = " % j
for i in range(dim):
str +="x%d * %f + " % (i, M[j+dim+1])
str += "%f" % M[dim][j+dim+1]
res += str + "\n"
return res
def transform(self, pt):
res = [0.0 for a in range(dim)]
for j in range(dim):
for i in range(dim):
res[j] += pt * M[j+dim+1]
res[j] += M[dim][j+dim+1]
return res
return transformation()
def test():
from_pt = ((38671803.6437, 2578831.9242), (38407102.8445, 2504239.2774), (38122268.3963, 2358570.38514),
(38126455.4595, 2346827.2602), (38177232.2601, 2398763.77833), (38423567.3485, 2571733.9203),
(38636876.4495, 2543442.3694), (38754169.8762, 2662401.86536), (38410773.8815, 2558886.6518),
(38668962.0430, 2578747.6349))  # 输入点坐标对
to_pt = ((38671804.6165, 2578831.1944), (38407104.0875, 2504239.1898), (38122269.2925, 2358571.57626),
(38126456.5675, 2346826.27022), (38177232.3973, 2398762.11714), (38423565.7744, 2571735.2278),
(38636873.6217, 2543440.7216), (38754168.8662, 2662401.86101), (38410774.5621, 2558886.0921),
(38668962.5493, 2578746.94))   # 输出点坐标对
trn = affine_fit(from_pt, to_pt)
if trn:
print "转换公式:"
print trn.To_Str()
err = 0.0
for i in range(len(from_pt)):
fp = from_pt
tp = to_pt
t = trn.Transform(fp)
print ("%s => %s ~= %s" % (fp, tuple(t), tp))
err += ((tp[0] - t[0])**2 + (tp[1] - t[1])**2)**0.5
print "拟合误差 = %f" % err
if __name__ == "__main__":
test()

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-373125-1-1.html 上篇帖子: python BeautifulSoup 中文编码问题解决 下篇帖子: [转]Python字符串常用大全
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表