Para detectar las piezas en el tablero una de las cosas que tenemos que hacer es saber dónde está el tablero. Generalmente vamos a colocar el tablero en la misma posición pero creemos que es conveniente realizar la detección del tablero por si pequeños cambios en la posición del tablero o la cámara afectan a la detección de las piezas, y también así hacemos el sistema más robusto.
Usamos un programa de detección de tableros que otro grupo está usando para otro proyecto, usando unas funciones de OpenCV, pero tenemos un problema porque no detecta bien todas las esquinas, así que buscamos por Internet y encontramos la manera de mejorarlo usando corrección de color y uso de una máscara. De esta manera conseguimos detectar los puntos centrales del tablero.
Tras esto tenemos que añadir los puntos del borde del tablero, y lo hacemos de forma manual. El cálculo de los puntos lo hacemos tomando las distancias con los adyacentes; no es el sistema más exacto porque la foto tiene un poco de deformación esférica, además de la perspectiva cónica, pero el error no es demasiado.
Añadimos todos los puntos a un array de dos dimensiones porque así facilitará el uso de los puntos de las casillas más tarde. Añadimos también al programa una función para dibujar los puntos en la imagen, como medida de comprobación de que está bien.
El programa que realiza esta detección y composición de los puntos de las esquinas es el siguiente:
import cv2
import numpy as np
#################################################################
def DibujaPuntos(frame,Puntos):
for ii in range(9):
for jj in range(9):
cv2.circle(frame,(int(Puntos[ii][jj][0]),int(Puntos[ii][jj][1])),2,(0,20*ii,255),2)
return frame
#################################################################
# Load the image
img = cv2.imread("tablero.jpg")
# Color-segmentation to get binary mask
lwr = np.array([0, 0, 143])
upr = np.array([179, 61, 252])
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
msk = cv2.inRange(hsv, lwr, upr)
# Extract chess-board
krn = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 30))
dlt = cv2.dilate(msk, krn, iterations=5)
res = 255 - cv2.bitwise_and(dlt, msk)
# Displaying chess-board features
res = np.uint8(res)
ret, corners = cv2.findChessboardCorners(res, (7, 7),
flags=cv2.CALIB_CB_ADAPTIVE_THRESH +
cv2.CALIB_CB_FAST_CHECK +
cv2.CALIB_CB_NORMALIZE_IMAGE)
if ret:
# Inicialización matriz de puntos del tablero
Puntos=[]
punto=[0,0]
for ii in range(9):
col = []
for jj in range(9):
col.append(punto)
Puntos.append(col)
# Relleno de la matriz de puntos a partir de corners
for ii in range(7):
Puntos[1][7-ii]=corners[ii][0]
Puntos[2][ii+1]=corners[7+ii][0]
Puntos[3][7-ii]=corners[14+ii][0]
Puntos[4][ii+1]=corners[21+ii][0]
Puntos[5][7-ii]=corners[28+ii][0]
Puntos[6][ii+1]=corners[35+ii][0]
Puntos[7][7-ii]=corners[42+ii][0]
print(Puntos[2][7])
#Distancias
Db=(corners[48][0]-corners[40][0])
Dsh=(corners[6][0]-corners[12][0])
Ds=(corners[8][0]-corners[0][0])
Dg=(corners[42][0]-corners[36][0])
DS=(corners[1][0]-corners[0][0])
DO=(corners[7][0]-corners[0][0])
DN=(corners[6][0]-corners[5][0])
DE=(corners[48][0]-corners[41][0])
# Añade puntos exteriores
Puntos[0][0]=(corners[6][0]+Dsh)
for ii in range(7):
Puntos[0][ii+1]=corners[6-ii][0]-(corners[13-ii][0]-corners[6-ii][0])
Puntos[0][8]=(corners[0][0]-Ds)
Puntos[8][0]=(corners[48][0]+Db)
for ii in range(7):
Puntos[8][ii+1]=corners[48-ii][0]+(corners[48-ii][0]-corners[41-ii][0])
Puntos[8][8]=(corners[42][0]+Dg)
for ii in range(7):
Puntos[ii+1][0]=corners[(ii*7)+6][0]+(corners[(ii*7)+6][0]-corners[(ii*7)+5][0])
for ii in range(7):
Puntos[ii+1][8]=corners[ii*7][0]+(corners[ii*7][0]-corners[(ii*7)+1][0])
print(Puntos)
img2=DibujaPuntos(img,Puntos)
img2=cv2.resize(img2,(960,540))
cv2.imshow("fn2", img2)
fnl = cv2.drawChessboardCorners(img, (7, 7), corners, ret)
fn2=cv2.resize(fnl,(960,540))
cv2.imshow("fnl", fn2)
cv2.waitKey(0)
else:
print("No Checkerboard Found")
Deja una respuesta