移动一个像素的坐标

Shifting the coordinates of one pixel

我正在尝试制作一个算法原型来查找盘子上球的坐标,我想让它尽可能高效,因为我必须在 FPGA 中实现它。球和盘子的图片并不总是在同一方向,所以我需要根据盘子角的坐标移动球的中心坐标。

要理解我的意思,请参见下图,其中白色 sheet 代表盘子。

现在我已经找到了确定球在图片上的坐标,以及图中盘子角坐标的方法,但是我想知道球在盘子上的位置.

我尝试用 getPerspectiveTransform() 和 wrapPerspective() 做一些事情并且它起作用了,但这涉及很多矩阵计算,我认为当我只想移动一个像素的坐标时这有点过分了(球的中心)。

关于如何确定球在盘子上的中心像素的坐标,你知道更有效的方法吗?

Opencv 的 getPerspectiveTransform returns 一个 3x3 变换矩阵。 warpPerspective 所做的就是获取每个像素的 x,y 坐标并将其与该矩阵相乘(增加 [x,y] -> [x,y,1])。

如果你只想修改一个点 P [x,y,1],那么给定变换矩阵 M,你可以使用以下方法变换点:

numpy.matmul(M, P);

这里有一些示例代码展示了它是如何工作的。我们制作了四个示例点并表明使用 matmul 对它们进行变形等同于使用 warpPerspective。

import cv2
import numpy as np

# test points
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]]);
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]]);

# transformation
M = cv2.getPerspectiveTransform(pts1,pts2);

# if our method works, then transforming each pts1 with M
# should result in pts2
transformed_points = [];
for p in pts1:
    # augment point
    point = np.array([p[0], p[1], 1], dtype = np.float32);

    # multiply
    transformed = np.matmul(M, point);

    # unpack and clean up
    x, y, scale = transformed;
    x /= scale;
    y /= scale;
    x = round(x, 5); # to clear out long floating points
    y = round(y, 5);
    transformed_points.append([x,y]);

# compare points
for a in range(len(pts2)):
    print("Target: " + str(pts2[a]));
    print("Transformed: " + str(transformed_points[a]));

我用下面post的morotspaj的答案和Matlab解决了。

ui和vi是已知的(这些等于图片的分辨率),所以我将它们填充到8x8矩阵中得到如下:

/ x0 y0  1  0  0  0     0          0    \ /m00\ /  0  \
| x1 y1  1  0  0  0 -x1*RES_H -y1*RES_H | |m01| |RES_H|
| x2 y2  1  0  0  0     0          0    | |m02| |  0  |
| x3 y3  1  0  0  0 -x3*RES_H -y3*RES_H |.|m10|=|RES_H|
|  0  0  0 x0 y0  1     0          0    | |m11| |  0  |
|  0  0  0 x1 y1  1     0          0    | |m12| |  0  |
|  0  0  0 x2 y2  1 -x2*RES_V -y2*RES_V | |m20| |RES_V|
\  0  0  0 x3 y3  1 -x3*RES_V -y3*RES_V / \m21/ \RES_V/

其中 RES_H = (640 - 1) 且 RES_V = (480 - 1)。这个等式可以看做Ax=b。我把 A 矩阵 (8x8) 和 b 向量 (8x1) 放在 Matlab 中并使用 linsolve(A,b)求解线性方程组:

syms x0 x1 x2 x3 y0 y1 y2 y3 RES_H RES_V;
A = [ x0 y0 1 0 0 0 0 0 ; x1 y1 1 0 0 0 -x1*RES_H -y1*RES_H ; x2 y2 1 0 0 0 0 0 ; x3 y3 1  0 0 0 -x3*RES_H -y3*RES_H ; 0 0 0 x0 y0 1 0 0 ; 0 0 0 x1 y1 1 0 0 ; 0 0 0 x2 y2 1 -x2*RES_V -y2*RES_V ; 0 0 0 x3 y3 1 -x3*RES_V -y3*RES_V ];
b = [ 0 ; RES_H ; 0 ; RES_H ; 0 ; 0 ; RES_V ; RES_V ];
simplify(linsolve(A,B))

结果如下:

