如何在 1 go 中应用两次 getPerspectiveTransform/ 如何在 2D space 中将矩形的坐标乘以矩形?

How to apply getPerspectiveTransform twice in 1 go/ How do I multiply the coordinates of a rectangle in a rectangle in a 2D space?

我正在尝试从图片(附图中称为 main)中提取棋盘游戏上的矩形(附图中称为 sub)。我知道矩形相对于棋盘的位置,我也知道棋盘相对于图片的位置。我的目标是使用 getPerspectiveTransform 从图片中提取矩形。

在下图中,矩形已替换为其中一个角的单个坐标,以使插图更简单。

对于图片上的坐标,我希望坐标在 (290,190) 范围内。

我尝试使用 getPerspectiveTransform 两次:一次获取板(子),然后从生成的板(子)图像中提取矩形。但这会导致质量损失并且影响性能。

我还尝试将 2 个矩阵相互相乘以获取内部矩形的坐标,但这没有用。此计算不适用于 2d space。我对矩阵的了解差不多none。我的尝试:

main_width = 4000
mainheight = 2250

subwidth = 800
subheight = 533
# [top-left, top-right, bottom-right, bottom-left]
main  = np.float32([[386/main_width, 90/mainheight],[3441/main_width, 72/mainheight],[301/main_width, 2174/mainheight],[3540/main_width, 2163/mainheight]])
sub  = np.float32([[132/subwidth,56/subheight],[145/subwidth,79/subheight],[137/subwidth,83/subheight],[126/subwidth,59/subheight]])

innerRectangle = cv2.multiply(main,sub)
print(innerRectangle)

如何提取内部矩形的坐标?

好吧,我无法让它与库一起工作,所以我尝试自己编程。我想到了以下内容:

import numpy as np

main_width = 4000
mainheight = 2250

subwidth = 990
subheight = 660

#                   0            1               2               3
#                   [top-left,   top-right,      bottom-right,   bottom-left]
main = np.float32([ [386, 90],   [3437, 72],     [3538, 2165],   [300, 2175]])
sub = np.float32([  [166, 68],   [180, 98],      [169, 103],     [156, 73]])


subTopLeftX = sub[0][0]
boardRatioWidth = subTopLeftX/subwidth#132/800
print("boardRatioWidth: \t" + str(boardRatioWidth))#.165

subTopLeftY = sub[0][1]
boardRatioHeight = subTopLeftY/subheight#58/533
print("boardRatioHeight: \t" + str(boardRatioHeight))#0.108

#              386 +          ((291-386) * 0.108)
leftsideX = main[0][0] + ((main[3][0] - main[0][0]) * boardRatioHeight)
#3444 + ((3555-3444) * 0.108)
rightsideX = main[1][0] + ((main[2][0] - main[1][0]) * (boardRatioHeight))

x = leftsideX + ((rightsideX - leftsideX) * boardRatioWidth)


#88 + ((70 - 88 ) * .165)
topsideY = main[0][1] + ((main[1][1] - main[0][1]) * boardRatioWidth)
print("topsideY: \t" + str(topsideY))
bottomsideY = main[3][1] + ((main[2][1] - main[3][1]) * (boardRatioWidth))
print("bottomsideY: \t" + str(bottomsideY))

#87 + ((2172 - 87) * .108)
y = topsideY + ((bottomsideY - topsideY) * boardRatioHeight)

print("x,y: \t" + str((x, y)))

这将计算 1 个 x,y 坐标。要计算 X,它会计算板左侧 (leftsideX)、板右侧 (rightsideX) 的 x,并根据坐标距离的比率 (boardRatioWidth) 乘以 2。 Y 也是如此,但相反。