简单2D转换的结果不正确

时间:2019-07-16 15:14:51

标签: python affinetransform

我正在尝试使用nudged软件包进行2D转换。

代码非常简单:

import nudged

# Domain data
x_d = [2538.87, 1294.42, 3002.49, 2591.56, 2881.37, 891.906, 1041.24, 2740.13, 1928.55, 3335.12, 3771.76, 1655.0, 696.772, 583.242, 2313.95, 2422.2]
y_d = [2501.89, 4072.37, 2732.65, 2897.21, 808.969, 1760.97, 992.531, 1647.57, 2407.18, 2868.68, 724.832, 1938.11, 1487.66, 1219.14, 672.898, 145.059]

# Range data
x_r = [3.86551776277075, 3.69693290266126, 3.929110096606081, 3.8731112887391532, 3.9115924127798536, 3.6388068074815862, 3.6590261077461577, 3.892482104449016, 3.781816183438835, 3.97464058821231, 4.033173444601999, 3.743901522907265, 3.6117470568340906, 3.5959585708147728, 3.8338853650390945, 3.8487836817639334]
y_r = [1.6816478101135388, 1.8732008327428353, 1.7089144628920678, 1.729386055302033, 1.4767657611559102, 1.5933812675900505, 1.5003232598807479, 1.5781629182153942, 1.670867507106891, 1.7248363641300841, 1.4654588884234485, 1.6143557610354264, 1.5603626129237362, 1.5278835570641824, 1.4609066190929916, 1.397111300807424]

# Random domain data
x, y = np.random.uniform(0., 4000., (2, 1000))

# Define domain and range points
dom, ran = (x_d, y_d), (x_r, y_r)

# Obtain transformation dom --> ran
trans = nudged.estimate(dom, ran)

# Apply the transformation to the (x, y) points
x_t, y_t = trans.transform((x, y))

其中(x_d, y_d)(x_r, y_r)是1到1相关的“域”和“范围”点,而(x, y)(x_d, y_d)(域)中的所有点我要转换为(x_r, y_r)(范围)系统的系统。

这是我得到的结果:

enter image description here

其中:

trans.get_matrix()
[[-0.0006459232439068067, -0.0007947429558548157, 6.534164085946009], [0.0007947429558548157, -0.0006459232439068067, 2.515279819707991], [0, 0, 1]]
trans.get_rotation()
2.2532603497070713
trans.get_scale()
0.0010241255796531702
trans.get_translation()
[6.534164085946009, 2.515279819707991]

这是最终的转换后的dom值,其原始ran点被覆盖:

enter image description here

这显然是不对的,我无法弄清楚自己在做错什么。

1 个答案:

答案 0 :(得分:1)

我能够找出您的问题。简而言之,nudge的符号有些问题,文献记载不充分。

estimate函数接受坐标对列表。您必须有效地转置domran才能使它起作用。我建议要么切换到numpy数组,要么使用list(map(list, zip(...)))进行转置。

Transform.transfom方法非常严格,要求内部对的类型为list。不是tuple,不是任何其他序列,而是特别是list。您尝试致电trans.transform((x, y))仅是靠运气。 transform评估到第一个元素不是列表,并尝试将(x, y)转换为一对整数。幸运的是,numpy运算符是矢量化的,因此您可以将整个数组作为一个单元处理。

这是您的代码的有效版本,主要使用python生成正确的图:

x_d = [2538.87, 1294.42, 3002.49, 2591.56, 2881.37, 891.906, 1041.24, 2740.13, 1928.55, 3335.12, 3771.76, 1655.0, 696.772, 583.242, 2313.95, 2422.2]
y_d = [2501.89, 4072.37, 2732.65, 2897.21, 808.969, 1760.97, 992.531, 1647.57, 2407.18, 2868.68, 724.832, 1938.11, 1487.66, 1219.14, 672.898, 145.059]

# Range data
x_r = [3.86551776277075, 3.69693290266126, 3.929110096606081, 3.8731112887391532, 3.9115924127798536, 3.6388068074815862, 3.6590261077461577, 3.892482104449016, 3.781816183438835, 3.97464058821231, 4.033173444601999, 3.743901522907265, 3.6117470568340906, 3.5959585708147728, 3.8338853650390945, 3.8487836817639334]
y_r = [1.6816478101135388, 1.8732008327428353, 1.7089144628920678, 1.729386055302033, 1.4767657611559102, 1.5933812675900505, 1.5003232598807479, 1.5781629182153942, 1.670867507106891, 1.7248363641300841, 1.4654588884234485, 1.6143557610354264, 1.5603626129237362, 1.5278835570641824, 1.4609066190929916, 1.397111300807424]

# Random domain data
uni = np.random.uniform(0., 4000., (2, 1000))

# Define domain and range points
dom = list(map(list, zip(x_d, y_d)))
ran = list(map(list, zip(x_r, y_r)))

# Obtain transformation dom --> ran
trans = estimate(dom, ran)

# Apply the transformation to the (x, y) points
tra = trans.transform(uni)

fig, ax = plt.subplots(2, 2)
ax[0][0].scatter(x_d, y_d)
ax[0][0].set_title('dom')

ax[0][1].scatter(x_r, y_r)
ax[0][1].set_title('ran')

ax[1][0].scatter(*uni)
ax[1][1].scatter(*tra) 

我以uni离开了您,因为我不想将随机值数组转换为嵌套列表。结果图如下:

enter image description here

我的总体建议是根据这些发现向nudge库提交许多错误报告。