m00 = -(RES_H*(y0 - y2)*(x0*y1 - x1*y0 - x0*y3 + x3*y0 + x1*y3 - x3*y1)*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2))/(- x0*x0*x1*y1*y2*y2 + 2*x0*x0*x1*y1*y2*y3 - x0*x0*x1*y1*y3*y3 + x0*x0*x2*y1*y1*y2 - 2*x0*x0*x2*y1*y2*y3 + x0*x0*x2*y2*y3*y3 - 2*x0*x0*x3*y1*y1*y2 + x0*x0*x3*y1*y1*y3 + 2*x0*x0*x3*y1*y2*y2 - x0*x0*x3*y2*y2*y3 + x0*x1*x1*y0*y2*y2 - 2*x0*x1*x1*y0*y2*y3 + x0*x1*x1*y0*y3*y3 - 2*x0*x1*x2*y0*y1*y3 + 2*x0*x1*x2*y0*y2*y3 + 2*x0*x1*x2*y1*y3*y3 - 2*x0*x1*x2*y2*y3*y3 + 2*x0*x1*x3*y0*y1*y2 - 2*x0*x1*x3*y0*y2*y2 - 2*x0*x1*x3*y1*y2*y3 + 2*x0*x1*x3*y2*y2*y3 - x0*x2*x2*y0*y1*y1 + 2*x0*x2*x2*y0*y1*y3 - x0*x2*x2*y0*y3*y3 + 2*x0*x2*x3*y0*y1*y1 - 2*x0*x2*x3*y0*y1*y2 - 2*x0*x2*x3*y1*y1*y3 + 2*x0*x2*x3*y1*y2*y3 - x0*x3*x3*y0*y1*y1 + x0*x3*x3*y0*y2*y2 + 2*x0*x3*x3*y1*y1*y2 - 2*x0*x3*x3*y1*y2*y2 - x1*x1*x2*y0*y0*y2 + 2*x1*x1*x2*y0*y0*y3 - 2*x1*x1*x2*y0*y3*y3 + x1*x1*x2*y2*y3*y3 - x1*x1*x3*y0*y0*y3 + 2*x1*x1*x3*y0*y2*y3 - x1*x1*x3*y2*y2*y3 + x1*x2*x2*y0*y0*y1 - 2*x1*x2*x2*y0*y0*y3 + 2*x1*x2*x2*y0*y3*y3 - x1*x2*x2*y1*y3*y3 - 2*x1*x2*x3*y0*y0*y1 + 2*x1*x2*x3*y0*y0*y2 + 2*x1*x2*x3*y0*y1*y3 - 2*x1*x2*x3*y0*y2*y3 + x1*x3*x3*y0*y0*y1 - 2*x1*x3*x3*y0*y1*y2 + x1*x3*x3*y1*y2*y2 + x2*x2*x3*y0*y0*y3 - 2*x2*x2*x3*y0*y1*y3 + x2*x2*x3*y1*y1*y3 - x2*x3*x3*y0*y0*y2 + 2*x2*x3*x3*y0*y1*y2 - x2*x3*x3*y1*y1*y2);
m01 = (RES_H*(x0 - x2)*(x0*y1 - x1*y0 - x0*y3 + x3*y0 + x1*y3 - x3*y1)*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2))/(- x0*x0*x1*y1*y2*y2 + 2*x0*x0*x1*y1*y2*y3 - x0*x0*x1*y1*y3*y3 + x0*x0*x2*y1*y1*y2 - 2*x0*x0*x2*y1*y2*y3 + x0*x0*x2*y2*y3*y3 - 2*x0*x0*x3*y1*y1*y2 + x0*x0*x3*y1*y1*y3 + 2*x0*x0*x3*y1*y2*y2 - x0*x0*x3*y2*y2*y3 + x0*x1*x1*y0*y2*y2 - 2*x0*x1*x1*y0*y2*y3 + x0*x1*x1*y0*y3*y3 - 2*x0*x1*x2*y0*y1*y3 + 2*x0*x1*x2*y0*y2*y3 + 2*x0*x1*x2*y1*y3*y3 - 2*x0*x1*x2*y2*y3*y3 + 2*x0*x1*x3*y0*y1*y2 - 2*x0*x1*x3*y0*y2*y2 - 2*x0*x1*x3*y1*y2*y3 + 2*x0*x1*x3*y2*y2*y3 - x0*x2*x2*y0*y1*y1 + 2*x0*x2*x2*y0*y1*y3 - x0*x2*x2*y0*y3*y3 + 2*x0*x2*x3*y0*y1*y1 - 2*x0*x2*x3*y0*y1*y2 - 2*x0*x2*x3*y1*y1*y3 + 2*x0*x2*x3*y1*y2*y3 - x0*x3*x3*y0*y1*y1 + x0*x3*x3*y0*y2*y2 + 2*x0*x3*x3*y1*y1*y2 - 2*x0*x3*x3*y1*y2*y2 - x1*x1*x2*y0*y0*y2 + 2*x1*x1*x2*y0*y0*y3 - 2*x1*x1*x2*y0*y3*y3 + x1*x1*x2*y2*y3*y3 - x1*x1*x3*y0*y0*y3 + 2*x1*x1*x3*y0*y2*y3 - x1*x1*x3*y2*y2*y3 + x1*x2*x2*y0*y0*y1 - 2*x1*x2*x2*y0*y0*y3 + 2*x1*x2*x2*y0*y3*y3 - x1*x2*x2*y1*y3*y3 - 2*x1*x2*x3*y0*y0*y1 + 2*x1*x2*x3*y0*y0*y2 + 2*x1*x2*x3*y0*y1*y3 - 2*x1*x2*x3*y0*y2*y3 + x1*x3*x3*y0*y0*y1 - 2*x1*x3*x3*y0*y1*y2 + x1*x3*x3*y1*y2*y2 + x2*x2*x3*y0*y0*y3 - 2*x2*x2*x3*y0*y1*y3 + x2*x2*x3*y1*y1*y3 - x2*x3*x3*y0*y0*y2 + 2*x2*x3*x3*y0*y1*y2 - x2*x3*x3*y1*y1*y2);
m02 = -(RES_H*(x0*y2 - x2*y0)*(x0*y1 - x1*y0 - x0*y3 + x3*y0 + x1*y3 - x3*y1)*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2))/(- x0*x0*x1*y1*y2*y2 + 2*x0*x0*x1*y1*y2*y3 - x0*x0*x1*y1*y3*y3 + x0*x0*x2*y1*y1*y2 - 2*x0*x0*x2*y1*y2*y3 + x0*x0*x2*y2*y3*y3 - 2*x0*x0*x3*y1*y1*y2 + x0*x0*x3*y1*y1*y3 + 2*x0*x0*x3*y1*y2*y2 - x0*x0*x3*y2*y2*y3 + x0*x1*x1*y0*y2*y2 - 2*x0*x1*x1*y0*y2*y3 + x0*x1*x1*y0*y3*y3 - 2*x0*x1*x2*y0*y1*y3 + 2*x0*x1*x2*y0*y2*y3 + 2*x0*x1*x2*y1*y3*y3 - 2*x0*x1*x2*y2*y3*y3 + 2*x0*x1*x3*y0*y1*y2 - 2*x0*x1*x3*y0*y2*y2 - 2*x0*x1*x3*y1*y2*y3 + 2*x0*x1*x3*y2*y2*y3 - x0*x2*x2*y0*y1*y1 + 2*x0*x2*x2*y0*y1*y3 - x0*x2*x2*y0*y3*y3 + 2*x0*x2*x3*y0*y1*y1 - 2*x0*x2*x3*y0*y1*y2 - 2*x0*x2*x3*y1*y1*y3 + 2*x0*x2*x3*y1*y2*y3 - x0*x3*x3*y0*y1*y1 + x0*x3*x3*y0*y2*y2 + 2*x0*x3*x3*y1*y1*y2 - 2*x0*x3*x3*y1*y2*y2 - x1*x1*x2*y0*y0*y2 + 2*x1*x1*x2*y0*y0*y3 - 2*x1*x1*x2*y0*y3*y3 + x1*x1*x2*y2*y3*y3 - x1*x1*x3*y0*y0*y3 + 2*x1*x1*x3*y0*y2*y3 - x1*x1*x3*y2*y2*y3 + x1*x2*x2*y0*y0*y1 - 2*x1*x2*x2*y0*y0*y3 + 2*x1*x2*x2*y0*y3*y3 - x1*x2*x2*y1*y3*y3 - 2*x1*x2*x3*y0*y0*y1 + 2*x1*x2*x3*y0*y0*y2 + 2*x1*x2*x3*y0*y1*y3 - 2*x1*x2*x3*y0*y2*y3 + x1*x3*x3*y0*y0*y1 - 2*x1*x3*x3*y0*y1*y2 + x1*x3*x3*y1*y2*y2 + x2*x2*x3*y0*y0*y3 - 2*x2*x2*x3*y0*y1*y3 + x2*x2*x3*y1*y1*y3 - x2*x3*x3*y0*y0*y2 + 2*x2*x3*x3*y0*y1*y2 - x2*x3*x3*y1*y1*y2);
m10 = -(RES_V*(y0 - y1)*(x0*y2 - x2*y0 - x0*y3 + x3*y0 + x2*y3 - x3*y2)*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2))/(- x0*x0*x1*y1*y2*y2 + 2*x0*x0*x1*y1*y2*y3 - x0*x0*x1*y1*y3*y3 + x0*x0*x2*y1*y1*y2 - 2*x0*x0*x2*y1*y2*y3 + x0*x0*x2*y2*y3*y3 - 2*x0*x0*x3*y1*y1*y2 + x0*x0*x3*y1*y1*y3 + 2*x0*x0*x3*y1*y2*y2 - x0*x0*x3*y2*y2*y3 + x0*x1*x1*y0*y2*y2 - 2*x0*x1*x1*y0*y2*y3 + x0*x1*x1*y0*y3*y3 - 2*x0*x1*x2*y0*y1*y3 + 2*x0*x1*x2*y0*y2*y3 + 2*x0*x1*x2*y1*y3*y3 - 2*x0*x1*x2*y2*y3*y3 + 2*x0*x1*x3*y0*y1*y2 - 2*x0*x1*x3*y0*y2*y2 - 2*x0*x1*x3*y1*y2*y3 + 2*x0*x1*x3*y2*y2*y3 - x0*x2*x2*y0*y1*y1 + 2*x0*x2*x2*y0*y1*y3 - x0*x2*x2*y0*y3*y3 + 2*x0*x2*x3*y0*y1*y1 - 2*x0*x2*x3*y0*y1*y2 - 2*x0*x2*x3*y1*y1*y3 + 2*x0*x2*x3*y1*y2*y3 - x0*x3*x3*y0*y1*y1 + x0*x3*x3*y0*y2*y2 + 2*x0*x3*x3*y1*y1*y2 - 2*x0*x3*x3*y1*y2*y2 - x1*x1*x2*y0*y0*y2 + 2*x1*x1*x2*y0*y0*y3 - 2*x1*x1*x2*y0*y3*y3 + x1*x1*x2*y2*y3*y3 - x1*x1*x3*y0*y0*y3 + 2*x1*x1*x3*y0*y2*y3 - x1*x1*x3*y2*y2*y3 + x1*x2*x2*y0*y0*y1 - 2*x1*x2*x2*y0*y0*y3 + 2*x1*x2*x2*y0*y3*y3 - x1*x2*x2*y1*y3*y3 - 2*x1*x2*x3*y0*y0*y1 + 2*x1*x2*x3*y0*y0*y2 + 2*x1*x2*x3*y0*y1*y3 - 2*x1*x2*x3*y0*y2*y3 + x1*x3*x3*y0*y0*y1 - 2*x1*x3*x3*y0*y1*y2 + x1*x3*x3*y1*y2*y2 + x2*x2*x3*y0*y0*y3 - 2*x2*x2*x3*y0*y1*y3 + x2*x2*x3*y1*y1*y3 - x2*x3*x3*y0*y0*y2 + 2*x2*x3*x3*y0*y1*y2 - x2*x3*x3*y1*y1*y2);
m11 = (RES_V*(x0 - x1)*(x0*y2 - x2*y0 - x0*y3 + x3*y0 + x2*y3 - x3*y2)*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2))/(- x0*x0*x1*y1*y2*y2 + 2*x0*x0*x1*y1*y2*y3 - x0*x0*x1*y1*y3*y3 + x0*x0*x2*y1*y1*y2 - 2*x0*x0*x2*y1*y2*y3 + x0*x0*x2*y2*y3*y3 - 2*x0*x0*x3*y1*y1*y2 + x0*x0*x3*y1*y1*y3 + 2*x0*x0*x3*y1*y2*y2 - x0*x0*x3*y2*y2*y3 + x0*x1*x1*y0*y2*y2 - 2*x0*x1*x1*y0*y2*y3 + x0*x1*x1*y0*y3*y3 - 2*x0*x1*x2*y0*y1*y3 + 2*x0*x1*x2*y0*y2*y3 + 2*x0*x1*x2*y1*y3*y3 - 2*x0*x1*x2*y2*y3*y3 + 2*x0*x1*x3*y0*y1*y2 - 2*x0*x1*x3*y0*y2*y2 - 2*x0*x1*x3*y1*y2*y3 + 2*x0*x1*x3*y2*y2*y3 - x0*x2*x2*y0*y1*y1 + 2*x0*x2*x2*y0*y1*y3 - x0*x2*x2*y0*y3*y3 + 2*x0*x2*x3*y0*y1*y1 - 2*x0*x2*x3*y0*y1*y2 - 2*x0*x2*x3*y1*y1*y3 + 2*x0*x2*x3*y1*y2*y3 - x0*x3*x3*y0*y1*y1 + x0*x3*x3*y0*y2*y2 + 2*x0*x3*x3*y1*y1*y2 - 2*x0*x3*x3*y1*y2*y2 - x1*x1*x2*y0*y0*y2 + 2*x1*x1*x2*y0*y0*y3 - 2*x1*x1*x2*y0*y3*y3 + x1*x1*x2*y2*y3*y3 - x1*x1*x3*y0*y0*y3 + 2*x1*x1*x3*y0*y2*y3 - x1*x1*x3*y2*y2*y3 + x1*x2*x2*y0*y0*y1 - 2*x1*x2*x2*y0*y0*y3 + 2*x1*x2*x2*y0*y3*y3 - x1*x2*x2*y1*y3*y3 - 2*x1*x2*x3*y0*y0*y1 + 2*x1*x2*x3*y0*y0*y2 + 2*x1*x2*x3*y0*y1*y3 - 2*x1*x2*x3*y0*y2*y3 + x1*x3*x3*y0*y0*y1 - 2*x1*x3*x3*y0*y1*y2 + x1*x3*x3*y1*y2*y2 + x2*x2*x3*y0*y0*y3 - 2*x2*x2*x3*y0*y1*y3 + x2*x2*x3*y1*y1*y3 - x2*x3*x3*y0*y0*y2 + 2*x2*x3*x3*y0*y1*y2 - x2*x3*x3*y1*y1*y2);
m12 = -(RES_V*(x0*y1 - x1*y0)*(x0*y2 - x2*y0 - x0*y3 + x3*y0 + x2*y3 - x3*y2)*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2))/(- x0*x0*x1*y1*y2*y2 + 2*x0*x0*x1*y1*y2*y3 - x0*x0*x1*y1*y3*y3 + x0*x0*x2*y1*y1*y2 - 2*x0*x0*x2*y1*y2*y3 + x0*x0*x2*y2*y3*y3 - 2*x0*x0*x3*y1*y1*y2 + x0*x0*x3*y1*y1*y3 + 2*x0*x0*x3*y1*y2*y2 - x0*x0*x3*y2*y2*y3 + x0*x1*x1*y0*y2*y2 - 2*x0*x1*x1*y0*y2*y3 + x0*x1*x1*y0*y3*y3 - 2*x0*x1*x2*y0*y1*y3 + 2*x0*x1*x2*y0*y2*y3 + 2*x0*x1*x2*y1*y3*y3 - 2*x0*x1*x2*y2*y3*y3 + 2*x0*x1*x3*y0*y1*y2 - 2*x0*x1*x3*y0*y2*y2 - 2*x0*x1*x3*y1*y2*y3 + 2*x0*x1*x3*y2*y2*y3 - x0*x2*x2*y0*y1*y1 + 2*x0*x2*x2*y0*y1*y3 - x0*x2*x2*y0*y3*y3 + 2*x0*x2*x3*y0*y1*y1 - 2*x0*x2*x3*y0*y1*y2 - 2*x0*x2*x3*y1*y1*y3 + 2*x0*x2*x3*y1*y2*y3 - x0*x3*x3*y0*y1*y1 + x0*x3*x3*y0*y2*y2 + 2*x0*x3*x3*y1*y1*y2 - 2*x0*x3*x3*y1*y2*y2 - x1*x1*x2*y0*y0*y2 + 2*x1*x1*x2*y0*y0*y3 - 2*x1*x1*x2*y0*y3*y3 + x1*x1*x2*y2*y3*y3 - x1*x1*x3*y0*y0*y3 + 2*x1*x1*x3*y0*y2*y3 - x1*x1*x3*y2*y2*y3 + x1*x2*x2*y0*y0*y1 - 2*x1*x2*x2*y0*y0*y3 + 2*x1*x2*x2*y0*y3*y3 - x1*x2*x2*y1*y3*y3 - 2*x1*x2*x3*y0*y0*y1 + 2*x1*x2*x3*y0*y0*y2 + 2*x1*x2*x3*y0*y1*y3 - 2*x1*x2*x3*y0*y2*y3 + x1*x3*x3*y0*y0*y1 - 2*x1*x3*x3*y0*y1*y2 + x1*x3*x3*y1*y2*y2 + x2*x2*x3*y0*y0*y3 - 2*x2*x2*x3*y0*y1*y3 + x2*x2*x3*y1*y1*y3 - x2*x3*x3*y0*y0*y2 + 2*x2*x3*x3*y0*y1*y2 - x2*x3*x3*y1*y1*y2);

