我试图从结果中扣除2d转换参数。
为未知x - y坐标系下的大量样本,以及它们在WGS84(经度、纬度)中的对应值。由于面积很小,我们可以假设目标系统也是平坦的。
遗憾的是,我不知道哪个顺序的规模,旋转,翻译被使用,我甚至不确定是否有1或2个翻译。
我试着创建一个冗长的方程系统,但它最终对我来说太复杂了。基础几何也让我失望,因为变换的顺序是未知的,我必须检查每一个可能的组合顺序。
有系统的方法来解决这个问题吗?
计算比例因子很容易,只要选择任意两点,在你的X-Y空间和你的WGS84空间中找到它们之间的距离,它们的比值就是你的比例因子。
旋转和平移有点棘手,但当你知道应用任意数量的旋转或平移(仅在二维中!)的结果可以简化为围绕某个未知点的某个未知角度的单个旋转时,就不会那么困难了。
突然你有N个点来确定3个未知数,旋转轴(x和y坐标)和旋转角度。
计算旋转是这样的:
Pr = R*(Pxy - Paxis_xy) + Paxis_xy
Pr
是X-Y空间中的旋转点,然后需要转换为WGS84空间(如果坐标系的轴不同)。R
是我们熟悉的旋转矩阵,取决于旋转角度。Pxy
是X-Y空间中未旋转的点。Paxis_xy
为X-Y空间的旋转轴。
要真正找到3个未知数,你需要取消你的WGS84点的比例(或等效地缩放你的X-Y点),并移动你的点,使两个坐标系具有相同的原点。
首先,求旋转角度:取两对对应的点P1, P1'
和P2, P2'
,写出
P1' = R(P1-A) + A
P2' = R(P2-A) + A
,我交换了A = Paxis_xy
为简洁。两个方程相减得到:
P2'-P1' = R(P2-P1)
B = R * C
Bx = cos(a) * Cx - sin(a) * Cy
By = cos(a) * Cx + sin(a) * Cy
By + Bx = 2 * cos(a) * Cx
(By + Bx) / (2 * Cx) = cos(a)
...
(By - Bx) / (2 * Cy) = sin(a)
a = atan2(sin(a), cos(a)) <-- to get the right quadrant
你有你的角度,你也可以做一个快速检查cos(a) * cos(a) + sin(a) * sin(a) == 1
,以确保你得到的所有计算都是正确的,或者你的系统真的是一个保持方向的等距(只包括平移和旋转)。
既然我们知道a
,我们就知道R
,所以要找到A
,我们可以这样做:
P1` = R(P1-A) + A
P1' - R*P1 = (I-R)A
A = (inverse(I-R)) * (P1' - R*P1)
,其中2x2矩阵的逆很容易。
EDIT:上面有一个错误,或者更具体地说,是一个需要单独处理的情况。
有一种平移和旋转的组合不会减少为单一的旋转,那就是单一的平移。你可以从固定点的角度来考虑(有多少点在操作后保持不变)。
平移没有固定点(所有的点都改变了),旋转有一个固定点(轴不改变)。事实证明,两次旋转留下一个不动点,一次平移和一次旋转留下一个不动点,这(通过一点证明,不动点的数量告诉你所执行的操作)是这些任意组合导致一次旋转的原因。
这对你来说意味着,如果你的角度是0
,那么使用上面的方法也会得到A = 0
,这可能是不正确的。在本例中,您必须执行A = P1' - P1
。
如果我理解正确的话,你有n个点(X1,Y1),…,(Xn,Yn),对应的点,比如(X1,Y1),…,(Xn,Yn)在另一个坐标系中,前者应该是由后者通过旋转,缩放和平移得到的。
请注意,该数据不确定旋转/缩放的固定点,也不确定操作"应该"应用的顺序。另一方面,如果你事先知道这些或任意选择它们,你会找到一个旋转、平移和缩放因子来转换数据。
例如,你可以选择一个任意点,比如p0 = [X1, Y1]T(列向量)作为旋转的固定点&将其坐标与其他两个点的坐标进行缩放并相减,得到p2 = [X2-X1, Y2-Y1]T, p3 = [X3 -Y1]T。也列向量q <子> 2子> 2 子> - x <子> 1,y <子> 2 子>是<子> 1 子>]<一口> T 一同晚餐,问<子> 3 子> = [x <子> 3 子> - x 一口>子><子> 1,y <子> 3 子>是<子> 1 子>]<一口> T 吃饭。现在[p2 p3] = A*[q2 q3],其中A是表示旋转标度的未知2x2矩阵。你可以解它(除非你运气不好,选择了简并点)为A = [p2 p3] * [q2 q3]-1其中-1表示矩阵逆(2x2矩阵[q2 q3])。现在,如果坐标系之间的变换确实是旋转缩放平移,那么所有的点都应满足Pk = a * (Qk-q0) + P 0,其中Pk =[Xk, Yk]T, Qk =[Xk, Yk]T, Q 0=[X 1, Y 1]T, k=1,…,n.一口>子>
如果你愿意,你可以很容易地从A的分量中确定缩放和旋转参数,或者组合b = -A * q0 + p0得到p k = A* q k + b。
上述方法对噪声和简并点的选取反应不佳。如果有必要,这可以通过应用主成分分析来解决,如果有MATLAB或其他线性代数工具,这也只是几行代码。
当然。假设这是一个仿射变换矩阵。你需要3个有序点对应3个不同的其他有序点你可以计算变换矩阵
首先使用下面的方程,它给出了将(0,0), (0,1) and (1,0)
映射到三个有序点(x1, y1), (x2,y2), and (x4,y4)
的矩阵,即:
Matrix(
a = x4 - x1,
b = x2 - x1,
c = x1,
d = y4 - y1,
e = y2 - y1,
f = y1,
)
这给了我们一个矩阵,将(0,0), (0,1), (1,0)
映射到你的点a1, a2, a4
。
然后对点b1, b2, b4
的另一个矩阵进行同样的计算。
现在我们有两个矩阵将我们的点转换成相同的点。我们称它们为矩阵T
和R
。如果我们想把点从一个映射到另一个,只要M = T * ~R
我们做常规的矩阵乘法~
告诉我们对矩阵求逆。所以我们从点开始:
a1, a2, a4
——(via T)——>(0,0), (0,1), (1,0)
—(via ~R)—>b1, b2, b4.
通过T * ~R
我们有M使得:
a1, a2, a4
——(via M)——>b1, b2, b4.
例如,如果你有4个点映射到其他4个点,数学就会变得更难。
映射点(0,0), (0,1), (1,1), (1,0)
i = 1
try:
j = (y1 - y2 + y3 - y4) / (y2 - y3)
k = (x1 - x2 + x3 - x4) / (x4 - x3)
m = (y4 - y3) / (y2 - y3)
n = (x2 - x3) / (x4 - x3)
h = i * (j - k * m) / (1 - m * n)
g = i * (k - j * n) / (1 - m * n)
except ZeroDivisionError:
h = 0.0
g = 0.0
c = x1 * i
f = y1 * i
a = x4 * (g + i) - x1 * i
b = x2 * (h + i) - x1 * i
d = y4 * (g + i) - y1 * i
e = y2 * (h + i) - y1 * i
如果矩阵是仿射的,则g
和h
的值为0。但是,它会导致除以0的误差。i
是为了完整性而给出的,可能应该将其设置为1并删除。它只缩放9x9矩阵的值。这里的不同之处在于透视/翘曲需要3x3矩阵(之前平行的线现在可以有交叉点)。如果您想使用第4点(p3
)作为完整性检查:
这将映射到点p3将映射到点(1,1)
x3 = x4 - x1 + x2
y3 = y4 - y1 + y2
如果这些方程是正确的,那么你的p3值位于矩阵为仿射所需的位置,如果它不在那里,那么上面的数学将给你的矩阵仍然使它位于你的第四个点。