Inverse perspective transformation - Python implementation of transformation matrix

Reference

Personal understanding of the perspective transformation principle and the python implementation of the transformation matrix
may be wrong, welcome to discuss.
To perform perspective transformation, four points need to be selected. These points define a rectangle, but in the original image, due to problems such as camera angles, it does not appear to be a rectangle. In order to change the perspective, we need to perform perspective transformation.
Perspective transformation essentially converts a picture from one perspective to another through a linear transformation between four points.

Calculation formula

Perspective transformation matrix:

insert image description here
We define the target point matrix as insert image description here, and define the source point matrix as insert image description here.
This is mapping from two-dimensional pixel coordinates to three-dimensional world coordinates. Our main goal here is to map pixel coordinates to another pixel coordinates.
For insert image description here
each pair, insert image description herethe following equations are satisfied.
insert image description here
Therefore, we can get the formula (1) and multiply it
insert image description here
up and down, and continue to deduce it:
insert image description here
we need to find insert image description here, and the other is the unknown, and convert the equation into a matrix AX = 0 AX=0AX=0
insert image description here
There are 9 unknowns at this time, we need to use 9 equations to solve, for a pair of matching pointsinsert image description herewe can get two equations.
Why do we only need 4 pairs of matching points to solve the above equation.

8 unknowns

We found that for formula (1) can be written in the following form, the result will not change.
insert image description herewhere α \alphaα is a number that is not 0.
At this point, we can map the above formula back to the matrix form, and we can get.insert image description here
Therefore, we can get
insert image description here
that there are only 8 unknowns at this point, and we only need to find 4 sets of corresponding points to solve the equation.
The reaction to the solution formula is as follows.
insert image description here
The last digit is a constant 1, we can modify the formula as formulainsert image description here

Code solution - realize it yourself

# 此处的src是原坐标数组,dst是目标坐标数组
def WarpPerspectiveMatrix(src, dst):
    assert src.shape[0] == dst.shape[0] and src.shape[0] >= 4

    nums = src.shape[0]
    # 4组对应点,每组2行8列
    # 总共8行8列的数组,对应公式(3)中最左边的矩阵
    A = np.zeros((2 * nums, 8))
    # 4组对应点,每组2行1列
    # 总共8行1列,对应公式(3)中最右边的矩阵
    B = np.zeros((2 * nums, 1))
    # 矩阵赋值,0下标为x值,1下标为y值
    for i in range(0, nums):
        A_i = src[i,:]
        B_i = dst[i,:]
        A[2*i, :] = [A_i[0], A_i[1], 1, 0, 0, 0, -A_i[0]*B_i[0], -A_i[1]*B_i[0]]
        B[2*i] = B_i[0]

        A[2*i+1, :] = [0, 0 , 0, A_i[0], A_i[1], 1, -A_i[0]*B_i[1], -A_i[1]*B_i[1]]
        B[2*i+1] = B_i[1]

	# 转换为矩阵
    A = np.mat(A)
    # 求解未知数值,.I表示求逆
    warpMatrix = A.I * B

	# 矩阵后处理,主要是将a33的1值赋值回去
    warpMatrix = np.array(warpMatrix).T[0]
    warpMatrix = np.insert(warpMatrix, warpMatrix.shape[0], values=1.0, axis=0)
    warpMatrix = warpMatrix.reshape((3, 3))
    return warpMatrix

Code solution - Opencv implementation

# 注意,这里的src和dst,本人验证,使用np.float32()定义可以不出错
M = cv2.getPerspectiveTransform(src, dst)
src = np.float32([[34 * 720 / 160, 113 * 1280 / 288], [34 * 720 / 160, 186 * 1280 / 288], [157 * 720 / 160, 50 * 1280 / 288], [157 * 720 / 160, 244 * 1280 / 288]])
dst = np.float32([[150, 50], [150, 490], [780, 50], [780, 490]])


def WarpPerspectiveMatrix(src, dst):
    assert src.shape[0] == dst.shape[0] and src.shape[0] >= 4

    nums = src.shape[0]
    A = np.zeros((2 * nums, 8))
    B = np.zeros((2 * nums, 1))
    for i in range(0, nums):
        A_i = src[i,:]
        B_i = dst[i,:]
        A[2*i, :] = [A_i[0], A_i[1], 1, 0, 0, 0, -A_i[0]*B_i[0], -A_i[1]*B_i[0]]
        B[2*i] = B_i[0]

        A[2*i+1, :] = [0, 0 , 0, A_i[0], A_i[1], 1, -A_i[0]*B_i[1], -A_i[1]*B_i[1]]
        B[2*i+1] = B_i[1]

    A = np.mat(A)
    warpMatrix = A.I * B

    warpMatrix = np.array(warpMatrix).T[0]
    warpMatrix = np.insert(warpMatrix, warpMatrix.shape[0], values=1.0, axis=0)
    warpMatrix = warpMatrix.reshape((3, 3))
    return warpMatrix

M = WarpPerspectiveMatrix(src, dst)
print(M)
M = cv2.getPerspectiveTransform(src, dst)
print(M)
# 自己实现的
[[ 6.41178433e+00  0.00000000e+00 -7.04158205e+02]
 [ 1.54253726e+00  2.50298025e+00 -1.40077892e+03]
 [ 5.52700641e-03  0.00000000e+00  1.00000000e+00]]
# opencv官方的
[[ 6.41178433e+00  0.00000000e+00 -7.04158205e+02]
 [ 1.54253726e+00  2.50298025e+00 -1.40077892e+03]
 [ 5.52700641e-03 -1.08420217e-19  1.00000000e+00]]

Guess you like

Origin blog.csdn.net/REstrat/article/details/126987198