使用m00、m01、m02、m10、m11和m12,我构建了一个M矩阵。我省略了m20,m21,m22因为它们对x,y的结果没有影响

最后,我用这个M矩阵对球的坐标进行了平移:

x_shifted = m00*x + m01*y + m02;
y_shifted = m10*x + m11*y + m12;

这是基于:

如您所见,Matlab 生成的解产生了非常长的方程。无意间,我发现当你在 A 矩阵中交换 xi 与 ui 和 yi 与 vi 时,你将得到变换矩阵 M 的逆 对于 m00、m01、m02、m10、m11、m12,但系数是用更短的方程式计算的。

/   0     0     1     0     0     0     0         0     \ /m00\ /x0\
| RES_H   0     1     0     0     0 -RES_H*x1     0     | |m01| |x1|
|   0   RES_V   1     0     0     0     0     -RES_V*x2 | |m02| |x2|
| RES_H RES_V   1     0     0     0 -RES_H*x3 -RES_V*x3 |.|m10|=|x3|
|   0     0     0     0     0     1     0         0     | |m11| |y0|
|   0     0     0   RES_H   0     1 -RES_H*y1     0     | |m12| |y1|
|   0     0     0     0   RES_V   1     0     -RES_V*y2 | |m20| |y2|
\   0     0     0   RES_H RES_V   1 -RES_H*y3 -RES_V*y3 / \m21/ \y3/

