Plot 8X8 grid between corners on part of the image

Question:

I have a photo of a chessboard. I’ve detected the four corners of the board using YOLO, and I have their x, y coordinates.

Now I would like to plot a 8×8 grid between the four corners (along the chessboard lines).

That’s a image for example:

chessboard with corners and outer lines – original image

Here’s my plotting code so far (python):

from matplotlib.pyplot import figure
import matplotlib.pyplot as plt
import matplotlib.image as image

figure(figsize=(10, 10), dpi=80)

im = plt.imread('1.jpgresized.jpg')
implot = plt.imshow(im)

#Left
plt.plot([0.179167 * 480, 0.063542 * 480], 
         [0.203125 * 640, 0.644531 * 640], 
         'bo', linestyle="--")

#Bottom
plt.plot([0.063542 * 480, 0.934375 * 480], 
         [0.644531 * 640, 0.627344 * 640], 
         'bo', linestyle="--")

#Right
plt.plot([0.934375 * 480, 0.789583 * 480], 
         [0.627344 * 640, 0.191406 * 640], 
         'bo', linestyle="--")

#Up
plt.plot([0.789583 * 480, 0.179167 * 480], 
         [0.191406 * 640, 0.203125 * 640], 
         'bo', linestyle="--")


plt.show()
Asked By: shainis

||

Answers:

This does what I describe. For each line, we create a set of 9 points evenly spaced. Then, we draw lines from the left set to the right set, and from the top set to the bottom set.

FOLLOWUP

I’ve added a hacky perspective correction on the Y coordinates. I just do a linear adjustment. It’s not mathematically defensible, but it does the job with this image. Doing it right would involve using the change in size from the top line to the bottom line to determine the perspective factor. I’ve just hard-coded it by experimentation.

from matplotlib.pyplot import figure
import matplotlib.pyplot as plt
import matplotlib.image as image

figure(figsize=(10, 10), dpi=80)

im = plt.imread('chessboard.jpg')
implot = plt.imshow(im)

W,H= 480,640

TL = (0.179167, 0.202125)
BL = (0.063542, 0.644531)
TR = (0.789583, 0.191406)
BR = (0.934375, 0.627344)

def interpolate(xy0, xy1, persp=0):
    x0,y0 = xy0
    x1,y1 = xy1
    dx = (x1-x0) / 8
    dy = (y1-y0 - persp*36) / 8
    return [(x0+i*dx,y0+i*dy+(i*(i+1)/2)*persp) for i in range(9)]

ptsT = interpolate( TL, TR )
ptsL = interpolate( TL, BL, 0.005 )
ptsR = interpolate( TR, BR, 0.005 )
ptsB = interpolate( BL, BR )

for a,b in zip(ptsL, ptsR):
    plt.plot( [a[0]*W, b[0]*W], [a[1]*H, b[1]*H], 'ro', linestyle="--" )
for a,b in zip(ptsT, ptsB):
    plt.plot( [a[0]*W, b[0]*W], [a[1]*H, b[1]*H], 'ro', linestyle="--" )

plt.show()

Output:
enter image description here

Answered By: Tim Roberts
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.