好吧,我要做的是;使用网络摄像头拍照并从该照片中提取棋盘上棋子的位置并将它们写在矩阵或列表上,这无关紧要,因为之后我只需要验证棋子的移动完成。
我浏览了一些教程和文档,但我迷路了,我能得到的最好的线索是this answer,但我什至无法获得网格:
这是有问题的代码:
import cv2
import numpy as np
def main():
im = cv2.imread('opencv_frame_0.png')
#im = cv2.resize(im, (640, 480))
#edge = cv2.imread('edge.png', 0)
edge = cv2.Canny(im, 60, 160, apertureSize=3)
lines = cv2.HoughLines(edge, 1, np.pi/180, 100, 100, 50)
for rho, theta in lines[0]:
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
x1 = int(x0 + 1000*(-b))
y1 = int(y0 + 1000*(a))
x2 = int(x0 - 1000*(-b))
y2 = int(y0 - 1000*(a))
cv2.line(im, (x1, y1), (x2, y2), (0, 0, 255), 2)
# TODO: filter the lines by color and line distance
cv2.imshow('image', im)
cv2.imshow('edge', edge)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
无论如何,即使我能弄清楚为什么
cv2.HoughLines
没有做我想做的事,我也不知道如何处理这个问题,获取棋盘上棋子的坐标,哪些空间是空的,哪些空间有一块
此外,我期望得到的矩阵与 chess python 库文档中所示的一样:
r . b q k b . r
p p p p . Q p p
. . n . . n . .
. . . . p . . .
. . B . P . . .
. . . . . . . .
P P P P . P P P
R N B . K . N R
更新
好吧,所以,根据@stateMachine 的建议,我改为颜色检测。我现在拥有的是,使用这张图片:
我在
cv2.goodFeaturesToTrack
的帮助下检测每个角落,这是输出:
现在,我要做的是获取棋盘上每个方格的中点坐标。而且,因为cv2给出的蓝色点(如上图所示)没有顺序,我不能直接使用其中的4个,只找到中间点,例如:
[[254, 606], [387, 465], [519, 187], [314, 262], [172, 132], [315, 329], [179, 405], [523, 395], [246, 334], [112, 475], [519, 256], [383, 327], [382, 193], [392, 534], [596, 531], [461, 601], [238, 130], [175, 198], [452, 327], [458, 533], [525, 461], [181, 471], [40, 339], [594, 460], [381, 260], [175, 336], [43, 477], [448, 191], [454, 394], [173, 264], [518, 118], [521, 323], [245, 262], [387, 396], [245, 404], [251, 540], [42, 408], [182, 543], [36, 204], [45, 614], [590, 322], [453, 258], [45, 545], [456, 466], [307, 125], [109, 338], [600, 597], [321, 537], [592, 392], [111, 545], [106, 203], [392, 603], [107, 266], [242, 198], [38, 269], [446, 53], [585, 185], [588, 253], [114, 610], [531, 599], [99, 65], [108, 407], [309, 55], [377, 54], [33, 135], [380, 122], [30, 67], [530, 530], [449, 123], [169, 64], [182, 608], [584, 117], [250, 472], [317, 400], [313, 193], [236, 62], [103, 132], [589, 47], [515, 51], [319, 466], [321, 604]]
所以,我目前的做法是找到左上角、右角和左下角和右下角的坐标,然后划分距离,这样我就可以相交线并找到更多的点:
现在,我的问题是;如果相机不是正对着上方,中间的点并不是真的在中间,原因是因为视角有些方块比其他方块大,所以划分不可靠。
我现在需要做的是找到上面显示的列表中属于同一个正方形的 4 个点,并找到它们之间的中间点,而不是仅仅使用板的 4 个角进行除法。
用于查找角点的代码(只有蓝点的图像): ''' 导入cv2 将 numpy 导入为 np
定义主要(): frame = cv2.imread("chessboard.jpg")
cv2.namedWindow("Frame", cv2.WINDOW_NORMAL)
corners = []
corners = find_chessboard(frame)
print(corners)
cv2.waitKey(0)
cv2.destroyAllWindows()
return True
def find_chessboard(框架): img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
corners = cv2.goodFeaturesToTrack(img, 81, 0.01, 10)
corners = np.int0(corners)
corners_coordinates = [[]]*len(corners)
i = 0
for corner in corners:
x, y = corner.ravel()
corners_coordinates[i] = [x, y]
i = i+1
cv2.circle(frame, (x, y), 5, (255, 0, 0), -1)
cv2.imshow("Frame", frame)
return corners_coordinates
如果name是“main”:
main()
'''