当你用Matlab用同样的方法求解时,你会得到:

m00 = (x0*x2*y1 - x1*x2*y0 - x0*x3*y1 + x1*x3*y0 - x0*x2*y3 + x0*x3*y2 + x1*x2*y3 - x1*x3*y2)/(RES_H*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2));
m01 = -(x0*x1*y2 - x1*x2*y0 - x0*x1*y3 + x0*x3*y1 - x0*x3*y2 + x2*x3*y0 + x1*x2*y3 - x2*x3*y1)/(RES_V*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2));
m02 = x0;
m10 = (x0*y1*y2 - x1*y0*y2 - x0*y1*y3 + x1*y0*y3 - x2*y0*y3 + x3*y0*y2 + x2*y1*y3 - x3*y1*y2)/(RES_H*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2));
m11 = -(x0*y1*y2 - x2*y0*y1 - x1*y0*y3 + x3*y0*y1 - x0*y2*y3 + x2*y0*y3 + x1*y2*y3 - x3*y1*y2)/(RES_V*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2));
m12 = y0;
m20 = (x0*y2 - x2*y0 - x0*y3 - x1*y2 + x2*y1 + x3*y0 + x1*y3 - x3*y1)/(RES_H*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2));
m21 = -(x0*y1 - x1*y0 - x0*y3 + x1*y2 - x2*y1 + x3*y0 + x2*y3 - x3*y2)/(RES_V*(x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2));
m22 = 1.0;

当您将这些系数放入一个矩阵并反转该矩阵时,对于 m00、m01、m02、m10、m11、m12,您将得到与第一种方法相同的结果。

我使用了我在这里找到的程序来反转矩阵: https://codingtech2017.wordpress.com/2017/05/03/c-program-to-inverse-a-matrix3x3/