Home > Blockchain >  How to apply getPerspectiveTransform twice in 1 go/ How do I multiply the coordinates of a rectangle
How to apply getPerspectiveTransform twice in 1 go/ How do I multiply the coordinates of a rectangle

Time:02-08

I am trying to extract a rectangle that is on a boardgame(called sub in the attached illustration) from a picture (called main in the attached illustration). I know the position of the rectange relative to the board, and I know the position of the board relative to the picture. My goal is to extract the rectangle from the picture with getPerspectiveTransform.

In the following image the rectangle has been replace by a single coordinate of one of the corners to make the illustration simpler.

Illustration of point in a tranformed rectangle in a rectangle

For the coordinate on the picture i expect a coordinate of something in the range of (290,190).

I tried using getPerspectiveTransform twice: once to get the board(sub) and then extract the rectangle from the resulting board(sub) image. But that leads to quality loss and is a hit on performance.

I also tried multiplying 2 matrixes with each other with the goal of getting the coordinates for the inner rectangle, but that didn't work. This calculation does not work in a 2d space. My knowledge of matrixes is almost none. My attempt:

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)

How do I extract the coordinates of the inner rectangle?

CodePudding user response:

Well, I couldn't get it to work with the libraries, so I tried programming it myself. I came up with the following:

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)))

This calculates 1 x,y coordinate. To calculate X, it calcaluates x at the left side of the board(leftsideX), the right side of the board(rightsideX), and multiplies the 2 based on the ratio(boardRatioWidth) of how far the coordinate is. The same is being done for Y but the other way around.

  •  Tags:  
  • Related