我需要帮助,
我从服务器接收单应性,所以我想将此单应性标准化为我的应用程序的坐标系,当我尝试用坐标表示对象时,服务器应用程序生成接下来的4个点:
收到[96.629539,217.31934; 97.289948,167.21941; 145.69249,168.28044; 145.69638,219.84604]
我的应用程序生成接下来的4个点:
当地[126.0098,55.600437; 262.39163,53.98035; 259.41382,195.34763; 121.48138,184.95235]
我用图形表示这一点,R(收到),P(本地)
看起来生成的正方形是旋转和缩放的,所以我想知道是否有任何方法将此旋转应用于服务器单应性,以便能够具有与我的应用程序单应性相同的单应性
谢谢,我需要更多信息,请问我。
非常感谢您的快速答案,最后我使用其他近似,就像从服务器获取点并使用findhomography获得逆单应性一样简单。
homography = findHomography(srcPoints,dstPoints,match_mask,RANSAC,10);
感谢!!!
答案 0 :(得分:4)
我想我想出来了。下面是你的两个单应性的更准确的情节。蓝色是“接收”的单应性,红色是“本地”单应性。
您可以使用OpenCV函数getAffineTransform来计算与3个点对相关的仿射变换(我必须重新组织您的点对,因为它们的顺序错误)。我在numpy中运行如下:
r = array([[97.289948, 167.21941], [96.629539, 217.31934], [145.69638, 219.84604]], np.float32)
l = array([[126.0098, 55.600437], [121.48138, 184.95235], [259.41382, 195.34763]], np.float32)
A = cv2.getAffineTransform(r, l)
这给了我们以下的仿射关系:
array([[ 2.81385763e+00, -5.32961421e-02, -1.38838108e+02],
[ 7.88519054e-02, 2.58291747e+00, -3.83984986e+02]])
我将其应用回r
,看看我是否可以l
确保其效果如下:
# split affine warp into rotation, scale, and/or shear + translation matrix
T = mat(A[:, 2]).T
matrix([[-138.83810801],
[-383.98498637]])
A = mat(A[:, 0:2])
matrix([[ 2.81385763, -0.05329614],
[ 0.07885191, 2.58291747]])
# apply warp to r to get l
r = mat(r).T
A*r + T
# gives
matrix([[ 126.00980377, 121.48137665, 259.41381836],
[ 55.60043716, 184.9523468 , 195.34762573]])
# which equals
l = mat(l).T
matrix([[ 126.00980377, 121.48137665, 259.41381836],
[ 55.60043716, 184.9523468 , 195.34762573]], dtype=float32)
另外值得注意的是,您可以使用OpenCV函数getPerspectiveTransform生成Markus Jarderot
所示的透视变换。
希望有所帮助!
答案 1 :(得分:2)
如果您将点和转换插入Maple,您可以很快得到结果。
> with(LinearAlgebra);
> # The server coordinates
pa := [[96.629539, 217.31934], [97.289948, 167.21941], [145.69249, 168.28044],
[145.69638, 219.84604]]:
> # The local coordiantes
pb := [[126.0098, 55.600437], [262.39163, 53.98035], [259.41382, 195.34763],
[121.48138, 184.95235]]:
> # The placeholder variables for the transformation (last one is '1', because it
# is scale-invariant)
T := [seq]([seq](`if`(i = 3 and j = 3, 1, t[i, j]), j = 1 .. 3), i = 1 .. 3):
V := convert(map(op, T)[1 .. -2], set):
> # Transformation function (Matrix multiplication + divide with 3rd coordinate)
trans := (p, T) -> [
(T[1, 1]*p[1]+T[1, 2]*p[2]+T[1, 3])/(T[3, 1]*p[1]+T[3, 2]*p[2]+T[3, 3]),
(T[2, 1]*p[1]+T[2, 2]*p[2]+T[2, 3])/(T[3, 1]*p[1]+T[3, 2]*p[2]+T[3, 3])
]:
> # Transform pa, and construct the equation system
pat := map(trans, pa, T):
eqs := {op}(zip((p1, p2) -> op(zip(`=`, p1, p2)), pat, pb)):
> # Solve for the transform variables
sol := solve(eqs, V):
> # Populate the transform
eval(T, sol);
<强>输出:强>
[[ .1076044020, -3.957029830, 1074.517140 ],
[ 4.795375318, .3064507355, -430.7044862 ],
[ 0.3875626264e-3, 0.3441632491e-2, 1 ]]
要使用此功能,请将其与服务器点相乘T * <x, y, 1>
。
void ServerToLocal(double serverX, double serverY, double *localX, double *localY)
{
double w;
w = 0.3875626264e-3 * serverX + 0.3441632491e-2 * serverY + 1.0;
*localX = (.1076044020 * serverX - 3.957029830 * serverY + 1074.517140) / w;
*localY = (4.795375318 * serverX + .3064507355 * serverY - 430.7044862) / w;
}
可以在http://alumni.media.mit.edu/~cwren/interpolator/
阅读另一种方法这个可以用C语言编写,给定一个合理的线性代数库。